Merge pull request #3231 from jangko/devel

fixed UTF-16 to UTF-8 conversion in widestrs.nim
This commit is contained in:
Andreas Rumpf 2015-08-21 21:28:24 +02:00
commit abccaa15d8
2 changed files with 135 additions and 23 deletions

View file

@ -114,41 +114,47 @@ proc newWideCString*(s: cstring): WideCString =
proc newWideCString*(s: string): WideCString =
result = newWideCString(s, s.len)
proc `$`*(w: WideCString, estimate: int): string =
proc `$`*(w: WideCString, estimate: int, replacement: int = 0xFFFD): string =
result = newStringOfCap(estimate + estimate shr 2)
var i = 0
while w[i].int16 != 0'i16:
var ch = w[i].int
var ch = int(cast[uint16](w[i]))
inc i
if ch >=% UNI_SUR_HIGH_START and ch <=% UNI_SUR_HIGH_END:
if ch >= UNI_SUR_HIGH_START and ch <= UNI_SUR_HIGH_END:
# If the 16 bits following the high surrogate are in the source buffer...
let ch2 = w[i].int
let ch2 = int(cast[uint16](w[i]))
# If it's a low surrogate, convert to UTF32:
if ch2 >=% UNI_SUR_LOW_START and ch2 <=% UNI_SUR_LOW_END:
ch = ((ch -% UNI_SUR_HIGH_START) shr halfShift) +%
(ch2 -% UNI_SUR_LOW_START) +% halfBase
if ch2 >= UNI_SUR_LOW_START and ch2 <= UNI_SUR_LOW_END:
ch = (((ch and halfMask) shl halfShift) + (ch2 and halfMask)) + halfBase
inc i
if ch <=% 127:
else:
#invalid UTF-16
ch = replacement
elif ch >= UNI_SUR_LOW_START and ch <= UNI_SUR_LOW_END:
#invalid UTF-16
ch = replacement
if ch < 0x80:
result.add chr(ch)
elif ch <=% 0x07FF:
result.add chr((ch shr 6) or 0b110_00000)
result.add chr((ch and ones(6)) or 0b10_000000)
elif ch <=% 0xFFFF:
result.add chr(ch shr 12 or 0b1110_0000)
result.add chr(ch shr 6 and ones(6) or 0b10_0000_00)
result.add chr(ch and ones(6) or 0b10_0000_00)
elif ch <=% 0x0010FFFF:
result.add chr(ch shr 18 or 0b1111_0000)
result.add chr(ch shr 12 and ones(6) or 0b10_0000_00)
result.add chr(ch shr 6 and ones(6) or 0b10_0000_00)
result.add chr(ch and ones(6) or 0b10_0000_00)
elif ch < 0x800:
result.add chr((ch shr 6) or 0xc0)
result.add chr((ch and 0x3f) or 0x80)
elif ch < 0x10000:
result.add chr((ch shr 12) or 0xe0)
result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80)
elif ch <= 0x10FFFF:
result.add chr((ch shr 18) or 0xf0)
result.add chr(((ch shr 12) and 0x3f) or 0x80)
result.add chr(((ch shr 6) and 0x3f) or 0x80)
result.add chr((ch and 0x3f) or 0x80)
else:
# replacement char:
# replacement char(in case user give very large number):
result.add chr(0xFFFD shr 12 or 0b1110_0000)
result.add chr(0xFFFD shr 6 and ones(6) or 0b10_0000_00)
result.add chr(0xFFFD and ones(6) or 0b10_0000_00)
proc `$`*(s: WideCString): string =
result = s $ 80