Initial commit
This commit is contained in:
64
Utf16.c
Normal file
64
Utf16.c
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "CgeStr.h"
|
||||
|
||||
#define INVALID_RUNE 0xFFFD
|
||||
|
||||
int CgeUtf16Encode(uint32_t rune, uint16_t* data) {
|
||||
if (rune <= 0xFFFF) {
|
||||
if (rune >= 0xD800 && rune <= 0xDFFF)
|
||||
return -1;
|
||||
data[0] = (uint16_t)rune;
|
||||
return 1;
|
||||
}
|
||||
if (rune <= 0x10FFFF) {
|
||||
uint32_t x = rune - 0x10000;
|
||||
data[0] = (uint16_t)(0xD800 + (x >> 10));
|
||||
data[1] = (uint16_t)(0xDC00 + (x & 0x3FF));
|
||||
return 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CgeUtf16EncodeLax(uint32_t rune, uint16_t* data) {
|
||||
int result;
|
||||
|
||||
result = CgeUtf16Encode(rune, data);
|
||||
if (result == -1)
|
||||
result = CgeUtf16Encode(INVALID_RUNE, data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int CgeUtf16Decode(const uint16_t* data, size_t size, uint32_t* rune) {
|
||||
uint16_t trail, lead = data[0];
|
||||
|
||||
if (size == 0)
|
||||
return -1;
|
||||
|
||||
if (lead < 0xD800 || lead > 0xDFFF) {
|
||||
*rune = lead;
|
||||
return 1;
|
||||
} else if (lead >= 0xD800 && lead <= 0xDBFF) {
|
||||
if (size < 2)
|
||||
return -1;
|
||||
|
||||
trail = data[1];
|
||||
if (trail >= 0xDC00 && trail <= 0xDFFF) {
|
||||
*rune = 0x10000 + ((lead & 0x3FF) << 10) + (trail & 0x3FF);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CgeUtf16DecodeLax(const uint16_t* data, size_t size, uint32_t* rune) {
|
||||
int result;
|
||||
|
||||
result = CgeUtf16Decode(data, size, rune);
|
||||
if (result == -1) {
|
||||
*rune = INVALID_RUNE;
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user