0031878: DXF import - support Windows and ISO 8859 code pages in DXF import
[occt.git] / src / Resource / Resource_Unicode.cxx
1 // Created on: 1996-09-26
2 // Created by: Arnaud BOUZY
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Resource_ConvertUnicode.hxx>
19 #include <Resource_Manager.hxx>
20 #include <Resource_Unicode.hxx>
21 #include <TCollection_AsciiString.hxx>
22 #include <TCollection_ExtendedString.hxx>
23 #include <NCollection_UtfString.hxx>
24 #include <Standard_NotImplemented.hxx>
25 #include "Resource_CodePages.pxx"
26 #include "Resource_GBK.pxx"
27 #include "Resource_Big5.pxx"
28
29 #define isjis(c) (((c)>=0x21 && (c)<=0x7e))
30 #define iseuc(c) (((c)>=0xa1 && (c)<=0xfe))
31 #define issjis1(c) (((c)>=0x81 && (c)<=0x9f) || ((c)>=0xe0 && (c)<=0xef))
32
33 #define issjis2(c) ((c)>=0x40 && (c)<=0xfc && (c)!=0x7f)
34
35 #define ishankana(c) ((c)>=0xa0 && (c)<=0xdf)
36
37 static inline Standard_Boolean isshift (unsigned char c) { return c >= 0x80; }
38 static inline Standard_Boolean isshift (unsigned int c) { return c >= 0x80 && c <= 0xff; }
39
40 void Resource_Unicode::ConvertSJISToUnicode(const Standard_CString fromstr,TCollection_ExtendedString& tostr)
41 {
42   tostr.Clear();
43
44   unsigned char* currentstr = ((unsigned char*) fromstr);
45   unsigned int pl,ph;
46   // BIG INDIAN USED HERE
47   while(*currentstr != '\0') {
48     if (issjis1(*currentstr)) {
49       
50       ph = ((unsigned int) *currentstr);
51       // Be Carefull with first and second !!
52
53       currentstr++;
54
55       pl =  ((unsigned int) *currentstr);
56       currentstr++;
57       
58       Resource_sjis_to_unicode(&ph,&pl);
59       Standard_ExtCharacter curcar = ((Standard_ExtCharacter) ((ph << 8) | pl));
60       TCollection_ExtendedString curext(curcar);
61       tostr.AssignCat(curext);
62     }
63     else {
64       TCollection_ExtendedString curext(((char) *currentstr));
65       currentstr++;
66       tostr.AssignCat(curext);
67     }
68   }
69 }
70
71
72 void Resource_Unicode::ConvertEUCToUnicode(const Standard_CString fromstr,TCollection_ExtendedString& tostr)
73 {
74   tostr.Clear();
75
76   unsigned char* currentstr = ((unsigned char*) fromstr);
77   unsigned int pl,ph;
78   // BIG INDIAN USED HERE
79   while(*currentstr != '\0') {
80     if (iseuc(*currentstr)) {
81       
82       ph = ((unsigned int) *currentstr);
83       // Be Carefull with first and second !!
84
85       currentstr++;
86
87       pl =  ((unsigned int) *currentstr);
88       currentstr++;
89       
90       Resource_euc_to_unicode(&ph,&pl);
91       Standard_ExtCharacter curcar = ((Standard_ExtCharacter) ((ph << 8) | pl));
92       TCollection_ExtendedString curext(curcar);
93       tostr.AssignCat(curext);
94     }
95     else {
96       TCollection_ExtendedString curext(((char) *currentstr));
97       currentstr++;
98       tostr.AssignCat(curext);
99     }
100   }
101 }
102
103 void Resource_Unicode::ConvertGBToUnicode(const Standard_CString fromstr,TCollection_ExtendedString& tostr)
104 {
105   tostr.Clear();
106
107   unsigned char* currentstr = ((unsigned char*) fromstr);
108   unsigned int pl,ph;
109   // BIG INDIAN USED HERE
110   while(*currentstr != '\0') {
111     if (isshift(*currentstr)) {
112       
113       ph = ((unsigned int) *currentstr);
114       // Be Carefull with first and second !!
115
116       currentstr++;
117
118       pl =  ((unsigned int) *currentstr);
119       currentstr++;
120       
121       Resource_gb_to_unicode(&ph,&pl);
122       Standard_ExtCharacter curcar = ((Standard_ExtCharacter) ((ph << 8) | pl));
123       TCollection_ExtendedString curext(curcar);
124       tostr.AssignCat(curext);
125     }
126     else {
127       TCollection_ExtendedString curext(((char) *currentstr));
128       currentstr++;
129       tostr.AssignCat(curext);
130     }
131   }
132 }
133
134 Standard_Boolean Resource_Unicode::ConvertGBKToUnicode(const Standard_CString fromstr, TCollection_ExtendedString& tostr)
135 {
136   tostr.Clear();
137
138   unsigned char* currentch = ((unsigned char*) fromstr);
139   unsigned int gb1 = 0x00, gb2 = 0x00, gb3 = 0x00;
140
141   while(*currentch != '\0') {
142     if (gb3 != 0x00)
143     {
144       if (!(*currentch >= 0x30 && *currentch <= 0x39))
145       {
146         TCollection_ExtendedString curext3(((char) *currentch));
147         TCollection_ExtendedString curext2(((char) gb3));
148         TCollection_ExtendedString curext1(((char) gb2));
149         tostr.Insert(0, curext3);
150         tostr.Insert(0, curext2);
151         tostr.Insert(0, curext1);
152         gb1 = 0;
153         gb2 = 0;
154         gb3 = 0;
155         return Standard_False;
156       }
157
158       unsigned int codepnt = ((gb1 - 0x81) * (10 * 126 * 10)) + ((gb2 - 0x30) * (10 * 126)) + ((gb3 - 0x81) * 10) + *currentch - 0x30;
159       if (codepnt < 23940)
160       {
161         unsigned short uni = gbkuni [codepnt];
162         Standard_ExtCharacter curcar = ((Standard_ExtCharacter)uni);
163         TCollection_ExtendedString curext(curcar);
164         tostr.AssignCat(curext);
165         currentch++;
166         continue;
167       }
168
169       return Standard_False;
170     }
171     else if (gb2 != 0x00)
172     {
173       if (*currentch >= 0x81 && *currentch <= 0xFE)
174       {
175         gb3 = (unsigned int)(*currentch);
176         currentch++;
177         continue;
178       }
179       TCollection_ExtendedString curext2(((char) *currentch));
180       TCollection_ExtendedString curext1(((char) gb2));
181       tostr.Insert(0, curext2);
182       tostr.Insert(0, curext1);
183       gb1 = 0;
184       gb2 = 0;
185       return Standard_False;
186     }
187     else if (gb1 != 0x00)
188     {
189       if (*currentch >= 0x30 && *currentch <= 0x39)
190       {
191         gb2 = (unsigned int)(*currentch);
192         currentch++;
193         continue;
194       }
195
196       unsigned int lead = gb1;
197       unsigned int pointer = 0;
198       gb1 = 0x00;
199       unsigned int offset = *currentch < 0x7F ? 0x40 : 0x41;
200
201       if ((*currentch >= 0x40 && *currentch <= 0x7E) ||
202           (*currentch >= 0x80 && *currentch <= 0xFE))
203       {
204         pointer = (lead - 0x81) * 190 + (*currentch - offset);
205
206         if (pointer < 23940)
207         {
208           unsigned short uni = gbkuni [pointer];
209           Standard_ExtCharacter curcar = ((Standard_ExtCharacter)uni);
210           TCollection_ExtendedString curext(curcar);
211           tostr.AssignCat(curext);
212           currentch++;
213           continue;
214         }
215       }
216       if (*currentch <= 0x7F)
217       {
218         // ASCII symbol
219         TCollection_ExtendedString curext(((char) *currentch));
220         currentch++;
221         tostr.Insert(0, curext);
222         continue;
223       }
224       return Standard_False;
225     }
226     else
227     {
228       if (*currentch <= 0x7F)
229       {
230         // ASCII symbol
231         TCollection_ExtendedString curext(((char) *currentch));
232         currentch++;
233         tostr.AssignCat(curext);
234       }
235       else if (*currentch == 0x80)
236       {
237         // Special symbol
238         Standard_ExtCharacter curcar = ((Standard_ExtCharacter)((0x20 << 8) | 0xAC));
239         TCollection_ExtendedString curext(curcar);
240         tostr.AssignCat(curext);
241         currentch++;
242       }
243       else if (*currentch >= 0x81 && *currentch <= 0xFE) {
244         // Chinese symbol
245         gb1 = (unsigned int)(*currentch);
246         currentch++;
247       }
248       else
249         return Standard_False;
250     }
251   }
252   return Standard_True;
253 }
254
255 Standard_Boolean Resource_Unicode::ConvertBig5ToUnicode(const Standard_CString fromstr, TCollection_ExtendedString& tostr)
256 {
257   tostr.Clear();
258
259   unsigned char* currentch = ((unsigned char*) fromstr);
260   unsigned int big5lead = 0x00;
261
262   while(*currentch != '\0') {
263     if (big5lead != 0x00)
264     {
265       unsigned int lead = big5lead;
266       unsigned int pointer = 0;
267       big5lead = 0x00;
268       unsigned int offset = *currentch < 0x7F ? 0x40 : 0x62;
269
270       if ((*currentch >= 0x40 && *currentch <= 0x7E) ||
271           (*currentch >= 0xA1 && *currentch <= 0xFE))
272       {
273         pointer = (lead - 0x81) * 157 + (*currentch - offset);
274
275         Standard_Integer aLength = tostr.Length();
276         switch (pointer) {
277         case 1133: {
278           tostr.Insert(aLength+1,(Standard_ExtCharacter)0x00CA);
279           tostr.Insert(aLength+2,(Standard_ExtCharacter)0x0304);
280           currentch++;
281           continue;
282         }
283         case 1135: {
284           tostr.Insert(aLength+1,(Standard_ExtCharacter)0x00CA);
285           tostr.Insert(aLength+2,(Standard_ExtCharacter)0x030C);
286           currentch++;
287           continue;
288         }
289         case 1164: {
290           tostr.Insert(aLength+1,(Standard_ExtCharacter)0x00EA);
291           tostr.Insert(aLength+2,(Standard_ExtCharacter)0x0304);
292           currentch++;
293           continue;
294         }
295         case 1166: {
296           tostr.Insert(aLength+1,(Standard_ExtCharacter)0x00EA);
297           tostr.Insert(aLength+2,(Standard_ExtCharacter)0x030C);
298           currentch++;
299           continue;
300         }
301         default: {
302           if (pointer < 19782)
303           {
304             unsigned int uni = big5uni [pointer];
305             if (uni <= 0xFFFF)
306             {
307               Standard_ExtCharacter curcar = ((Standard_ExtCharacter)uni);
308               tostr.Insert(aLength+1,curcar);
309             }
310             else
311             {
312               Standard_Utf32Char* aChar32 = new Standard_Utf32Char[1];
313               aChar32[0] = uni;
314               NCollection_Utf32String aStr32(aChar32);
315               NCollection_Utf16String aStr16 = aStr32.ToUtf16();
316
317               if (aStr16.Size() != 4) return Standard_False; // not a surrogate pair
318               const Standard_Utf16Char* aChar16 = aStr16.ToCString();
319               tostr.Insert(aLength+1,(Standard_ExtCharacter)(*aChar16));
320               aChar16++;
321               tostr.Insert(aLength+2,(Standard_ExtCharacter)(*aChar16));
322             }
323             currentch++;
324             continue;
325           }
326         }
327         }
328       }
329       if (*currentch <= 0x7F)
330       {
331         // ASCII symbol
332         TCollection_ExtendedString curext(((char) *currentch));
333         currentch++;
334         tostr.Insert(0, curext);
335         continue;
336       }
337       return Standard_False;
338     }
339     else
340     {
341       if (*currentch <= 0x7F)
342       {
343         // ASCII symbol
344         TCollection_ExtendedString curext(((char) *currentch));
345         currentch++;
346         tostr.AssignCat(curext);
347       }
348       else if (*currentch >= 0x81 && *currentch <= 0xFE) {
349         // Chinese symbol
350         big5lead = (unsigned int)(*currentch);
351         currentch++;
352       }
353       else
354         return Standard_False;
355     }
356   }
357   return Standard_True;
358 }
359
360 Standard_Boolean Resource_Unicode::ConvertUnicodeToSJIS(const TCollection_ExtendedString& fromstr,
361                                                         Standard_PCharacter& tostr,
362                                                         const Standard_Integer maxsize)
363 {
364   Standard_Integer nbtrans = 0;
365   Standard_Integer nbext = 1;
366   Standard_Boolean finished = Standard_False;
367   Standard_ExtCharacter curcar;
368   unsigned int pl,ph;
369   // BIG INDIAN USED HERE
370   
371   while (!finished) {
372     if (nbext > fromstr.Length()) {
373       finished = Standard_True;
374       tostr[nbtrans] = '\0';
375     }
376     else {
377       curcar = fromstr.Value(nbext);
378       nbext++;
379       ph = (((unsigned int) curcar) >> 8) & 0xFF;
380       pl = ((unsigned int) curcar) & 0xFF;
381       Resource_unicode_to_sjis(&ph,&pl);
382       if (issjis1(ph)) {
383         if (nbtrans < (maxsize-3)) {
384           tostr[nbtrans] = ((char) ph);
385           nbtrans++;
386           tostr[nbtrans] =  ((char) pl);
387           nbtrans++;
388         }
389         else {
390           tostr[nbtrans] = '\0';
391           nbtrans = maxsize-1;
392           return Standard_False;
393         }
394       }
395       else {
396         tostr[nbtrans] =  ((char) pl);
397         nbtrans++;
398       }
399       if (nbtrans >= (maxsize - 1)) {
400         tostr[maxsize-1] = '\0';
401         finished = Standard_True;
402         return Standard_False;
403       }
404     }
405   }
406   return Standard_True;
407 }
408           
409 Standard_Boolean Resource_Unicode::ConvertUnicodeToEUC(const TCollection_ExtendedString& fromstr,
410                                                        Standard_PCharacter& tostr,
411                                                        const Standard_Integer maxsize)
412 {
413   Standard_Integer nbtrans = 0;
414   Standard_Integer nbext = 1;
415   Standard_Boolean finished = Standard_False;
416   Standard_ExtCharacter curcar;
417   unsigned int pl,ph;
418   // BIG INDIAN USED HERE
419   
420   while (!finished) {
421     if (nbext > fromstr.Length()) {
422       finished = Standard_True;
423       tostr[nbtrans] = '\0';
424     }
425     else {
426       curcar = fromstr.Value(nbext);
427       nbext++;
428       ph = (((unsigned int) curcar) >> 8) & 0xFF;
429       pl = ((unsigned int) curcar) & 0xFF;
430       Resource_unicode_to_euc(&ph,&pl);
431       if (iseuc(ph)) {
432         if (nbtrans < (maxsize-3)) {
433           tostr[nbtrans] = ((char) ph);
434           nbtrans++;
435           tostr[nbtrans] =  ((char) pl);
436           nbtrans++;
437         }
438         else {
439           tostr[nbtrans-1] = '\0';
440           nbtrans = maxsize-1;
441           return Standard_False;
442         }
443       }
444       else {
445         tostr[nbtrans] =  ((char) pl);
446         nbtrans++;
447       }
448       if (nbtrans >= (maxsize - 1)) {
449         tostr[maxsize-1] = '\0';
450         finished = Standard_True;
451         return Standard_False;
452       }
453     }
454   }
455   return Standard_True;
456 }
457           
458 Standard_Boolean Resource_Unicode::ConvertUnicodeToGB(const TCollection_ExtendedString& fromstr,
459                                                       Standard_PCharacter& tostr,
460                                                       const Standard_Integer maxsize)
461 {
462   Standard_Integer nbtrans = 0;
463   Standard_Integer nbext = 1;
464   Standard_Boolean finished = Standard_False;
465   Standard_ExtCharacter curcar;
466   unsigned int pl,ph;
467   // BIG INDIAN USED HERE
468   
469   while (!finished) {
470     if (nbext > fromstr.Length()) {
471       finished = Standard_True;
472       tostr[nbtrans] = '\0';
473     }
474     else {
475       curcar = fromstr.Value(nbext);
476       nbext++;
477       ph = (((unsigned int) curcar) >> 8) & 0xFF;
478       pl = ((unsigned int) curcar) & 0xFF;
479       Resource_unicode_to_gb(&ph,&pl);
480       if (isshift(ph)) {
481         if (nbtrans < (maxsize-3)) {
482           tostr[nbtrans] = ((char) ph);
483           nbtrans++;
484           tostr[nbtrans] =  ((char) pl);
485           nbtrans++;
486         }
487         else {
488           tostr[nbtrans-1] = '\0';
489           nbtrans = maxsize-1;
490           return Standard_False;
491         }
492       }
493       else {
494         tostr[nbtrans] =  ((char) curcar) & 0xFF;
495         nbtrans++;
496       }
497       if (nbtrans >= (maxsize - 1)) {
498         tostr[maxsize-1] = '\0';
499         finished = Standard_True;
500         return Standard_False;
501       }
502     }
503   }
504   return Standard_True;
505 }
506           
507 Standard_Boolean Resource_Unicode::ConvertUnicodeToANSI(const TCollection_ExtendedString& fromstr,
508                                                         Standard_PCharacter& tostr,
509                                                         const Standard_Integer maxsize)
510 {
511   Standard_Integer nbtrans = 0;
512   Standard_Integer nbext = 1;
513   Standard_Boolean finished = Standard_False;
514   Standard_ExtCharacter curcar;
515   unsigned int pl,ph;
516   // BIG INDIAN USED HERE
517   
518   while (!finished) {
519     if (nbext > fromstr.Length()) {
520       finished = Standard_True;
521       tostr[nbtrans] = '\0';
522     }
523     else {
524       curcar = fromstr.Value(nbext);
525       nbext++;
526       ph = ((unsigned int) curcar) >> 8;
527       pl = ((unsigned int) curcar) & 0xFF;
528       if (ph == 0) {
529         tostr[nbtrans] =  ((char) pl);
530       }
531       else {
532         tostr[nbtrans] =  ' ';
533       }
534       nbtrans++;
535     }
536     if (nbtrans >= (maxsize - 1)) {
537       tostr[maxsize-1] = '\0';
538       finished = Standard_True;
539       return Standard_False;
540     }
541   }
542   return Standard_True;
543 }
544
545 static Standard_Boolean AlreadyRead = Standard_False;
546           
547 static Resource_FormatType& Resource_Current_Format()
548 {
549   static Resource_FormatType theformat = Resource_ANSI;
550   if (!AlreadyRead) {
551     AlreadyRead = Standard_True ;
552     Handle(Resource_Manager) mgr = new Resource_Manager("CharSet");
553     if (mgr->Find("FormatType")) {
554       TCollection_AsciiString form = mgr->Value("FormatType");
555       if (form.IsEqual("SJIS")) {
556         theformat = Resource_SJIS;
557       }
558       else if (form.IsEqual("EUC")) {
559         theformat = Resource_EUC;
560       }
561       else if (form.IsEqual("GB")) {
562         theformat = Resource_GB;
563       }
564       else {
565         theformat = Resource_ANSI;
566       }
567     }
568     else {
569       theformat = Resource_ANSI;
570     }
571   }
572   return theformat;
573 }
574
575 void Resource_Unicode::SetFormat(const Resource_FormatType typecode)
576 {
577   AlreadyRead = Standard_True;
578   Resource_Current_Format() = typecode;
579 }
580
581 Resource_FormatType Resource_Unicode::GetFormat()
582 {
583   return Resource_Current_Format();
584 }
585
586
587 void  Resource_Unicode::ReadFormat()
588 {
589   AlreadyRead = Standard_False;
590   Resource_Unicode::GetFormat();
591 }
592
593 void Resource_Unicode::ConvertFormatToUnicode (const Resource_FormatType theFormat,
594                                                const Standard_CString theFromStr,
595                                                TCollection_ExtendedString& theToStr)
596 {
597   switch (theFormat)
598   {
599     case Resource_FormatType_SJIS:
600     {
601       ConvertSJISToUnicode (theFromStr, theToStr);
602       break;
603     }
604     case Resource_FormatType_EUC:
605     {
606       ConvertEUCToUnicode(theFromStr, theToStr);
607       break;
608     }
609     case Resource_FormatType_GB:
610     {
611       ConvertGBToUnicode(theFromStr, theToStr);
612       break;
613     }
614     case Resource_FormatType_ANSI:
615     {
616       theToStr = TCollection_ExtendedString(theFromStr, Standard_False);
617       break;
618     }
619     case Resource_FormatType_CP1250:
620     case Resource_FormatType_CP1251:
621     case Resource_FormatType_CP1252:
622     case Resource_FormatType_CP1253:
623     case Resource_FormatType_CP1254:
624     case Resource_FormatType_CP1255:
625     case Resource_FormatType_CP1256:
626     case Resource_FormatType_CP1257:
627     case Resource_FormatType_CP1258:
628     case Resource_FormatType_iso8859_1:
629     case Resource_FormatType_iso8859_2:
630     case Resource_FormatType_iso8859_3:
631     case Resource_FormatType_iso8859_4:
632     case Resource_FormatType_iso8859_5:
633     case Resource_FormatType_iso8859_6:
634     case Resource_FormatType_iso8859_7:
635     case Resource_FormatType_iso8859_8:
636     case Resource_FormatType_iso8859_9:
637     {
638       const int aCodePageIndex = (int)theFormat - (int)Resource_FormatType_CP1250;
639       const Standard_ExtString aCodePage = THE_CODEPAGES_ANSI[aCodePageIndex];
640       theToStr.Clear();
641       for (const char* anInputPntr = theFromStr; *anInputPntr != '\0'; ++anInputPntr)
642       {
643         unsigned char anInputChar = (unsigned char)(*anInputPntr);
644         Standard_ExtCharacter aRes = (anInputChar & 0x80) != 0
645           ? aCodePage[(0x7f & anInputChar)]
646           : anInputChar;
647         if (aRes == 0)
648         {
649           aRes = '?';
650         }
651         theToStr.AssignCat(aRes);
652       }
653       break;
654     }
655     case Resource_FormatType_Big5:
656     {
657       ConvertBig5ToUnicode(theFromStr, theToStr);
658       break;
659     }
660     case Resource_FormatType_GBK:
661     {
662       ConvertGBKToUnicode(theFromStr, theToStr);
663       break;
664     }
665     case Resource_FormatType_UTF8:
666     {
667       theToStr = TCollection_ExtendedString (theFromStr, Standard_True);
668       break;
669     }
670     case Resource_FormatType_SystemLocale:
671     {
672       NCollection_Utf16String aString;
673       aString.FromLocale (theFromStr);
674       theToStr = TCollection_ExtendedString (aString.ToCString());
675       break;
676     }
677   }
678 }
679
680 Standard_Boolean Resource_Unicode::ConvertUnicodeToFormat(const Resource_FormatType theFormat,
681                                                           const TCollection_ExtendedString& theFromStr,
682                                                           Standard_PCharacter& theToStr,
683                                                           const Standard_Integer theMaxSize)
684 {
685   switch (theFormat)
686   {
687     case Resource_FormatType_SJIS:
688     {
689       return ConvertUnicodeToSJIS (theFromStr, theToStr, theMaxSize);
690     }
691     case Resource_FormatType_EUC:
692     {
693       return ConvertUnicodeToEUC (theFromStr, theToStr, theMaxSize);
694     }
695     case Resource_FormatType_GB:
696     {
697       return ConvertUnicodeToGB (theFromStr, theToStr, theMaxSize);
698     }
699     case Resource_FormatType_ANSI:
700     {
701       return ConvertUnicodeToANSI(theFromStr, theToStr, theMaxSize);
702     }
703     case Resource_FormatType_CP1250:
704     case Resource_FormatType_CP1251:
705     case Resource_FormatType_CP1252:
706     case Resource_FormatType_CP1253:
707     case Resource_FormatType_CP1254:
708     case Resource_FormatType_CP1255:
709     case Resource_FormatType_CP1256:
710     case Resource_FormatType_CP1257:
711     case Resource_FormatType_CP1258:
712     case Resource_FormatType_iso8859_1:
713     case Resource_FormatType_iso8859_2:
714     case Resource_FormatType_iso8859_3:
715     case Resource_FormatType_iso8859_4:
716     case Resource_FormatType_iso8859_5:
717     case Resource_FormatType_iso8859_6:
718     case Resource_FormatType_iso8859_7:
719     case Resource_FormatType_iso8859_8:
720     case Resource_FormatType_iso8859_9:
721     {
722       if (theMaxSize < theFromStr.Length())
723       {
724         return Standard_False;
725       }
726       const int aCodePageIndex = (int)theFormat - (int)Resource_FormatType_CP1250;
727       const Standard_ExtString aCodePage = THE_CODEPAGES_ANSI[aCodePageIndex];
728       for (Standard_Integer aToCharInd = 0; aToCharInd < theMaxSize - 1; ++aToCharInd)
729       {
730         Standard_Boolean isFind = Standard_False;
731         Standard_ExtCharacter aFromChar = theFromStr.Value(aToCharInd + 1);
732         if (aFromChar == 0)
733         {
734           // zero value should be handled explicitly to avoid false conversion by
735           // selected code page that may have unused values (encoded as zero)
736           theToStr[aToCharInd] = '\0';
737         }
738         else
739         {
740           // find the character in the code page
741           for (unsigned char anIndCP = 0; aFromChar != 0 && anIndCP < 128; ++anIndCP)
742           {
743             if (aCodePage[anIndCP] == aFromChar)
744             {
745               theToStr[aToCharInd] = anIndCP | 0x80;
746               isFind = Standard_True;
747             }
748           }
749           // if character is not found, put '?'
750           if (!isFind)
751           {
752             theToStr[aToCharInd] = '?';
753           }
754         }
755       }
756       theToStr[theMaxSize - 1] = '\0';
757       return Standard_True;
758     }
759     case Resource_FormatType_UTF8:
760     {
761       if (theMaxSize < theFromStr.LengthOfCString())
762       {
763         return Standard_False;
764       }
765       theFromStr.ToUTF8CString (theToStr);
766       return Standard_True;
767     }
768     case Resource_FormatType_SystemLocale:
769     {
770       const NCollection_Utf16String aString (theFromStr.ToExtString());
771       return aString.ToLocale (theToStr, theMaxSize);
772     }
773     case Resource_FormatType_GBK:
774     case Resource_FormatType_Big5:
775     {
776       throw Standard_NotImplemented("Resource_Unicode::ConvertUnicodeToFormat - convert from GBK and Big5 to Unocode is not implemented");
777     }
778   }
779   return Standard_False;
780 }