#include once "utf_conv.bi" #include once "crt/string.bi" const LN2 = log(2) type TWString as integer reservedChars as wstring ptr value declare constructor declare constructor(str_ as string) declare constructor(ascii as uinteger) declare destructor declare operator cast as wstring ptr declare operator cast as string declare operator let(tw as TWString) declare operator let(s as string) declare operator [](index as uinteger) as uinteger declare function mid(byval first as uinteger = 1, byval length as integer = -1) as TWString declare function wordLength as integer end type declare operator len(tw as TWString) as integer declare operator =(tw1 as TWString, tw2 as TWString) as integer declare operator <(tw1 as TWString, tw2 as TWString) as integer declare operator >(tw1 as TWString, tw2 as TWString) as integer declare operator <>(tw1 as TWString, tw2 as TWString) as integer declare operator &(w as TWString, s as string) as TWString declare operator &(s as string, w as TWString) as TWString declare operator &(w1 as TWString, w2 as TWString) as TWString constructor TWString end constructor constructor TWString(str_ as string) dim as integer size = len(str_) reservedChars = size+1 value = callocate(reservedChars*sizeof(wstring)) UTFToWChar UTF_ENCOD_UTF8, strptr(str_), value, @size end constructor constructor TWString(ascii as uinteger) reservedChars = 2 value = callocate(reservedChars*sizeof(wstring)) *value = wchr(ascii) end constructor destructor TWString if reservedChars then reservedChars = 0 deallocate value end if end destructor operator TWString.cast as wstring ptr return value end operator operator TWString.cast as string if reservedChars = 0 then return "" dim bytes as integer, temp as string = space(len(*value)*8) WCharToUTF UTF_ENCOD_UTF8, value, len(*value), strptr(temp), @bytes return left(temp, bytes) end operator operator TWString.let(tw as TWString) if tw.reservedChars = 0 then reservedChars = 0 deallocate value exit operator end if dim as integer size = 1 shl int(log(len(tw))/LN2 + 1) if reservedChars = 0 then reservedChars = size value = callocate(reservedChars*sizeof(wstring)) elseif reservedChars < size then reservedChars = size value = reallocate(value, reservedChars*sizeof(wstring)) end if memcpy value, tw.value, (len(tw)+1)*sizeof(wstring) end operator operator TWString.let(s as string) if s = "" then if reservedChars then reservedChars = 0 deallocate value end if exit operator end if dim as integer size = len(s)+1 if reservedChars = 0 then reservedChars = size value = callocate(reservedChars*sizeof(wstring)) elseif reservedChars < size then reservedChars = size value = reallocate(value, reservedChars*sizeof(wstring)) end if UTFToWChar UTF_ENCOD_UTF8, strptr(s), value, @size end operator operator len(tw as TWString) as integer if tw.reservedChars = 0 then return 0 return len(*tw.value) end operator operator =(tw1 as TWString, tw2 as TWString) as integer return *tw1.value = *tw2.value end operator operator <(tw1 as TWString, tw2 as TWString) as integer return *tw1.value < *tw2.value end operator operator >(tw1 as TWString, tw2 as TWString) as integer return *tw1.value > *tw2.value end operator operator <>(tw1 as TWString, tw2 as TWString) as integer return *tw1.value <> *tw2.value end operator operator TWString.[](index as uinteger) as uinteger if index >= len(*value) then return 0 return asc(value[index]) end operator operator &(w as TWString, s as string) as TWString dim as integer size = len(s) dim as TWString ret = string(len(w) + len(s), 32) & chr(0) dim as wstring ptr temp = callocate((len(s)+1)*sizeof(wstring)) UTFToWChar UTF_ENCOD_UTF8, strptr(s), temp, @size memcpy ret.value, w.value, len(w)*sizeof(wstring) memcpy ret.value+len(w), temp, (len(*temp)+1)*sizeof(wstring) deallocate temp return ret end operator operator &(s as string, w as TWString) as TWString dim as integer size = len(s) dim as TWString ret = string(len(w) + len(s), 32) & chr(0) dim as wstring ptr temp = callocate((len(s)+1)*sizeof(wstring)) UTFToWChar UTF_ENCOD_UTF8, strptr(s), temp, @size memcpy ret.value, temp, len(*temp)*sizeof(wstring) memcpy ret.value+len(*temp), w.value, (len(w)+1)*sizeof(wstring) deallocate temp return ret end operator operator &(w1 as TWString, w2 as TWString) as TWString dim as TWString ret = string(len(w1) + len(w2), 32) & chr(0) memcpy ret.value, w1.value, len(w1)*sizeof(wstring) memcpy ret.value+len(w1), w2.value, len(w2)*sizeof(wstring) return ret end operator function TWString.mid(byval first as uinteger = 1, byval length as integer = -1) as TWString if first = 0 or length = 0 then return "" dim as uinteger last, thislength = len(this) if first > thislength then return "" if length < 0 then last = thislength else last = first + length - 1 if last > thislength then last = len(this) end if dim as TWString ret = string(last-first+2, 0) for i as integer = first to last ret.value[i-first] = asc(value[i-1]) next return ret end function function TWString.wordLength as integer ' returns the word size, excluding escape chars dim as integer ret = 0, i = 0 do while i < len(*value) if value[i] = 0 then exit do if value[i] = 27 then i += 2 : continue do #ifdef FONT_STRESS_ESCAPE if value[i] = FONT_STRESS_CHAR then i += 1 : continue do #endif ret += 1 i += 1 loop return ret end function