51 #include "../library/lib.h"
55 #define BASE64_LINE_LEN 76
58 #define NON_BYTE_MASK 0xFFFFFF00
59 #define BYTE_MASK 0xFF
62 static const void* s_vpMagicNumber = (
void*)
"conv";
63 static uint8_t s_caBOM8[] = {0xEF, 0xBB, 0xBF};
64 static uint8_t s_caBOM16BE[] = {0xFE, 0xFF};
65 static uint8_t s_caBOM16LE[] = {0xFF, 0xFE};
66 static uint8_t s_caBOM32BE[] = {0, 0, 0xFE, 0xFF};
67 static uint8_t s_caBOM32LE[] = {0xFF, 0xFE, 0, 0};
68 static uint8_t s_ucaCRLF[] = {13,10};
97 static abool bIsBOM8(uint8_t* ucpStream,
aint uiLen);
98 static abool bIsBOM16BE(uint8_t* ucpStream,
aint uiLen);
99 static abool bIsBOM16LE(uint8_t* ucpStream,
aint uiLen);
100 static abool bIsBOM32BE(uint8_t* ucpStream,
aint uiLen);
101 static abool bIsBOM32LE(uint8_t* ucpStream,
aint uiLen);
102 static void vBase64Encode(
conv* spConv,
conv_dst* spDst);
103 static void vBase64Decode(
conv* spConv, uint8_t* ucpSrc,
aint uiSrcLen);
104 static void vBase64Validate(
conv* spConv, uint8_t* ucpSrc,
aint uiSrcLen);
105 static void vBinaryEncode(
conv* spConv);
106 static void vBinaryDecode(
conv* spConv);
107 static void vUtf32BEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen);
108 static void vUtf32LEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen);
109 static void vUtf32BEEncode(
conv* spConv,
conv_dst* spDst);
110 static void vUtf32LEEncode(
conv* spConv,
conv_dst* spDst);
111 static void vUtf16BEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen);
112 static void vUtf16LEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen);
113 static void vUtf16BEEncode(
conv* spConv,
conv_dst* spDst);
114 static void vUtf16LEEncode(
conv* spConv,
conv_dst* spDst);
116 static void vUtf8Decode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen);
117 static void vSetError(
conv* spConv, uint32_t uiValue, uint32_t uiOffset,
const char* cpMsg);
119 static uint8_t ucaBase64Chars[] = {
120 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,
121 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,
122 48,49,50,51,52,53,54,55,56,57,
125 static uint32_t uiEncode64Mask = 0x0000003F;
126 static uint32_t uiDecode64Mask = 0x000000FF;
139 memset(spConv, 0,
sizeof(
conv));
140 spConv->
vpMem = vpMem;
142 aint uiBufSize = 128 * 1024;
143 spConv->
vpVecInput = (uint8_t*)
vpVecCtor(vpMem,
sizeof(uint8_t),
sizeof(uint8_t) * uiBufSize);
145 spConv->
vpVec32bit = (uint32_t*)
vpVecCtor(vpMem,
sizeof(uint32_t),
sizeof(uint32_t) * uiBufSize);
149 return (
void*)spConv;
165 void* vpMem = spCtx->
vpMem;
166 memset(vpCtx, 0,
sizeof(
conv));
188 if(spConv && spConv->
vpValidate == s_vpMagicNumber){
192 XTHROW(spConv->
spException,
"uiLineEnd must be one of BASE64_LF or BASE64_CRLF");
207 if(spConv && spConv->
vpValidate == s_vpMagicNumber){
227 if(!ucpData || !uiDataLen){
233 vBinaryDecode(spConv);
236 if(bIsBOM8(ucpData, uiDataLen)){
237 vUtf8Decode(spConv, (ucpData + 3), (uiDataLen - 3));
239 vUtf8Decode(spConv, ucpData, uiDataLen);
243 if(bIsBOM16BE(ucpData, uiDataLen)){
244 vUtf16BEDecode(spConv, (ucpData + 2), (uiDataLen - 2));
245 }
else if(bIsBOM16LE(ucpData, uiDataLen)){
246 vUtf16LEDecode(spConv, (ucpData + 2), (uiDataLen - 2));
248 vUtf16BEDecode(spConv, ucpData, uiDataLen);
252 if(bIsBOM16BE(ucpData, uiDataLen)){
253 vUtf16BEDecode(spConv, (ucpData + 2), (uiDataLen - 2));
255 vUtf16BEDecode(spConv, ucpData, uiDataLen);
259 if(bIsBOM16LE(ucpData, uiDataLen)){
260 vUtf16LEDecode(spConv, (ucpData + 2), (uiDataLen - 2));
262 vUtf16LEDecode(spConv, ucpData, uiDataLen);
266 if(bIsBOM32BE(ucpData, uiDataLen)){
267 vUtf32BEDecode(spConv, (ucpData + 4), (uiDataLen - 4));
268 }
else if(bIsBOM32LE(ucpData, uiDataLen)){
269 vUtf32LEDecode(spConv, (ucpData + 4), (uiDataLen - 4));
271 vUtf32BEDecode(spConv, ucpData, uiDataLen);
275 if(bIsBOM32BE(ucpData, uiDataLen)){
276 vUtf32BEDecode(spConv, (ucpData + 4), (uiDataLen - 4));
278 vUtf32BEDecode(spConv, ucpData, uiDataLen);
282 if(bIsBOM32LE(ucpData, uiDataLen)){
283 vUtf32LEDecode(spConv, (ucpData + 4), (uiDataLen - 4));
285 vUtf32LEDecode(spConv, ucpData, uiDataLen);
304 if(spConv && spConv->
vpValidate == s_vpMagicNumber){
314 vBinaryEncode(spConv);
317 vUtf8Encode(spConv, spDst);
321 vUtf16BEEncode(spConv, spDst);
324 vUtf16LEEncode(spConv, spDst);
328 vUtf32BEEncode(spConv, spDst);
331 vUtf32LEEncode(spConv, spDst);
339 vBase64Encode(spConv, spDst);
363 if(spConv && spConv->
vpValidate == s_vpMagicNumber){
368 uint32_t uiOriginalLen = *uipDataLen;
371 if(!*uipDataLen || !uip32){
375 if(uipData && uiOriginalLen){
377 aint uiLen = *uipDataLen >= uiOriginalLen ? uiOriginalLen : *uipDataLen;
378 for(; ui < uiLen; ui++){
379 uipData[ui] = uip32[ui];
397 if(spConv && spConv->
vpValidate == s_vpMagicNumber){
400 if(!uipSrc || !uiSrcLen){
406 for(ui = 0; ui < uiSrcLen; ui++){
407 uip32bit[ui] = uipSrc[ui];
424 if(spConv && spConv->
vpValidate == s_vpMagicNumber){
425 if(!spSrc || !spDst){
436 static void vBase64Encode(
conv* spConv,
conv_dst* spDst){
437 aint uiTail, uiUnits, u3, u4, uu;
438 uint8_t* ucpTrans = NULL;
445 XTHROW(spConv->
spException,
"internal error - vBase64Encode called with no source");
447 uiUnits = uiSrcLen / 3;
448 uiTail = 3 - uiSrcLen % 3;
452 ucpTrans = (uint8_t*)
vpMemAlloc(spConv->
vpMem, (
aint)
sizeof(uint32_t) * (uiUnits + 1) * 4);
457 for(; uu < uiUnits; uu++){
458 ui32 = ucpSrc[u3++] << 16;
459 ui32 += ucpSrc[u3++] << 8;
460 ui32 += ucpSrc[u3++];
461 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 18) & uiEncode64Mask];
462 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 12) & uiEncode64Mask];
463 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 6) & uiEncode64Mask];
464 ucpTrans[u4++] = ucaBase64Chars[ui32 & uiEncode64Mask];
467 ui32 = ucpSrc[u3++] << 16;
468 ui32 += ucpSrc[u3] << 8;
469 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 18) & uiEncode64Mask];
470 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 12) & uiEncode64Mask];
471 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 6) & uiEncode64Mask];
472 ucpTrans[u4++] = ucaBase64Chars[64];
473 }
else if(uiTail == 2){
474 ui32 = ucpSrc[u3] << 16;
475 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 18) & uiEncode64Mask];
476 ucpTrans[u4++] = ucaBase64Chars[(ui32 >> 12) & uiEncode64Mask];
477 ucpTrans[u4++] = ucaBase64Chars[64];
478 ucpTrans[u4++] = ucaBase64Chars[64];
484 for(; ui < u4; ui++){
504 static void vBase64Validate(
conv* spConv, uint8_t* ucpSrc,
aint uiSrcLen){
505 uint8_t* ucpValues = NULL;
508 uint8_t* ucpChar = ucpSrc;
509 uint8_t* ucpEnd = ucpSrc + uiSrcLen - spConv->
uiTail;
511 aint uiValuesLen = 0;
513 for(; ucpChar < ucpEnd; ucpChar++, uiOffset++){
516 if(ucChar == 10 || ucChar == 13 || ucChar == 9 || ucChar == 32){
520 if(ucChar >= 65 && ucChar <= 90){
521 ucpValues[uiValuesLen++] = ucChar - 65;
524 if(ucChar >= 97 && ucChar <= 122){
525 ucpValues[uiValuesLen++] = ucChar - 71;
528 if(ucChar >= 48 && ucChar <= 57){
529 ucpValues[uiValuesLen++] = ucChar + 4;
533 ucpValues[uiValuesLen++] = 62;
537 ucpValues[uiValuesLen++] = 63;
542 ucpValues[uiValuesLen++] = 64;
545 vSetError(spConv, (uint32_t)ucChar, (uint32_t)uiOffset,
"invalid base64 character");
554 if(!(ucpValues[uiValuesLen - 1] == 64 && ucpValues[uiValuesLen - 2] == 64)){
557 }
else if(spConv->
uiTail == 1){
558 if(ucpValues[uiValuesLen - 1] != 64){
562 if((uiValuesLen % 4) != 0){
568 static void vBase64Decode(
conv* spConv, uint8_t* ucpSrc,
aint uiSrcLen){
569 uint8_t* ucpOut = NULL;
570 vBase64Validate(spConv, ucpSrc, uiSrcLen);
573 aint uiUnits = uiBaseLen / 4;
581 uint32_t ui32bits = 0;
582 for(; uu < uiUnits; uu++){
583 ui32bits = ((uint32_t)ucpBase[u4++]) << 18;
584 ui32bits += ((uint32_t)ucpBase[u4++]) << 12;
585 ui32bits += ((uint32_t)ucpBase[u4++]) << 6;
586 ui32bits += (uint32_t)ucpBase[u4++];
587 ucpOut[u3++] = (uint8_t)((ui32bits >> 16) & uiDecode64Mask);
588 ucpOut[u3++] = (uint8_t)((ui32bits >> 8) & uiDecode64Mask);
589 ucpOut[u3++] = (uint8_t)(ui32bits & uiDecode64Mask);
592 ui32bits = ((uint32_t)ucpBase[u4++]) << 18;
593 ui32bits += ((uint32_t)ucpBase[u4++]) << 12;
594 ui32bits += ((uint32_t)ucpBase[u4++]) << 6;
595 ucpOut[u3++] = (uint8_t)((ui32bits >> 16) & uiDecode64Mask);
596 ucpOut[u3++] = (uint8_t)((ui32bits >> 8) & uiDecode64Mask);
597 }
else if(spConv->
uiTail == 2){
598 ui32bits = ((uint32_t)ucpBase[u4++]) << 18;
599 ui32bits += ((uint32_t)ucpBase[u4++]) << 12;
600 ucpOut[u3++] = (uint8_t)((ui32bits >> 16) & uiDecode64Mask);
607 static void vBinaryDecode(
conv* spConv){
614 if(!ucpIn || !uiLen){
615 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
619 uipEnd = uip32 + uiLen;
620 while(uip32 < uipEnd){
621 *uip32++ = (uint32_t)*ucpIn++;
624 static void vBinaryEncode(
conv* spConv){
631 if(!uip32 || !uiLen){
632 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
636 uipEnd = uip32 + uiLen;
637 uint32_t uiOffset = 0;
638 while(uip32 < uipEnd){
640 vSetError(spConv, *uip32, uiOffset,
"can't binary encode values > 0xFF");
645 *ucpOut++ = (uint8_t)*uip32++;
649 static void vUtf32BEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen){
652 if(!ucpData || !uiDataLen){
653 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
656 if(uiDataLen %4 != 0){
660 while(uc < uiDataLen){
661 uiWord = ((uint32_t)ucpData[uc++]) << 24;
662 uiWord += ((uint32_t)ucpData[uc++]) << 16;
663 uiWord += ((uint32_t)ucpData[uc++]) << 8;
664 uiWord += (uint32_t)ucpData[uc++];
665 if(uiWord >= 0xd800 && uiWord < 0xe000){
666 vSetError(spConv, uiWord, uc,
"UTF-32BE value in surrogate pair range");
670 if(uiWord > 0x10ffff){
671 vSetError(spConv, uiWord, uc,
"UTF-32BE value out of range (> 0x10FFFF)");
678 static void vUtf32LEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen){
681 if(!ucpData || !uiDataLen){
682 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
685 if(uiDataLen %4 != 0){
689 while(uc < uiDataLen){
690 uiWord = (uint32_t)ucpData[uc++];
691 uiWord += ((uint32_t)ucpData[uc++]) << 8;
692 uiWord += ((uint32_t)ucpData[uc++]) << 16;
693 uiWord += ((uint32_t)ucpData[uc++]) << 24;
694 if(uiWord >= 0xd800 && uiWord < 0xe000){
695 vSetError(spConv, uiWord, uc,
"UTF-32LE value in surrogate pair range");
699 if(uiWord > 0x10ffff){
700 vSetError(spConv, uiWord, uc,
"UTF-32LE value out of range (> 0x10FFFF)");
707 static void vUtf32BEEncode(
conv* spConv,
conv_dst* spDst){
713 if(!uipWords || !uiWordCount){
714 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
719 ucaBuf[0] = s_caBOM32BE[0];
720 ucaBuf[1] = s_caBOM32BE[1];
721 ucaBuf[2] = s_caBOM32BE[2];
722 ucaBuf[3] = s_caBOM32BE[3];
725 for(ui = 0; ui < uiWordCount; ui++){
726 uiWord = uipWords[ui];
727 if(uiWord >= 0xd800 && uiWord < 0xe000){
728 vSetError(spConv, uiWord, ui,
"UTF-32BE value in surrogate pair range");
732 if(uiWord > 0x10ffff){
733 vSetError(spConv, uiWord, ui,
"UTF-32BE value out of range (> 0x10FFFF)");
737 ucaBuf[0] = (uint8_t)(uiWord >> 24);
738 ucaBuf[1] = (uint8_t)((uiWord >> 16) &
BYTE_MASK);
739 ucaBuf[2] = (uint8_t)((uiWord >> 8) &
BYTE_MASK);
740 ucaBuf[3] = (uint8_t)(uiWord &
BYTE_MASK);
746 static void vUtf32LEEncode(
conv* spConv,
conv_dst* spDst){
752 if(!uipWords || !uiWordCount){
753 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
758 ucaBuf[0] = s_caBOM32LE[0];
759 ucaBuf[1] = s_caBOM32LE[1];
760 ucaBuf[2] = s_caBOM32LE[2];
761 ucaBuf[3] = s_caBOM32LE[3];
764 for(ui = 0; ui < uiWordCount; ui++){
765 uiWord = uipWords[ui];
766 if(uiWord >= 0xd800 && uiWord < 0xe000){
767 vSetError(spConv, uiWord, ui,
"UTF-32LE value in surrogate pair range");
771 if(uiWord > 0x10ffff){
772 vSetError(spConv, uiWord, ui,
"UTF-32LE value out of range (> 0x10FFFF)");
776 ucaBuf[3] = (uint8_t)(uiWord >> 24);
777 ucaBuf[2] = (uint8_t)((uiWord >> 16) &
BYTE_MASK);
778 ucaBuf[1] = (uint8_t)((uiWord >> 8) &
BYTE_MASK);
779 ucaBuf[0] = (uint8_t)(uiWord &
BYTE_MASK);
785 static abool bIsBOM8(uint8_t* ucpStream,
aint uiLen){
788 if(ucpStream[0] == s_caBOM8[0] &&
789 ucpStream[1] == s_caBOM8[1] &&
790 ucpStream[2] == s_caBOM8[2]){
796 static abool bIsBOM16BE(uint8_t* ucpStream,
aint uiLen){
799 if(ucpStream[0] == s_caBOM16BE[0] &&
800 ucpStream[1] == s_caBOM16BE[1]){
806 static abool bIsBOM16LE(uint8_t* ucpStream,
aint uiLen){
809 if(ucpStream[0] == s_caBOM16LE[0] &&
810 ucpStream[1] == s_caBOM16LE[1]){
816 static abool bIsBOM32BE(uint8_t* ucpStream,
aint uiLen){
819 if(ucpStream[0] == s_caBOM32BE[0] &&
820 ucpStream[1] == s_caBOM32BE[1] &&
821 ucpStream[2] == s_caBOM32BE[2] &&
822 ucpStream[3] == s_caBOM32BE[3] ){
828 static abool bIsBOM32LE(uint8_t* ucpStream,
aint uiLen){
831 if(ucpStream[0] == s_caBOM32LE[0] &&
832 ucpStream[1] == s_caBOM32LE[1] &&
833 ucpStream[2] == s_caBOM32LE[2] &&
834 ucpStream[3] == s_caBOM32LE[3] ){
848 if(!uipWords || !uiWordCount){
849 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
854 ucaBuf[0] = s_caBOM8[0];
855 ucaBuf[1] = s_caBOM8[1];
856 ucaBuf[2] = s_caBOM8[2];
859 for(ui = 0; ui < uiWordCount; ui++){
860 uiWord = uipWords[ui];
863 ucaBuf[0] = (uint8_t)uiWord;
865 }
else if(uiWord < 0x800){
867 ucaBuf[0] = 0xc0 + (uint8_t)((uiWord & 0x7c0) >> 6);
868 ucaBuf[1] = 0x80 + (uint8_t)(uiWord & 0x3f);
870 }
else if(uiWord < 0xd800){
872 ucaBuf[0] = 0xe0 + (uint8_t)((uiWord & 0xf000) >> 12);
873 ucaBuf[1] = 0x80 + (uint8_t)((uiWord & 0xfc0) >> 6);
874 ucaBuf[2] = 0x80 + (uint8_t)(uiWord & 0x3f);
876 }
else if(uiWord < 0xe000){
878 vSetError(spConv, uiWord, ui,
"UTF-8 value in surrogate pair");
881 }
else if(uiWord < 0x10000){
883 ucaBuf[0] = 0xe0 + (uint8_t)((uiWord & 0xf000) >> 12);
884 ucaBuf[1] = 0x80 + (uint8_t)((uiWord & 0xfc0) >> 6);
885 ucaBuf[2] = 0x80 + (uint8_t)(uiWord & 0x3f);
887 }
else if(uiWord <= 0x10ffff){
889 ucaBuf[0] = 0xf0 + (uint8_t)((uiWord & 0x1c0000) >> 18);
890 ucaBuf[1] = 0x80 + (uint8_t)((uiWord & 0x3f000) >> 12);
891 ucaBuf[2] = 0x80 + (uint8_t)((uiWord & 0xfc0) >> 6);
892 ucaBuf[3] = 0x80 + (uint8_t)(uiWord & 0x3f);
896 vSetError(spConv, uiWord, ui,
"UTF-8 value out of range (> 0x10FFFF)");
904 static void vUtf8Decode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen){
905 if(!ucpData || !uiDataLen){
906 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
912 aint uiRemainder = uiDataLen - 1;
913 while(uc < uiDataLen){
914 ucChar = ucpData[uc];
915 if(ucChar == 0xc0 || ucChar == 0xc1 || ucChar >= 0xf5){
916 vSetError(spConv, (uint32_t)ucChar, uc,
"invalid UTF-8 value");
922 uiWord = (uint32_t)ucChar;
925 }
else if(ucChar < 0xe0){
928 vSetError(spConv, (uint32_t)ucChar, uc,
"UTF-8 data has too few trailing bytes");
932 uiWord = (uint32_t)(ucChar & 0x1f) << 6;
933 uiWord += (uint32_t)(ucpData[++uc] & 0x3f);
936 }
else if(ucChar < 0xf0){
939 vSetError(spConv, (uint32_t)ucChar, uc,
"UTF-8 data has too few trailing bytes");
943 uiWord = (uint32_t)(ucChar & 0xf) << 12;
944 uiWord += (uint32_t)(ucpData[++uc] & 0x3f) << 6;
945 uiWord += (uint32_t)(ucpData[++uc] & 0x3f);
948 if(uiWord >= 0xd800 && uiWord <= 0xdfff){
949 vSetError(spConv, (uint32_t)ucChar, (uc - 3),
"UTF-8 value in surrogate pair range (0xD800 - 0xDFFF)");
954 vSetError(spConv, (uint32_t)ucChar, (uc - 3),
"UTF-8 value has over-long encoding");
958 }
else if(ucChar < 0xf5){
961 vSetError(spConv, (uint32_t)ucChar, uc,
"UTF-8 data has too few trailing bytes");
966 uiWord = (uint32_t)(ucChar & 0x7) << 18;
967 uiWord += (uint32_t)(ucpData[++uc] & 0x3f) << 12;
968 uiWord += (uint32_t)(ucpData[++uc] & 0x3f) << 6;
969 uiWord += (uint32_t)(ucpData[++uc] & 0x3f);
972 if(uiWord < 0x10000){
973 vSetError(spConv, (uint32_t)ucChar, (uc - 4),
"UTF-8 value has over-long encoding");
977 if(uiWord > 0x10ffff){
978 vSetError(spConv, (uint32_t)ucChar, (uc - 4),
"UTF-8 value out of range (> 0x10FFFF)");
986 static void vUtf16BEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen){
987 if(!ucpData || !uiDataLen){
988 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
991 if(uiDataLen % 2 != 0){
995 uint32_t uiLow, uiHigh;
997 aint uiRemainder = uiDataLen;
998 while(uc < uiDataLen){
999 uiHigh = (((uint32_t)ucpData[uc]) << 8);
1001 uiHigh += (((uint32_t)ucpData[uc]) & 0xff);
1004 if(uiHigh >= 0xd800 && uiHigh < 0xdc00){
1006 if(uiRemainder == 0){
1007 vSetError(spConv, uiHigh, (uc - 2),
"UTF-16BE data has missing low surrogate value");
1011 uiLow = (((uint32_t)ucpData[uc]) << 8);
1013 uiLow += (((uint32_t)ucpData[uc]) & 0xff);
1016 if(uiLow >= 0xdc00 && uiLow < 0xe000){
1017 uiHigh = (uiHigh - 0xd800) << 10;
1019 uiHigh += uiLow + 0x10000;
1022 vSetError(spConv, uiLow, (uc - 2),
"UTF-16BE data has missing low surrogate value");
1027 if(uiHigh >= 0xdc00 && uiHigh < 0xe000){
1028 vSetError(spConv, uiHigh, (uc - 2),
"UTF-16BE data has high surrogate out of order");
1037 static void vUtf16LEDecode(
conv* spConv, uint8_t* ucpData,
aint uiDataLen){
1038 if(!ucpData || !uiDataLen){
1039 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
1042 if(uiDataLen % 2 != 0){
1046 uint32_t uiLow, uiHigh;
1048 aint uiRemainder = uiDataLen;
1049 while(uc < uiDataLen){
1050 uiHigh = (((uint32_t)ucpData[uc]) & 0xff);
1052 uiHigh += (((uint32_t)ucpData[uc]) << 8);
1055 if(uiHigh >= 0xd800 && uiHigh < 0xdc00){
1057 if(uiRemainder == 0){
1058 vSetError(spConv, uiHigh, (uc - 2),
"UTF-16LE data has missing low surrogate value");
1062 uiLow = (((uint32_t)ucpData[uc]) & 0xff);
1064 uiLow += (((uint32_t)ucpData[uc]) << 8);
1067 if(uiLow >= 0xdc00 && uiLow < 0xe000){
1068 uiHigh = (uiHigh - 0xd800) << 10;
1070 uiHigh += uiLow + 0x10000;
1073 vSetError(spConv, uiLow, (uc - 2),
"UTF-16LE data has missing low surrogate value");
1078 if(uiHigh >= 0xdc00 && uiHigh < 0xe000){
1079 vSetError(spConv, uiHigh, (uc - 2),
"UTF-16LE data has high surrogate out of order");
1088 static void vUtf16BEEncode(
conv* spConv,
conv_dst* spDst){
1096 if(!uipWords || !uiWordCount){
1097 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
1102 ucaBuf[0] = s_caBOM16BE[0];
1103 ucaBuf[1] = s_caBOM16BE[1];
1106 for(ui = 0; ui < uiWordCount; ui++){
1107 uiWord = uipWords[ui];
1108 if(uiWord < 0x10000){
1110 if(uiWord >= 0xd800 && uiWord < 0xe000){
1111 vSetError(spConv, uiWord, ui,
"UTF-16BE has value in surrogate pair range (0xD800-0xDFFF)");
1115 ucaBuf[0] = (uint8_t)(uiWord >> 8);
1116 ucaBuf[1] = (uint8_t)(uiWord & 0xFF);
1118 }
else if(uiWord <= 0x10FFFF){
1121 uint32_t uiHigh = 0xd800 + (uiWord >> 10);
1122 uint32_t uiLow = 0xdc00 + (uiWord & 0x3FF);
1123 ucaBuf[0] = (uint8_t)(uiHigh >> 8);
1124 ucaBuf[1] = (uint8_t)(uiHigh & 0xFF);
1125 ucaBuf[2] = (uint8_t)(uiLow >> 8);
1126 ucaBuf[3] = (uint8_t)(uiLow & 0xFF);
1130 vSetError(spConv, uiWord, ui,
"UTF-16BE has value out of range (> 0x10FFFF)");
1138 static void vUtf16LEEncode(
conv* spConv,
conv_dst* spDst){
1146 if(!uipWords || !uiWordCount){
1147 XTHROW(spConv->
spException,
"internal error - function called without necessary data");
1152 ucaBuf[0] = s_caBOM16LE[0];
1153 ucaBuf[1] = s_caBOM16LE[1];
1156 for(ui = 0; ui < uiWordCount; ui++){
1157 uiWord = uipWords[ui];
1158 if(uiWord < 0x10000){
1160 if(uiWord >= 0xd800 && uiWord < 0xe000){
1161 vSetError(spConv, uiWord, ui,
"UTF-16LE has value in surrogate pair range (0xD800-0xDFFF)");
1165 ucaBuf[1] = (uint8_t)(uiWord >> 8);
1166 ucaBuf[0] = (uint8_t)(uiWord & 0xFF);
1168 }
else if(uiWord <= 0x10FFFF){
1171 uint32_t uiHigh = 0xd800 + (uiWord >> 10);
1172 uint32_t uiLow = 0xdc00 + (uiWord & 0x3FF);
1173 ucaBuf[1] = (uint8_t)(uiHigh >> 8);
1174 ucaBuf[0] = (uint8_t)(uiHigh & 0xFF);
1175 ucaBuf[3] = (uint8_t)(uiLow >> 8);
1176 ucaBuf[2] = (uint8_t)(uiLow & 0xFF);
1180 vSetError(spConv, uiWord, ui,
"UTF-16LE has value out of range (> 0x10FFFF)");
1188 static void vSetError(
conv* spConv, uint32_t uiValue, uint32_t uiOffset,
const char* cpMsg){