Convert and map inconvertible Unicode characters. We use it for extended ASCII names in Unix.
| 181 | // Convert and map inconvertible Unicode characters. |
| 182 | // We use it for extended ASCII names in Unix. |
| 183 | void CharToWideMap(const char *Src,wchar *Dest,size_t DestSize,bool &Success) |
| 184 | { |
| 185 | // Map inconvertible characters to private use Unicode area 0xE000. |
| 186 | // Mark such string by placing special non-character code before |
| 187 | // first inconvertible character. |
| 188 | Success=false; |
| 189 | bool MarkAdded=false; |
| 190 | uint SrcPos=0,DestPos=0; |
| 191 | while (DestPos<DestSize) |
| 192 | { |
| 193 | if (Src[SrcPos]==0) |
| 194 | { |
| 195 | Success=true; |
| 196 | break; |
| 197 | } |
| 198 | mbstate_t ps; |
| 199 | memset(&ps,0,sizeof(ps)); |
| 200 | size_t res=mbrtowc(Dest+DestPos,Src+SrcPos,MB_CUR_MAX,&ps); |
| 201 | if (res==(size_t)-1 || res==(size_t)-2) |
| 202 | { |
| 203 | // For security reasons we do not want to map low ASCII characters, |
| 204 | // so we do not have additional .. and path separator codes. |
| 205 | if (byte(Src[SrcPos])>=0x80) |
| 206 | { |
| 207 | if (!MarkAdded) |
| 208 | { |
| 209 | Dest[DestPos++]=MappedStringMark; |
| 210 | MarkAdded=true; |
| 211 | if (DestPos>=DestSize) |
| 212 | break; |
| 213 | } |
| 214 | Dest[DestPos++]=byte(Src[SrcPos++])+MapAreaStart; |
| 215 | } |
| 216 | else |
| 217 | break; |
| 218 | } |
| 219 | else |
| 220 | { |
| 221 | memset(&ps,0,sizeof(ps)); |
| 222 | int Length=mbrlen(Src+SrcPos,MB_CUR_MAX,&ps); |
| 223 | SrcPos+=Max(Length,1); |
| 224 | DestPos++; |
| 225 | } |
| 226 | } |
| 227 | Dest[Min(DestPos,DestSize-1)]=0; |
| 228 | } |
| 229 | #endif |
| 230 | |
| 231 |