다음 코드는 잠시 동안 작업 한 IRI 라이브러리를 기반으로합니다.의 섹션 3.2 ("URI를 IRI로 변환")는 유효하지 않은 UTF-8 옥텟을 유효한 UTF-8로 변환하는 것을 다룹니다.
#define IS_IN_RANGE(c, f, l) (((c) >= (f)) && ((c) <= (l)))
int UTF8BufferToUTF32Buffer(char *Data, int DataLen, unsigned long *Buffer, int BufLen, int *Eaten)
{
if(Eaten)
{
*Eaten = 0;
}
int Result = 0;
unsigned char b, b2;
unsigned char *ptr = (unsigned char*) Data;
unsigned long uc;
int i = 0;
int seqlen;
while(i < DataLen)
{
if((Buffer) && (!BufLen))
break;
b = ptr[i];
if((b & 0x80) == 0)
{
uc = (unsigned long)(b & 0x7F);
seqlen = 1;
}
else if((b & 0xE0) == 0xC0)
{
uc = (unsigned long)(b & 0x1F);
seqlen = 2;
}
else if((b & 0xF0) == 0xE0)
{
uc = (unsigned long)(b & 0x0F);
seqlen = 3;
}
else if((b & 0xF8) == 0xF0)
{
uc = (unsigned long)(b & 0x07);
seqlen = 4;
}
else
{
uc = 0;
return -1;
}
if((i+seqlen) > DataLen)
{
return -1;
}
for(int j = 1; j < seqlen; ++j)
{
b = ptr[i+j];
if((b & 0xC0) != 0x80)
{
return -1;
}
}
switch(seqlen)
{
case 2:
{
b = ptr[i];
if(!IS_IN_RANGE(b, 0xC2, 0xDF))
{
return -1;
}
break;
}
case 3:
{
b = ptr[i];
b2 = ptr[i+1];
if(((b == 0xE0) && !IS_IN_RANGE(b2, 0xA0, 0xBF)) ||
((b == 0xED) && !IS_IN_RANGE(b2, 0x80, 0x9F)) ||
(!IS_IN_RANGE(b, 0xE1, 0xEC) && !IS_IN_RANGE(b, 0xEE, 0xEF)))
{
return -1;
}
break;
}
case 4:
{
b = ptr[i];
b2 = ptr[i+1];
if(((b == 0xF0) && !IS_IN_RANGE(b2, 0x90, 0xBF)) ||
((b == 0xF4) && !IS_IN_RANGE(b2, 0x80, 0x8F)) ||
!IS_IN_RANGE(b, 0xF1, 0xF3))
{
return -1;
}
break;
}
}
for(int j = 1; j < seqlen; ++j)
{
uc = ((uc << 6) | (unsigned long)(ptr[i+j] & 0x3F));
}
if(Buffer)
{
*Buffer++ = uc;
--BufLen;
}
++Result;
i += seqlen;
}
if(Eaten)
{
*Eaten = i;
}
return Result;
}
{
std::string filename = "...";
unsigned long ch;
int eaten;
std::string::size_type i = 0;
while(i < filename.length())
{
if(UTF8BufferToUTF32Buffer(&filename[i], filename.length()-i, &ch, 1, &eaten) == 1)
{
i += eaten;
}
else
{
// replace the character at filename[i] with your chosen
// escaping, and then increment i by the number of
// characters used...
}
}
}
당신이해야 할 일은 어떤 종류의 이스케이프를 사용할지 결정하는 것입니다. URI/IRI는 백분율 인코딩 ("NN"은 한 옥텟의 2 자리 16 진수 값)을 사용합니다 ("% NN").
ICU 등의 라이브러리를 사용할 수 있습니까? – kennytm
"이스케이프 처리"는 일반적으로 "다음 토큰이 다른 의미로 사용된다는 신호를 나타내는 프리픽스 삽입"을 의미합니다. 예 : ''\ t ''은't '가 문자't '가 아니라 TAB이라는 것을 의미합니다. 이것은 아마 당신이 찾고있는 것이 아닙니다. 예를 들어, 'FF'바이트는 UTF-8로 나타나지 않습니다. 따라서 "FF"문자열이 UTF-8이 아닌 한 "escape"를 삽입해도 상관 없습니다. – MSalters
오른쪽. 바이트 FF가 바이너리에서 발생하면, 그것을 바꿀 필요가있다. 나는 BASE64와 노드에 XML을 BASE64로 인코딩 한 노드를 넣을 수도 있지만 그렇지 않을 것이다. 흠. 내가 8 진수로 탈출 할 수 ... – vy32