1 /* Copyright (c) MediaArea.net SARL. All Rights Reserved.
2 *
3 * Use of this source code is governed by a zlib-style license that can
4 * be found in the License.txt file in the root of the source tree.
5 */
6
7 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 //
9 // More methods for std::(w)string
10 //
11 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12
13 //---------------------------------------------------------------------------
14 #include "ZenLib/PreComp.h"
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18 //---------------------------------------------------------------------------
19
20 //---------------------------------------------------------------------------
21 #include "ZenLib/Conf_Internal.h"
22 //---------------------------------------------------------------------------
23
24 //---------------------------------------------------------------------------
25 #ifdef ZENLIB_USEWX
26 #include <wx/strconv.h>
27 #include <wx/datetime.h>
28 #else //ZENLIB_USEWX
29 #ifdef ZENLIB_STANDARD
30 #undef WINDOWS
31 #endif
32 #ifdef WINDOWS
33 #undef __TEXT
34 #include <windows.h>
35 #include <tchar.h>
36 #endif
37 #endif //ZENLIB_USEWX
38 #ifdef __MINGW32__
39 #include <windows.h>
40 #endif //__MINGW32__
41 #include <algorithm>
42 #include <iomanip>
43 #include <cmath>
44 #include <ctime>
45 #include "ZenLib/OS_Utils.h"
46 #include "ZenLib/File.h"
47 using namespace std;
48 //---------------------------------------------------------------------------
49
50 namespace ZenLib
51 {
52
53 int16u Ztring_ISO_8859_2[96]=
54 {
55 0x00A0,
56 0x0104,
57 0x02D8,
58 0x0141,
59 0x00A4,
60 0x013D,
61 0x015A,
62 0x00A7,
63 0x00A8,
64 0x0160,
65 0x015E,
66 0x0164,
67 0x0179,
68 0x00AD,
69 0x017D,
70 0x017B,
71 0x00B0,
72 0x0105,
73 0x02DB,
74 0x0142,
75 0x00B4,
76 0x013E,
77 0x015B,
78 0x02C7,
79 0x00B8,
80 0x0161,
81 0x015F,
82 0x0165,
83 0x017A,
84 0x02DD,
85 0x017E,
86 0x017C,
87 0x0154,
88 0x00C1,
89 0x00C2,
90 0x0102,
91 0x00C4,
92 0x0139,
93 0x0106,
94 0x00C7,
95 0x010C,
96 0x00C9,
97 0x0118,
98 0x00CB,
99 0x011A,
100 0x00CD,
101 0x00CE,
102 0x010E,
103 0x0110,
104 0x0143,
105 0x0147,
106 0x00D3,
107 0x00D4,
108 0x0150,
109 0x00D6,
110 0x00D7,
111 0x0158,
112 0x016E,
113 0x00DA,
114 0x0170,
115 0x00DC,
116 0x00DD,
117 0x0162,
118 0x00DF,
119 0x0155,
120 0x00E1,
121 0x00E2,
122 0x0103,
123 0x00E4,
124 0x013A,
125 0x0107,
126 0x00E7,
127 0x010D,
128 0x00E9,
129 0x0119,
130 0x00EB,
131 0x011B,
132 0x00ED,
133 0x00EE,
134 0x010F,
135 0x0111,
136 0x0144,
137 0x0148,
138 0x00F3,
139 0x00F4,
140 0x0151,
141 0x00F6,
142 0x00F7,
143 0x0159,
144 0x016F,
145 0x00FA,
146 0x0171,
147 0x00FC,
148 0x00FD,
149 0x0163,
150 0x02D9,
151 };
152
153 //---------------------------------------------------------------------------
154 Ztring EmptyZtring;
155 //---------------------------------------------------------------------------
156
157 //---------------------------------------------------------------------------
158 #if defined(STREAM_MISSING)
159 #if defined (_UNICODE)
160 #if defined (MACOS) || defined (MACOSX)
161 #define _tnprintf swprintf
162 #else
163 #define _tnprintf snwprintf
164 #endif
165 #else
166 #define _tnprintf snprintf
167 #endif
168 #else
169 typedef basic_stringstream<Char> tStringStream;
170 typedef basic_istringstream<Char> tiStringStream;
171 typedef basic_ostringstream<Char> toStringStream;
172 #endif
173 //---------------------------------------------------------------------------
174
175 //***************************************************************************
176 // Operators
177 //***************************************************************************
178
operator ()(size_type Pos)179 Char &Ztring::operator() (size_type Pos)
180 {
181 if (Pos>size())
182 resize(Pos);
183 return operator[] (Pos);
184 }
185
186 //***************************************************************************
187 // Assign
188 //***************************************************************************
189
Assign_FromFile(const Ztring & FileName)190 bool Ztring::Assign_FromFile (const Ztring &FileName)
191 {
192 File F;
193 if (!F.Open(FileName))
194 return false;
195 int64u F_Size=F.Size_Get();
196 if (F_Size>((size_t)-1)-1)
197 return false;
198
199 //Creating buffer
200 int8u* Buffer=new int8u[(size_t)F_Size+1];
201 size_t Buffer_Offset=0;
202
203 //Reading the file
204 while(Buffer_Offset<F_Size)
205 {
206 size_t BytesRead=F.Read(Buffer+Buffer_Offset, (size_t)F_Size-Buffer_Offset);
207 if (BytesRead==0)
208 break; //Read is finished
209 Buffer_Offset+=BytesRead;
210 }
211 if (Buffer_Offset<F_Size)
212 {
213 delete[] Buffer;
214 return false;
215 }
216 Buffer[Buffer_Offset]='\0';
217
218 //Filling
219 assign((const Char*)Buffer);
220 delete[] Buffer;
221
222 return true;
223 }
224
225 //***************************************************************************
226 // Conversions
227 //***************************************************************************
228
From_Unicode(const wchar_t S)229 Ztring& Ztring::From_Unicode (const wchar_t S)
230 {
231 #ifdef _UNICODE
232 append(1, S);
233 #else
234 From_Unicode(&S, 1);
235 #endif
236 return *this;
237 }
238
From_Unicode(const wchar_t * S)239 Ztring& Ztring::From_Unicode (const wchar_t* S)
240 {
241 if (S==NULL)
242 return *this;
243
244 #ifdef _UNICODE
245 assign(S);
246 #else
247 #ifdef ZENLIB_USEWX
248 size_type OK=wxConvCurrent->WC2MB(NULL, S, 0);
249 if (OK!=0 && OK!=Error)
250 assign(wxConvCurrent->cWC2MB(S));
251 #else //ZENLIB_USEWX
252 #ifdef WINDOWS
253 int Size=WideCharToMultiByte(CP_UTF8, 0, S, -1, NULL, 0, NULL, NULL);
254 if (Size!=0)
255 {
256 char* AnsiString=new char[Size+1];
257 WideCharToMultiByte(CP_UTF8, 0, S, -1, AnsiString, Size, NULL, NULL);
258 AnsiString[Size]='\0';
259 assign (AnsiString);
260 delete[] AnsiString;
261 }
262 else
263 clear();
264 #else //WINDOWS
265 size_t Size=wcstombs(NULL, S, 0);
266 if (Size!=0 && Size!=(size_t)-1)
267 {
268 char* AnsiString=new char[Size+1];
269 Size=wcstombs(AnsiString, S, wcslen(S));
270 AnsiString[Size]='\0';
271 assign (AnsiString);
272 delete[] AnsiString;
273 }
274 else
275 clear();
276 #endif
277 #endif //ZENLIB_USEWX
278 #endif
279 return *this;
280 }
281
From_Unicode(const wchar_t * S,size_type Start,size_type Length)282 Ztring& Ztring::From_Unicode (const wchar_t *S, size_type Start, size_type Length)
283 {
284 if (S==NULL)
285 return *this;
286
287 if (Length==Error)
288 Length=wcslen(S+Start);
289 wchar_t* Temp=new wchar_t[Length+1];
290 wcsncpy (Temp, S+Start, Length);
291 Temp[Length]=__T('\0');
292
293 From_Unicode(Temp);
294 delete[] Temp; //Temp=NULL;
295 return *this;
296 }
297
From_UTF8(const char * S)298 Ztring& Ztring::From_UTF8 (const char* S)
299 {
300 if (S==NULL)
301 return *this;
302
303 #ifdef ZENLIB_USEWX
304 size_type OK=wxConvUTF8.MB2WC(NULL, S, 0);
305 if (OK!=0 && OK!=Error)
306 #ifdef _UNICODE
307 assign(wxConvUTF8.cMB2WC(S).data());
308 #else
309 assign(wxConvCurrent->cWC2MB(wxConvUTF8.cMB2WC(S)));
310 #endif
311 #else //ZENLIB_USEWX
312 #ifdef _UNICODE
313 // Don't use MultiByteToWideChar(), some characters are not well decoded
314 clear();
315 const int8u* Z=(const int8u*)S;
316 while (*Z) //0 is end
317 {
318 //1 byte
319 if (*Z<0x80)
320 {
321 operator += ((wchar_t)(*Z));
322 Z++;
323 }
324 //2 bytes
325 else if ((*Z&0xE0)==0xC0)
326 {
327 if ((*(Z+1)&0xC0)==0x80)
328 {
329 operator += ((((wchar_t)(*Z&0x1F))<<6)|(*(Z+1)&0x3F));
330 Z+=2;
331 }
332 else
333 {
334 clear();
335 return *this; //Bad character
336 }
337 }
338 //3 bytes
339 else if ((*Z&0xF0)==0xE0)
340 {
341 if ((*(Z+1)&0xC0)==0x80 && (*(Z+2)&0xC0)==0x80)
342 {
343 operator += ((((wchar_t)(*Z&0x0F))<<12)|((*(Z+1)&0x3F)<<6)|(*(Z+2)&0x3F));
344 Z+=3;
345 }
346 else
347 {
348 clear();
349 return *this; //Bad character
350 }
351 }
352 //4 bytes
353 else if ((*Z&0xF8)==0xF0)
354 {
355 if ((*(Z+1)&0xC0)==0x80 && (*(Z+2)&0xC0)==0x80 && (*(Z+3)&0xC0)==0x80)
356 {
357 #if defined(_MSC_VER)
358 #pragma warning(push)
359 #pragma warning(disable:4127)
360 #endif //defined(_MSC_VER)
361 if (sizeof(wchar_t) == 2)
362 #if defined(_MSC_VER)
363 #pragma warning(pop)
364 #endif //defined(_MSC_VER)
365 {
366 int32u Value = ((((int32u)(*Z&0x0F))<<18)|((*(Z+1)&0x3F)<<12)|((*(Z+2)&0x3F)<<6)|(*(Z+3)&0x3F));
367 operator += (0xD800|((Value>>10)-0x40));
368 operator += (0xDC00| (Value&0x3FF));
369 }
370 else
371 operator += ((((wchar_t)(*Z&0x0F))<<18)|((*(Z+1)&0x3F)<<12)|((*(Z+2)&0x3F)<<6)|(*(Z+3)&0x3F));
372 Z+=4;
373 }
374 else
375 {
376 clear();
377 return *this; //Bad character
378 }
379 }
380 else
381 {
382 clear();
383 return *this; //Bad character
384 }
385 }
386 #else
387 assign(S); //Not implemented
388 #endif
389 #endif //ZENLIB_USEWX
390 return *this;
391 }
392
From_UTF8(const char * S,size_type Start,size_type Length)393 Ztring& Ztring::From_UTF8 (const char* S, size_type Start, size_type Length)
394 {
395 if (S==NULL)
396 return *this;
397
398 if (Length==Error)
399 Length=strlen(S+Start);
400 char* Temp=new char[Length+1];
401 strncpy (Temp, S+Start, Length);
402 Temp[Length]='\0';
403
404 From_UTF8(Temp);
405 delete[] Temp; //Temp=NULL;
406 return *this;
407 }
408
From_UTF16(const char * S)409 Ztring& Ztring::From_UTF16 (const char* S)
410 {
411 if (S==NULL)
412 return *this;
413
414 if ((unsigned char)S[0]==(unsigned char)0xFF && (unsigned char)S[1]==(unsigned char)0xFE)
415 return From_UTF16LE(S+2);
416 else if ((unsigned char)S[0]==(unsigned char)0xFE && (unsigned char)S[1]==(unsigned char)0xFF)
417 return From_UTF16BE(S+2);
418 else if ((unsigned char)S[0]==(unsigned char)0x00 && (unsigned char)S[1]==(unsigned char)0x00)
419 {
420 clear(); //No begin!
421 return *this;
422 }
423 else
424 return From_UTF16LE(S); //Not sure, default
425 }
426
From_UTF16(const char * S,size_type Start,size_type Length)427 Ztring& Ztring::From_UTF16 (const char* S, size_type Start, size_type Length)
428 {
429 if (S==NULL)
430 return *this;
431
432 if (Length<2)
433 return *this;
434
435 if ((unsigned char)S[0]==(unsigned char)0xFF && (unsigned char)S[1]==(unsigned char)0xFE)
436 return From_UTF16LE(S+2, Start, Length-2);
437 else if ((unsigned char)S[0]==(unsigned char)0xFE && (unsigned char)S[1]==(unsigned char)0xFF)
438 return From_UTF16BE(S+2, Start, Length-2);
439 else if ((unsigned char)S[0]==(unsigned char)0x00 && (unsigned char)S[1]==(unsigned char)0x00)
440 {
441 clear(); //No begin!
442 return *this;
443 }
444 else
445 return From_UTF16LE(S, Start, Length); //Not sure, default
446 }
447
From_UTF16BE(const char * S)448 Ztring& Ztring::From_UTF16BE (const char* S)
449 {
450 if (S==NULL)
451 return *this;
452
453 #ifdef ZENLIB_USEWX
454 //clear(); return *this;
455 wxMBConvUTF16BE wxConvUTF16BE;
456 size_type OK=wxConvUTF16BE.MB2WC(NULL, S, 0);
457 if (OK!=0 && OK!=Error)
458 #ifdef _UNICODE
459 assign(wxConvUTF16BE.cMB2WC(S).data());
460 #else
461 assign(wxConvCurrent->cWC2MB(wxConvUTF16BE.cMB2WC(S)));
462 #endif
463 #else //ZENLIB_USEWX
464 #ifdef WINDOWS
465 clear();
466 const wchar_t* SW=(const wchar_t*)S;
467 size_t Pos=0;
468 while (SW[Pos]!=__T('\0'))
469 {
470 Char Temp=(Char)(((SW[Pos]&0xFF00)>>8)+((SW[Pos]&0x00FF)<<8));
471 append(1, Temp);
472 Pos++;
473 }
474 #else //WINDOWS
475 clear();
476 while (S[0]!=0 || S[1]!=0)
477 {
478 append(1, (Char)BigEndian2int16u(S));
479 S+=2;
480 }
481 #endif
482 #endif //ZENLIB_USEWX
483 return *this;
484 }
485
From_UTF16BE(const char * S,size_type Start,size_type Length)486 Ztring& Ztring::From_UTF16BE (const char* S, size_type Start, size_type Length)
487 {
488 if (S==NULL)
489 return *this;
490
491 if (Length==Error)
492 {
493 Length=0;
494 while(S[Length]!=0x0000)
495 Length++;
496 }
497 else
498 Length&=(size_t)-2; //odd number
499
500 char* Temp=new char[Length+2];
501 memcpy (Temp, S+Start, Length);
502 Temp[Length+0]=0x00;
503 Temp[Length+1]=0x00;
504 reserve(Length);
505 From_UTF16BE(Temp);
506 delete[] Temp; //Temp=NULL;
507 return *this;
508 }
509
From_UTF16LE(const char * S)510 Ztring& Ztring::From_UTF16LE (const char* S)
511 {
512 if (S==NULL)
513 return *this;
514
515 #ifdef ZENLIB_USEWX
516 //clear(); return *this;
517 wxMBConvUTF16LE wxConvUTF16LE;
518 size_type OK=wxConvUTF16LE.MB2WC(NULL, S, 0);
519 if (OK!=0 && OK!=Error)
520 #ifdef _UNICODE
521 assign(wxConvUTF16LE.cMB2WC(S).data());
522 #else
523 assign(wxConvCurrent->cWC2MB(wxConvUTF16LE.cMB2WC(S)));
524 #endif
525 #else //ZENLIB_USEWX
526 #ifdef WINDOWS
527 #ifdef UNICODE
528 const wchar_t* SW=(const wchar_t*)S;
529 assign(SW);
530 #else
531 clear(); //Not implemented
532 #endif
533 #else //WINDOWS
534 clear();
535 while (S[0]!=0 || S[1]!=0)
536 {
537 append(1, (Char)LittleEndian2int16u(S));
538 S+=2;
539 }
540 #endif
541 #endif //ZENLIB_USEWX
542 return *this;
543 }
544
From_UTF16LE(const char * S,size_type Start,size_type Length)545 Ztring& Ztring::From_UTF16LE (const char* S, size_type Start, size_type Length)
546 {
547 if (S==NULL)
548 return *this;
549
550 if (Length==Error)
551 {
552 Length=0;
553 while(S[Length]!=0x0000)
554 Length+=2;
555 }
556 else
557 Length&=(size_t)-2; //odd number
558
559 char* Temp=new char[Length+2];
560 memcpy (Temp, S+Start, Length);
561 Temp[Length+0]=0x00;
562 Temp[Length+1]=0x00;
563 From_UTF16LE(Temp);
564 delete[] Temp; //Temp=NULL;
565 return *this;
566 }
567
From_Local(const char * S)568 Ztring& Ztring::From_Local (const char* S)
569 {
570 if (S==NULL)
571 return *this;
572
573 #ifdef _UNICODE
574 #ifdef ZENLIB_USEWX
575 size_type OK=wxConvCurrent->MB2WC(NULL, S, 0);
576 if (OK!=0 && OK!=Error)
577 assign(wxConvCurrent->cMB2WC(S).data());
578 #else //ZENLIB_USEWX
579 #ifdef WINDOWS
580 int Size=MultiByteToWideChar(CP_ACP, 0, S, -1, NULL, 0);
581 if (Size!=0)
582 {
583 wchar_t* WideString=new wchar_t[Size+1];
584 MultiByteToWideChar(CP_ACP, 0, S, -1, WideString, Size);
585 WideString[Size]=L'\0';
586 assign (WideString);
587 delete[] WideString; //WideString=NULL;
588 }
589 else
590 clear();
591 #else //WINDOWS
592 size_t Size=mbsrtowcs(NULL, &S, 0, NULL);
593 if (Size!=0 && Size!=(size_t)-1)
594 {
595 wchar_t* WideString=new wchar_t[Size+1];
596 Size=mbsrtowcs(WideString, &S, Size, NULL);
597 WideString[Size]=L'\0';
598 assign (WideString);
599 delete[] WideString; //WideString=NULL;
600 }
601 else
602 clear();
603 #endif
604 #endif //ZENLIB_USEWX
605 #else
606 assign(S);
607 #endif
608 return *this;
609 }
610
From_Local(const char * S,size_type Start,size_type Length)611 Ztring& Ztring::From_Local (const char* S, size_type Start, size_type Length)
612 {
613 if (S==NULL)
614 return *this;
615
616 if (Length==Error)
617 Length=strlen(S+Start);
618 #ifdef _UNICODE
619 char* Temp=new char[Length+1];
620 strncpy (Temp, S+Start, Length);
621 Temp[Length]='\0';
622 From_Local(Temp);
623 delete[] Temp; //Temp=NULL;
624 #else
625 assign(S+Start, Length);
626 if (find(__T('\0'))!=std::string::npos)
627 resize(find(__T('\0')));
628 #endif
629 return *this;
630 }
631
From_ISO_8859_1(const char * S)632 Ztring& Ztring::From_ISO_8859_1(const char* S)
633 {
634 size_t Length = strlen(S);
635 wchar_t* Temp = new wchar_t[Length +1];
636
637 for (size_t Pos=0; Pos<Length+1; Pos++)
638 Temp[Pos]=(wchar_t)((int8u)S[Pos]);
639
640 From_Unicode(Temp);
641 delete[] Temp;
642 return *this;
643 }
644
From_ISO_8859_1(const char * S,size_type Start,size_type Length)645 Ztring& Ztring::From_ISO_8859_1(const char* S, size_type Start, size_type Length)
646 {
647 if (S==NULL)
648 return *this;
649
650 if (Length==Error)
651 Length=strlen(S+Start);
652 #ifdef _UNICODE
653 char* Temp = new char[Length+1];
654 strncpy(Temp, S +Start, Length);
655 Temp[Length] = '\0';
656 From_ISO_8859_1(Temp);
657 delete[] Temp;
658 #else
659 assign(S +Start, Length);
660 if (find(__T('\0')) != std::string::npos)
661 resize(find(__T('\0')));
662 #endif
663 return *this;
664 }
665
From_ISO_8859_2(const char * S)666 Ztring& Ztring::From_ISO_8859_2(const char* S)
667 {
668 size_t Length = strlen(S);
669 wchar_t* Temp = new wchar_t[Length +1];
670
671 for (size_t Pos=0; Pos<Length+1; Pos++)
672 {
673 if ((int8u)S[Pos]>=0xA0)
674 Temp[Pos]=(wchar_t)Ztring_ISO_8859_2[((int8u)S[Pos])-0xA0];
675 else
676 Temp[Pos]=(wchar_t)((int8u)S[Pos]);
677 }
678
679 From_Unicode(Temp);
680 delete[] Temp;
681 return *this;
682 }
683
From_ISO_8859_2(const char * S,size_type Start,size_type Length)684 Ztring& Ztring::From_ISO_8859_2(const char* S, size_type Start, size_type Length)
685 {
686 if (S==NULL)
687 return *this;
688
689 if (Length==Error)
690 Length=strlen(S+Start);
691 #ifdef _UNICODE
692 char* Temp = new char[Length+1];
693 strncpy(Temp, S +Start, Length);
694 Temp[Length] = '\0';
695 From_ISO_8859_2(Temp);
696 delete[] Temp;
697 #else
698 assign(S +Start, Length);
699 if (find(__T('\0')) != std::string::npos)
700 resize(find(__T('\0')));
701 #endif
702 return *this;
703 }
704
From_GUID(const int128u S)705 Ztring& Ztring::From_GUID (const int128u S)
706 {
707 Ztring S1;
708 S1.From_CC1((int8u) ((S.hi&0x000000FF00000000LL)>>32)); append(S1);
709 S1.From_CC1((int8u) ((S.hi&0x0000FF0000000000LL)>>40)); append(S1);
710 S1.From_CC1((int8u) ((S.hi&0x00FF000000000000LL)>>48)); append(S1);
711 S1.From_CC1((int8u) ((S.hi&0xFF00000000000000LL)>>56)); append(S1); append(__T("-"));
712 S1.From_CC1((int8u) ((S.hi&0x0000000000FF0000LL)>>16)); append(S1);
713 S1.From_CC1((int8u) ((S.hi&0x00000000FF000000LL)>>24)); append(S1); append(__T("-"));
714 S1.From_CC1((int8u) ( S.hi&0x00000000000000FFLL )); append(S1);
715 S1.From_CC1((int8u) ((S.hi&0x000000000000FF00LL)>> 8)); append(S1); append(__T("-"));
716 S1.From_CC2((int16u)((S.lo&0xFFFF000000000000LL)>>48)); append(S1); append(__T("-"));
717 S1.From_CC2((int16u)((S.lo&0x0000FFFF00000000LL)>>32)); append(S1);
718 S1.From_CC2((int16u)((S.lo&0x00000000FFFF0000LL)>>16)); append(S1);
719 S1.From_CC2((int16u)( S.lo&0x000000000000FFFFLL )); append(S1);
720
721 return *this;
722 }
723
From_UUID(const int128u S)724 Ztring& Ztring::From_UUID (const int128u S)
725 {
726 Ztring S1;
727 S1.From_CC2((int16u)((S.hi&0xFFFF000000000000LL)>>48)); assign(S1);
728 S1.From_CC2((int16u)((S.hi&0x0000FFFF00000000LL)>>32)); append(S1); append(__T("-"));
729 S1.From_CC2((int16u)((S.hi&0x00000000FFFF0000LL)>>16)); append(S1); append(__T("-"));
730 S1.From_CC2((int16u)( S.hi&0x000000000000FFFFLL )); append(S1); append(__T("-"));
731 S1.From_CC2((int16u)((S.lo&0xFFFF000000000000LL)>>48)); append(S1); append(__T("-"));
732 S1.From_CC2((int16u)((S.lo&0x0000FFFF00000000LL)>>32)); append(S1);
733 S1.From_CC2((int16u)((S.lo&0x00000000FFFF0000LL)>>16)); append(S1);
734 S1.From_CC2((int16u)( S.lo&0x000000000000FFFFLL )); append(S1);
735
736 return *this;
737 }
738
From_CC4(const int32u S)739 Ztring& Ztring::From_CC4 (const int32u S)
740 {
741 clear();
742 for (int8s i=(4-1)*8; i>=0; i-=8)
743 {
744 int32u Value=(S&(0xFF<<i))>>i;
745 if (Value<0x20)
746 {
747 if (!i || (i!=24 && !(S&(0xFFFFFFFF>>(32-i)))))
748 return *this; // Trailing 0 are fine
749
750 // Not valid, using 0x as fallback
751 clear();
752 append(__T("0x"));
753 append(Ztring().From_CC1((int8u)((S&0xFF000000)>>24)));
754 append(Ztring().From_CC1((int8u)((S&0x00FF0000)>>16)));
755 append(Ztring().From_CC1((int8u)((S&0x0000FF00)>> 8)));
756 append(Ztring().From_CC1((int8u)((S&0x000000FF) )));
757 return *this;
758 }
759 append(1, (Char)(Value));
760 }
761 return *this;
762 }
763
From_CC3(const int32u S)764 Ztring& Ztring::From_CC3 (const int32u S)
765 {
766 clear();
767 for (int8s i=(3-1)*8; i>=0; i-=8)
768 {
769 int32u Value=(S&(0xFF<<i))>>i;
770 if (Value<0x20)
771 {
772 if (!i || (i!=16 && !(S&(0xFFFFFF>>(24-i)))))
773 return *this; // Trailing 0 are fine
774
775 // Not valid, using 0x as fallback
776 clear();
777 append(__T("0x"));
778 append(Ztring().From_CC1((int8u)((S&0x00FF0000)>>16)));
779 append(Ztring().From_CC1((int8u)((S&0x0000FF00)>> 8)));
780 append(Ztring().From_CC1((int8u)((S&0x000000FF) )));
781 return *this;
782 }
783 append(1, (Char)(Value));
784 }
785 return *this;
786 }
787
From_CC2(const int16u S)788 Ztring& Ztring::From_CC2 (const int16u S)
789 {
790 clear();
791 Ztring Pos1; Pos1.From_Number(S, 16);
792 resize(4-Pos1.size(), __T('0'));
793 append(Pos1);
794 MakeUpperCase();
795
796 return *this;
797 }
798
From_CC1(const int8u S)799 Ztring& Ztring::From_CC1 (const int8u S)
800 {
801 clear();
802 Ztring Pos1; Pos1.From_Number(S, 16);
803 resize(2-Pos1.size(), __T('0'));
804 append(Pos1);
805 MakeUpperCase();
806
807 return *this;
808 }
809
From_Number(const int8s I,int8u Radix)810 Ztring& Ztring::From_Number (const int8s I, int8u Radix)
811 {
812 #if defined(STREAM_MISSING)
813 if (Radix==0)
814 {
815 clear();
816 return *this;
817 }
818 Char* C1=new Char[33];
819 #ifdef __MINGW32__
820 _itot (I, C1, Radix);
821 #else
822 _tnprintf(C1, 32, Radix==10?__T("%d"):(Radix==16?__T("%x"):(Radix==8?__T("%o"):__T(""))), I);
823 #endif
824 assign (C1);
825 delete[] C1; //C1=NULL;
826 #else
827 toStringStream Stream;
828 #ifdef UNICODE
829 Stream << setbase(Radix) << I;
830 #else //UNICODE
831 Stream << setbase(Radix) << (size_t)I; //On linux (at least), (un)signed char is detected as a char
832 #endif //UNICODE
833 assign(Stream.str());
834 #endif
835 MakeUpperCase();
836 return *this;
837 }
838
From_Number(const int8u I,int8u Radix)839 Ztring& Ztring::From_Number (const int8u I, int8u Radix)
840 {
841 #if defined(STREAM_MISSING)
842 if (Radix==0)
843 {
844 clear();
845 return *this;
846 }
847 Char* C1=new Char[33];
848 #ifdef __MINGW32__
849 _ultot (I, C1, Radix);
850 #else
851 _tnprintf(C1, 32, Radix==10?__T("%d"):(Radix==16?__T("%x"):(Radix==8?__T("%o"):__T(""))), I);
852 #endif
853 assign (C1);
854 delete[] C1; //C1=NULL;
855 #else
856 if (Radix==2)
857 {
858 clear();
859 for (int8u Pos=0; Pos<8; Pos++)
860 {
861 if (I<(((int8u)1)<<Pos))
862 break;
863 insert(0, 1, (I&(((int8u)1)<<Pos))?__T('1'):__T('0'));
864 }
865 }
866 else
867 {
868 toStringStream Stream;
869 #ifdef UNICODE
870 Stream << setbase(Radix) << I;
871 #else //UNICODE
872 Stream << setbase(Radix) << (size_t)I; //On linux (at least), (un)signed char is detected as a char
873 #endif //UNICODE
874 assign(Stream.str());
875 }
876 #endif
877 MakeUpperCase();
878 return *this;
879 }
880
From_Number(const int16s I,int8u Radix)881 Ztring& Ztring::From_Number (const int16s I, int8u Radix)
882 {
883 #if defined(STREAM_MISSING)
884 if (Radix==0)
885 {
886 clear();
887 return *this;
888 }
889 Char* C1=new Char[33];
890 #ifdef __MINGW32__
891 _itot (I, C1, Radix);
892 #else
893 _tnprintf(C1, 32, Radix==10?__T("%d"):(Radix==16?__T("%x"):(Radix==8?__T("%o"):__T(""))), I);
894 #endif
895 assign (C1);
896 delete[] C1; //C1=NULL;
897 #else
898 toStringStream Stream;
899 Stream << setbase(Radix) << I;
900 assign(Stream.str());
901 #endif
902 MakeUpperCase();
903 return *this;
904 }
905
From_Number(const int16u I,int8u Radix)906 Ztring& Ztring::From_Number (const int16u I, int8u Radix)
907 {
908 #if defined(STREAM_MISSING)
909 if (Radix==0)
910 {
911 clear();
912 return *this;
913 }
914 Char* C1=new Char[33];
915 #ifdef __MINGW32__
916 _ultot (I, C1, Radix);
917 #else
918 _tnprintf(C1, 32, Radix==10?__T("%u"):(Radix==16?__T("%x"):(Radix==8?__T("%o"):__T(""))), I);
919 #endif
920 assign (C1);
921 delete[] C1; //C1=NULL;
922 #else
923 if (Radix==2)
924 {
925 clear();
926 for (int8u Pos=0; Pos<16; Pos++)
927 {
928 if (I<(((int16u)1)<<Pos))
929 break;
930 insert(0, 1, (I&(((int16u)1)<<Pos))?__T('1'):__T('0'));
931 }
932 }
933 else
934 {
935 toStringStream Stream;
936 Stream << setbase(Radix) << I;
937 assign(Stream.str());
938 }
939 #endif
940 MakeUpperCase();
941 return *this;
942 }
943
From_Number(const int32s I,int8u Radix)944 Ztring& Ztring::From_Number (const int32s I, int8u Radix)
945 {
946 #if defined(STREAM_MISSING)
947 if (Radix==0)
948 {
949 clear();
950 return *this;
951 }
952 Char* C1=new Char[33];
953 #ifdef __MINGW32__
954 _itot (I, C1, Radix);
955 #else
956 _tnprintf(C1, 32, Radix==10?__T("%ld"):(Radix==16?__T("%lx"):(Radix==8?__T("%lo"):__T(""))), I);
957 #endif
958 assign (C1);
959 delete[] C1; //C1=NULL;
960 #else
961 toStringStream Stream;
962 Stream << setbase(Radix) << I;
963 assign(Stream.str());
964 #endif
965 MakeUpperCase();
966 return *this;
967 }
968
From_Number(const int32u I,int8u Radix)969 Ztring& Ztring::From_Number (const int32u I, int8u Radix)
970 {
971 #if defined(STREAM_MISSING)
972 if (Radix==0)
973 {
974 clear();
975 return *this;
976 }
977 Char* C1=new Char[33];
978 #ifdef __MINGW32__
979 _ultot (I, C1, Radix);
980 #else
981 _tnprintf(C1, 32, Radix==10?__T("%lu"):(Radix==16?__T("%lx"):(Radix==8?__T("%lo"):__T(""))), I);
982 #endif
983 assign (C1);
984 delete[] C1; //C1=NULL;
985 #else
986 if (Radix==2)
987 {
988 clear();
989 for (int8u Pos=0; Pos<32; Pos++)
990 {
991 if (I<(((int32u)1)<<Pos))
992 break;
993 insert(0, 1, (I&(((int32u)1)<<Pos))?__T('1'):__T('0'));
994 }
995 }
996 else
997 {
998 toStringStream Stream;
999 Stream << setbase(Radix) << I;
1000 assign(Stream.str());
1001 }
1002 #endif
1003 MakeUpperCase();
1004 return *this;
1005 }
1006
From_Number(const int64s I,int8u Radix)1007 Ztring& Ztring::From_Number (const int64s I, int8u Radix)
1008 {
1009 #if defined(STREAM_MISSING)
1010 if (Radix==0)
1011 {
1012 clear();
1013 return *this;
1014 }
1015 Char* C1=new Char[65];
1016 #ifdef __MINGW32__
1017 _i64tot (I, C1, Radix);
1018 #else
1019 _tnprintf(C1, 64, Radix==10?__T("%lld"):(Radix==16?__T("%llx"):(Radix==8?__T("%llo"):__T(""))), I);
1020 #endif
1021 assign (C1);
1022 delete[] C1; //C1=NULL;
1023 #else
1024 toStringStream Stream;
1025 Stream << setbase(Radix) << I;
1026 assign(Stream.str());
1027 #endif
1028 MakeUpperCase();
1029 return *this;
1030 }
1031
From_Number(const int64u I,int8u Radix)1032 Ztring& Ztring::From_Number (const int64u I, int8u Radix)
1033 {
1034 #if defined(STREAM_MISSING)
1035 if (Radix==0)
1036 {
1037 clear();
1038 return *this;
1039 }
1040 Char* C1=new Char[65]; C1[0] = 0;
1041 #ifdef __MINGW32__
1042 _ui64tot (I, C1, Radix);
1043 #else
1044 _tnprintf(C1, 64, Radix==10?__T("%llu"):(Radix==16?__T("%llx"):(Radix==8?__T("%llo"):__T(""))), I);
1045 #endif
1046 assign (C1);
1047 delete[] C1; //C1=NULL;
1048 #else
1049 if (Radix==2)
1050 {
1051 clear();
1052 for (int8u Pos=0; Pos<32; Pos++)
1053 {
1054 if (I<(((int64u)1)<<Pos))
1055 break;
1056 insert(0, 1, (I&(((int64u)1)<<Pos))?__T('1'):__T('0'));
1057 }
1058 }
1059 else
1060 {
1061 toStringStream Stream;
1062 Stream << setbase(Radix) << I;
1063 assign(Stream.str());
1064 }
1065 #endif
1066 MakeUpperCase();
1067 return *this;
1068 }
1069
From_Number(const int128u I,int8u Radix)1070 Ztring& Ztring::From_Number (const int128u I, int8u Radix)
1071 {
1072 From_Local(I.toString(Radix));
1073
1074 return *this;
1075 }
1076
From_Number(const float32 F,int8u Precision,ztring_t Options)1077 Ztring& Ztring::From_Number (const float32 F, int8u Precision, ztring_t Options)
1078 {
1079 #if defined(STREAM_MISSING)
1080 Char C1[100];
1081 _tnprintf (C1, 99, (Ztring(__T("%."))+Ztring::ToZtring(Precision)+__T("f")).c_str(), F);
1082 assign(C1);
1083 #else
1084 toStringStream Stream;
1085 Stream << setprecision(Precision) << fixed << F;
1086 assign(Stream.str());
1087 #if defined(__BORLANDC__)
1088 FindAndReplace(__T(","), __T(".")); //Borland C++ Builder 2010+Windows Seven put a comma for istringstream, but does not support comma for ostringstream
1089 #endif
1090 #endif
1091
1092 if ((Options & Ztring_NoZero && size()>0) && find(__T('.'))!=string::npos)
1093 {
1094 while (size()>0 && ((*this)[size()-1]==__T('0')))
1095 resize(size()-1);
1096 if (size()>0 && (*this)[size()-1]==__T('.'))
1097 resize(size()-1);
1098 }
1099
1100 return *this;
1101 }
1102
From_Number(const float64 F,int8u Precision,ztring_t Options)1103 Ztring& Ztring::From_Number (const float64 F, int8u Precision, ztring_t Options)
1104 {
1105 #if defined(STREAM_MISSING)
1106 Char C1[100];
1107 _tnprintf (C1, 99, (Ztring(__T("%."))+Ztring::ToZtring(Precision)+__T("f")).c_str(), F);
1108 assign(C1);
1109 #else
1110 toStringStream Stream;
1111 Stream << setprecision(Precision) << fixed << F;
1112 assign(Stream.str());
1113 #if defined(__BORLANDC__)
1114 FindAndReplace(__T(","), __T(".")); //Borland C++ Builder 2010+Windows Seven put a comma for istringstream, but does not support comma for ostringstream
1115 #endif
1116 #endif
1117
1118 if ((Options & Ztring_NoZero && size()>0) && find(__T('.'))!=string::npos)
1119 {
1120 while (size()>0 && ((*this)[size()-1]==__T('0')))
1121 resize(size()-1);
1122 if (size()>0 && (*this)[size()-1]==__T('.'))
1123 resize(size()-1);
1124 }
1125
1126 return *this;
1127 }
1128
From_Number(const float80 F,int8u Precision,ztring_t Options)1129 Ztring& Ztring::From_Number (const float80 F, int8u Precision, ztring_t Options)
1130 {
1131 #if defined(STREAM_MISSING)
1132 Char C1[100];
1133 _tnprintf (C1, 99, (Ztring(__T("%."))+Ztring::ToZtring(Precision)+__T("f")).c_str(), F);
1134 assign(C1);
1135 #else
1136 toStringStream Stream;
1137 Stream << setprecision(Precision) << fixed << F;
1138 assign(Stream.str());
1139 #if defined(__BORLANDC__)
1140 FindAndReplace(__T(","), __T(".")); //Borland C++ Builder 2010+Windows Seven put a comma for istringstream, but does not support comma for ostringstream
1141 #endif
1142 #endif
1143
1144 if ((Options & Ztring_NoZero && size()>0) && find(__T('.'))!=string::npos)
1145 {
1146 while (size()>0 && ((*this)[size()-1]==__T('0')))
1147 resize(size()-1);
1148 if (size()>0 && (*this)[size()-1]==__T('.'))
1149 resize(size()-1);
1150 }
1151
1152 return *this;
1153 }
1154
1155 #ifdef SIZE_T_IS_LONG
From_Number(const size_t I,int8u Radix)1156 Ztring& Ztring::From_Number (const size_t I, int8u Radix)
1157 {
1158 #if defined(STREAM_MISSING)
1159 Char C1[100];
1160 _tnprintf(C1, 64, Radix==10?__T("%zu"):(Radix==16?__T("%zx"):(Radix==8?__T("%zo"):__T(""))), I);
1161 assign(C1);
1162 #else
1163 toStringStream Stream;
1164 Stream << setbase(Radix) << I;
1165 assign(Stream.str());
1166 #if defined(__BORLANDC__)
1167 FindAndReplace(__T(","), __T(".")); //Borland C++ Builder 2010+Windows Seven put a comma for istringstream, but does not support comma for ostringstream
1168 #endif
1169 #endif
1170 MakeUpperCase();
1171 return *this;
1172 }
1173 #endif //SIZE_T_IS_LONG
1174
From_BCD(const int8u I)1175 Ztring& Ztring::From_BCD (const int8u I)
1176 {
1177 #if defined(STREAM_MISSING)
1178 clear();
1179 append(1, __T('0')+I/0x10);
1180 append(1, __T('0')+I%0x10);
1181 #else
1182 toStringStream Stream;
1183 Stream << I/0x10;
1184 Stream << I%0x10;
1185 assign(Stream.str());
1186 #endif
1187 return *this;
1188 }
1189
1190 //---------------------------------------------------------------------------
Duration_From_Milliseconds(const int64s Value_)1191 Ztring& Ztring::Duration_From_Milliseconds (const int64s Value_)
1192 {
1193 int64s Value=Value_;
1194 bool Negative=false;
1195 if (Value<0)
1196 {
1197 Value=-Value;
1198 Negative=true;
1199 }
1200
1201 int64u HH=(int8u)(Value/1000/60/60);
1202 int64u MM=Value/1000/60 -((HH*60));
1203 int64u Stream=Value/1000 -((HH*60+MM)*60);
1204 int64u MS=Value -((HH*60+MM)*60+Stream)*1000;
1205 Ztring DateT;
1206 Ztring Date;
1207 DateT.From_Number(HH); if (DateT.size()<2){DateT=Ztring(__T("0"))+DateT;}
1208 Date+=DateT;
1209 Date+=__T(":");
1210 DateT.From_Number(MM); if (DateT.size()<2){DateT=Ztring(__T("0"))+DateT;}
1211 Date+=DateT;
1212 Date+=__T(":");
1213 DateT.From_Number(Stream); if (DateT.size()<2){DateT=Ztring(__T("0"))+DateT;}
1214 Date+=DateT;
1215 Date+=__T(".");
1216 DateT.From_Number(MS); if (DateT.size()<2){DateT=Ztring(__T("00"))+DateT;} else if (DateT.size()<3){DateT=Ztring(__T("0"))+DateT;}
1217 Date+=DateT;
1218 if (Negative)
1219 {
1220 assign(__T("-"));
1221 append(Date);
1222 }
1223 else
1224 assign (Date.c_str());
1225 return *this;
1226 }
1227
1228 //---------------------------------------------------------------------------
Duration_From_Milliseconds(const int64u Value)1229 Ztring& Ztring::Duration_From_Milliseconds (const int64u Value)
1230 {
1231 int64u HH=(int8u)(Value/1000/60/60);
1232 int64u MM=Value/1000/60 -((HH*60));
1233 int64u Stream=Value/1000 -((HH*60+MM)*60);
1234 int64u MS=Value -((HH*60+MM)*60+Stream)*1000;
1235 Ztring DateT;
1236 Ztring Date;
1237 DateT.From_Number(HH); if (DateT.size()<2){DateT=Ztring(__T("0"))+DateT;}
1238 Date+=DateT;
1239 Date+=__T(":");
1240 DateT.From_Number(MM); if (DateT.size()<2){DateT=Ztring(__T("0"))+DateT;}
1241 Date+=DateT;
1242 Date+=__T(":");
1243 DateT.From_Number(Stream); if (DateT.size()<2){DateT=Ztring(__T("0"))+DateT;}
1244 Date+=DateT;
1245 Date+=__T(".");
1246 DateT.From_Number(MS); if (DateT.size()<2){DateT=Ztring(__T("00"))+DateT;} else if (DateT.size()<3){DateT=Ztring(__T("0"))+DateT;}
1247 Date+=DateT;
1248 assign (Date.c_str());
1249 return *this;
1250 }
1251
Date_From_Milliseconds_1601(const int64u Value)1252 Ztring& Ztring::Date_From_Milliseconds_1601 (const int64u Value)
1253 {
1254 if (Value>=11644473600000LL) //Values <1970 are not supported
1255 {
1256 Date_From_Seconds_1970((int32u)((Value-11644473600000LL)/1000));
1257 append(__T("."));
1258 Ztring Milliseconds; Milliseconds.From_Number(Value%1000);
1259 while (Milliseconds.size()<3)
1260 Milliseconds+=__T('0');
1261 append(Milliseconds);
1262 }
1263 else
1264 clear(); //Not supported
1265
1266 return *this;
1267 }
1268
Date_From_Seconds_1601(const int64u Value)1269 Ztring& Ztring::Date_From_Seconds_1601 (const int64u Value)
1270 {
1271 return Date_From_Seconds_1970(((int64s)Value)-11644473600LL);
1272 }
1273
Date_From_Seconds_1900(const int32u Value)1274 Ztring& Ztring::Date_From_Seconds_1900 (const int32u Value)
1275 {
1276 if (Value>2208988800)
1277 return Date_From_Seconds_1970(((int64s)Value)-2208988800);
1278 else
1279 return Date_From_Seconds_1970(((int64s)Value)+0x100000000LL-2208988800); //Value is considering to loop e.g. NTP value
1280 }
1281
Date_From_Seconds_1900(const int64s Value)1282 Ztring& Ztring::Date_From_Seconds_1900 (const int64s Value)
1283 {
1284 return Date_From_Seconds_1970(Value-2208988800);
1285 }
1286
Date_From_Seconds_1904(const int32u Value)1287 Ztring& Ztring::Date_From_Seconds_1904 (const int32u Value)
1288 {
1289 return Date_From_Seconds_1970(((int64s)Value)-2082844800);
1290 }
1291
Date_From_Seconds_1904(const int64u Value)1292 Ztring& Ztring::Date_From_Seconds_1904 (const int64u Value)
1293 {
1294 return Date_From_Seconds_1970(((int64s)Value)-2082844800);
1295 }
1296
Date_From_Seconds_1904(const int64s Value)1297 Ztring& Ztring::Date_From_Seconds_1904 (const int64s Value)
1298 {
1299 return Date_From_Seconds_1970(Value-2082844800);
1300 }
1301
Date_From_Seconds_1970(const int32u Value)1302 Ztring& Ztring::Date_From_Seconds_1970 (const int32u Value)
1303 {
1304 return Date_From_Seconds_1970((int64s)Value);
1305 }
1306
Date_From_Seconds_1970(const int32s Value)1307 Ztring& Ztring::Date_From_Seconds_1970 (const int32s Value)
1308 {
1309 return Date_From_Seconds_1970((int64s)Value);
1310 }
1311
Date_From_Seconds_1970(const int64s Value)1312 Ztring& Ztring::Date_From_Seconds_1970 (const int64s Value)
1313 {
1314 time_t Time=(time_t)Value;
1315 #if defined(HAVE_GMTIME_R)
1316 struct tm Gmt_Temp;
1317 struct tm *Gmt=gmtime_r(&Time, &Gmt_Temp);
1318 #elif defined(_MSC_VER)
1319 struct tm Gmt_Temp;
1320 errno_t gmtime_s_Result=gmtime_s(&Gmt_Temp , &Time);
1321 struct tm* Gmt=gmtime_s_Result?NULL:&Gmt_Temp;
1322 #else
1323 #ifdef __GNUC__
1324 #warning "This version of ZenLib is not thread safe"
1325 #endif
1326 struct tm *Gmt=gmtime(&Time);
1327 #endif
1328 if (!Gmt)
1329 {
1330 clear();
1331 return *this;
1332 }
1333 Ztring DateT;
1334 Ztring Date=__T("UTC ");
1335 Date+=Ztring::ToZtring((Gmt->tm_year+1900));
1336 Date+=__T("-");
1337 DateT.From_Number(Gmt->tm_mon+1); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_mon+1);}
1338 Date+=DateT;
1339 Date+=__T("-");
1340 DateT.From_Number(Gmt->tm_mday); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_mday);}
1341 Date+=DateT;
1342 Date+=__T(" ");
1343 DateT.From_Number(Gmt->tm_hour); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_hour);}
1344 Date+=DateT;
1345 Date+=__T(":");
1346 DateT=Ztring::ToZtring(Gmt->tm_min); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_min);}
1347 Date+=DateT;
1348 Date+=__T(":");
1349 DateT.From_Number(Gmt->tm_sec); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_sec);}
1350 Date+=DateT;
1351 assign (Date.c_str());
1352 return *this;
1353 }
1354
Date_From_Seconds_1970_Local(const int32u Value)1355 Ztring& Ztring::Date_From_Seconds_1970_Local (const int32u Value)
1356 {
1357 time_t Time=(time_t)Value;
1358 #if defined(HAVE_LOCALTIME_R)
1359 struct tm Gmt_Temp;
1360 struct tm *Gmt=localtime_r(&Time, &Gmt_Temp);
1361 #elif defined(_MSC_VER)
1362 struct tm Gmt_Temp;
1363 errno_t localtime_s_Result=localtime_s(&Gmt_Temp , &Time);
1364 struct tm* Gmt=localtime_s_Result?NULL:&Gmt_Temp;
1365 #else
1366 #ifdef __GNUC__
1367 #warning "This version of ZenLib is not thread safe"
1368 #endif
1369 struct tm *Gmt=localtime(&Time);
1370 #endif
1371 Ztring DateT;
1372 Ztring Date;
1373 if (Gmt)
1374 {
1375 Date+=Ztring::ToZtring((Gmt->tm_year+1900));
1376 Date+=__T("-");
1377 DateT.From_Number(Gmt->tm_mon+1); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_mon+1);}
1378 Date+=DateT;
1379 Date+=__T("-");
1380 DateT.From_Number(Gmt->tm_mday); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_mday);}
1381 Date+=DateT;
1382 Date+=__T(" ");
1383 DateT.From_Number(Gmt->tm_hour); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_hour);}
1384 Date+=DateT;
1385 Date+=__T(":");
1386 DateT=Ztring::ToZtring(Gmt->tm_min); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_min);}
1387 Date+=DateT;
1388 Date+=__T(":");
1389 DateT.From_Number(Gmt->tm_sec); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Gmt->tm_sec);}
1390 Date+=DateT;
1391 assign (Date.c_str());
1392 }
1393 return *this;
1394 }
1395
Date_From_String(const char * Value,size_t Value_Size)1396 Ztring& Ztring::Date_From_String (const char* Value, size_t Value_Size)
1397 {
1398 //Only the year
1399 if (Value_Size<10)
1400 {
1401 From_UTF8(Value, 0, Value_Size);
1402 return *this;
1403 }
1404
1405 #ifdef ZENLIB_USEWX
1406 Ztring ToReturn=__T("UTC ");
1407 wxDateTime Date;
1408 Ztring DateS;
1409 DateS.From_Local(Value, Value_Size).c_str();
1410 if (!DateS.empty() && DateS[DateS.size()-1]==__T('\n'))
1411 DateS.resize(DateS.size()-1);
1412
1413 //Some strange formating : exactly 24 bytes (or 25 with 0x0A at the end) and Year is at the end
1414 if (DateS.size()==24 && DateS[23]>=__T('0') && DateS[23]<=__T('9') && DateS[21]>=__T('0') && DateS[21]<=__T('9') && DateS[19]==__T(' '))
1415 Date.ParseFormat(DateS.c_str(), __T("%a %b %d %H:%M:%S %Y"));
1416 //ISO date
1417 else if (DateS.size()==10 && (DateS[4]<__T('0') || DateS[4]>__T('9')) && (DateS[7]<__T('0') || DateS[7]>__T('9')))
1418 {
1419 DateS[4]=__T('-');
1420 DateS[7]=__T('-');
1421 ToReturn+=DateS;
1422 }
1423 //Default
1424 else
1425 Date.ParseDateTime(DateS.c_str());
1426
1427 if (ToReturn.size()<5)
1428 {
1429 ToReturn+=Date.FormatISODate();
1430 ToReturn+=__T(" ");
1431 ToReturn+=Date.FormatISOTime();
1432 }
1433 else
1434 ToReturn+=DateS;
1435
1436 assign (ToReturn.c_str());
1437 #else //ZENLIB_USEWX
1438 Ztring DateS; DateS.From_UTF8(Value, 0, Value_Size);
1439 //Unix style formating : exactly 24 bytes (or 25 with 0x0A at the end) and Year is at the end
1440 if ((DateS.size()==24 || (DateS.size()==25 && DateS[24]==__T('\n'))) && DateS[23]>=__T('0') && DateS[23]<=__T('9') && DateS[21]>=__T('0') && DateS[21]<=__T('9') && DateS[19]==__T(' '))
1441 {
1442 clear();
1443 append(1, DateS[20]);
1444 append(1, DateS[21]);
1445 append(1, DateS[22]);
1446 append(1, DateS[23]);
1447 append(1, __T('-'));
1448 if (DateS[4]==__T('J') && DateS[5]==__T('a') && DateS[6]==__T('n') && DateS[7]==__T(' '))
1449 {
1450 append(1, __T('0'));
1451 append(1, __T('1'));
1452 }
1453 else if (DateS[4]==__T('F') && DateS[5]==__T('e') && DateS[6]==__T('b') && DateS[7]==__T(' '))
1454 {
1455 append(1, __T('0'));
1456 append(1, __T('2'));
1457 }
1458 else if (DateS[4]==__T('M') && DateS[5]==__T('a') && DateS[6]==__T('r') && DateS[7]==__T(' '))
1459 {
1460 append(1, __T('0'));
1461 append(1, __T('3'));
1462 }
1463 else if (DateS[4]==__T('A') && DateS[5]==__T('p') && DateS[6]==__T('r') && DateS[7]==__T(' '))
1464 {
1465 append(1, __T('0'));
1466 append(1, __T('4'));
1467 }
1468 else if (DateS[4]==__T('M') && DateS[5]==__T('a') && DateS[6]==__T('y') && DateS[7]==__T(' '))
1469 {
1470 append(1, __T('0'));
1471 append(1, __T('5'));
1472 }
1473 else if (DateS[4]==__T('J') && DateS[5]==__T('u') && DateS[6]==__T('n') && DateS[7]==__T(' '))
1474 {
1475 append(1, __T('0'));
1476 append(1, __T('6'));
1477 }
1478 else if (DateS[4]==__T('J') && DateS[5]==__T('u') && DateS[6]==__T('l') && DateS[7]==__T(' '))
1479 {
1480 append(1, __T('0'));
1481 append(1, __T('7'));
1482 }
1483 else if (DateS[4]==__T('A') && DateS[5]==__T('u') && DateS[6]==__T('g') && DateS[7]==__T(' '))
1484 {
1485 append(1, __T('0'));
1486 append(1, __T('8'));
1487 }
1488 else if (DateS[4]==__T('S') && DateS[5]==__T('e') && DateS[6]==__T('p') && DateS[7]==__T(' '))
1489 {
1490 append(1, __T('0'));
1491 append(1, __T('9'));
1492 }
1493 else if (DateS[4]==__T('O') && DateS[5]==__T('c') && DateS[6]==__T('t') && DateS[7]==__T(' '))
1494 {
1495 append(1, __T('1'));
1496 append(1, __T('0'));
1497 }
1498 else if (DateS[4]==__T('N') && DateS[5]==__T('o') && DateS[6]==__T('v') && DateS[7]==__T(' '))
1499 {
1500 append(1, __T('1'));
1501 append(1, __T('1'));
1502 }
1503 else if (DateS[4]==__T('D') && DateS[5]==__T('e') && DateS[6]==__T('c') && DateS[7]==__T(' '))
1504 {
1505 append(1, __T('1'));
1506 append(1, __T('2'));
1507 }
1508 else
1509 {
1510 assign(DateS);
1511 return *this;
1512 }
1513 append(1, __T('-'));
1514 append(1, DateS[8]);
1515 append(1, DateS[9]);
1516 append(1, __T(' '));
1517 append(1, DateS[11]);
1518 append(1, DateS[12]);
1519 append(1, __T(':'));
1520 append(1, DateS[14]);
1521 append(1, DateS[15]);
1522 append(1, __T(':'));
1523 append(1, DateS[17]);
1524 append(1, DateS[18]);
1525 }
1526 else if (DateS.size()==20 && DateS[4]==__T('-') && DateS[7]==__T('-') && DateS[10]==__T('T') && DateS[13]==__T(':') && DateS[16]==__T(':') && DateS[19]==__T('Z'))
1527 {
1528 DateS.resize(19);
1529 DateS[10]=__T(' ');
1530 assign(__T("UTC "));
1531 append(DateS);
1532 }
1533 else if (DateS.size()==23 && DateS[4]==__T('-') && DateS[7]==__T('-') && DateS[10]==__T(' ') && DateS[14]==__T(' ') && DateS[17]==__T(':') && DateS[20]==__T(':'))
1534 {
1535 DateS.erase(10, 4);
1536 //assign(__T("UTC ")); //Is not UTC
1537 append(DateS);
1538 }
1539 else
1540 From_UTF8(Value, 0, Value_Size); //Not implemented
1541 #endif //ZENLIB_USEWX
1542 return *this;
1543 }
1544
Date_From_Numbers(const int8u Year,const int8u Month,const int8u Day,const int8u Hour,const int8u Minute,const int8u Second)1545 Ztring& Ztring::Date_From_Numbers (const int8u Year, const int8u Month, const int8u Day, const int8u Hour, const int8u Minute, const int8u Second)
1546 {
1547 Ztring DateT;
1548 Ztring Date=__T("UTC ");
1549 DateT.From_Number(Year); if (DateT.size()<2){DateT=Ztring(__T("200"))+Ztring::ToZtring(Year);}; if (DateT.size()<3){DateT=Ztring(__T("20"))+Ztring::ToZtring(Year);}
1550 Date+=DateT;
1551 Date+=__T("-");
1552 DateT.From_Number(Month); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Month);}
1553 Date+=DateT;
1554 Date+=__T("-");
1555 DateT.From_Number(Day); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Day);}
1556 Date+=DateT;
1557 Date+=__T(" ");
1558 DateT.From_Number(Hour); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Hour);}
1559 Date+=DateT;
1560 Date+=__T(":");
1561 DateT=Ztring::ToZtring(Minute); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Minute);}
1562 Date+=DateT;
1563 Date+=__T(":");
1564 DateT.From_Number(Second); if (DateT.size()<2){DateT=Ztring(__T("0"))+Ztring::ToZtring(Second);}
1565 Date+=DateT;
1566 assign (Date.c_str());
1567 return *this;
1568 }
1569
1570 #ifndef WSTRING_MISSING
1571 //---------------------------------------------------------------------------
To_Unicode() const1572 std::wstring Ztring::To_Unicode () const
1573 {
1574 #ifdef _UNICODE
1575 return c_str();
1576 #else //_UNICODE
1577 #ifdef ZENLIB_USEWX
1578 return wxConvCurrent->cMB2WC(c_str()).data();
1579 #else //ZENLIB_USEWX
1580 return std::wstring(); //Not implemented
1581 #endif //ZENLIB_USEWX
1582 #endif //_UNICODE
1583 }
1584 #endif //WSTRING_MISSING
1585
To_UTF8() const1586 std::string Ztring::To_UTF8 () const
1587 {
1588 #ifdef _UNICODE
1589 //Correction thanks to Andrew Jang
1590 // Don't use WideCharToMultiByte(), some characters are not well converted
1591 std::string ToReturn;
1592 ToReturn.reserve(size()); // more efficient
1593
1594 const wchar_t* Z=c_str();
1595
1596 while (*Z)
1597 {
1598 if (*Z < 0x80)
1599 {
1600 ToReturn += (char)(*(Z++));
1601 continue;
1602 }
1603
1604 int32u wc; // must be unsigned.
1605
1606 #if defined(_MSC_VER)
1607 #pragma warning(push)
1608 #pragma warning(disable:4127)
1609 #endif //defined(_MSC_VER)
1610 if (sizeof(wchar_t) == 2)
1611 #if defined(_MSC_VER)
1612 #pragma warning(pop)
1613 #endif //defined(_MSC_VER)
1614 {
1615 if (((*Z) & 0xFC00) == 0xD800)
1616 {
1617 //UTF-16
1618 wc =( (((int16u) *Z) & 0x3FF) + 0x40) << 10;
1619 Z++;
1620 wc |= (((int16u) *Z) & 0x3FF);
1621 }
1622 else
1623 wc = (int16u) *Z; // avoid a cast problem if wchar_t is signed.
1624 }
1625 else
1626 wc = *Z;
1627
1628 int count;
1629
1630 // refer to http://en.wikipedia.org/wiki/UTF-8#Description
1631
1632 if (wc < 0x80)
1633 count = 1;
1634 else if (wc < 0x800)
1635 count = 2;
1636 else if (wc < 0x10000)
1637 count = 3;
1638 else if (wc < 0x200000)
1639 count = 4;
1640 else if (wc < 0x4000000)
1641 count = 5;
1642 else if (wc <= 0x7fffffff)
1643 count = 6;
1644 else
1645 break; // bad character
1646
1647 int64u utfbuf = 0; // 8 bytes
1648 char* utf8chars = (char*) &utfbuf;
1649
1650 switch (count)
1651 {
1652 case 6:
1653 utf8chars[5] = 0x80 | (wc & 0x3f);
1654 wc = (wc >> 6) | 0x4000000;
1655 /* fallthrough */
1656 case 5:
1657 utf8chars[4] = 0x80 | (wc & 0x3f);
1658 wc = (wc >> 6) | 0x200000;
1659 /* fallthrough */
1660 case 4:
1661 utf8chars[3] = 0x80 | (wc & 0x3f);
1662 wc = (wc >> 6) | 0x10000;
1663 /* fallthrough */
1664 case 3:
1665 utf8chars[2] = 0x80 | (wc & 0x3f);
1666 wc = (wc >> 6) | 0x800;
1667 /* fallthrough */
1668 case 2:
1669 utf8chars[1] = 0x80 | (wc & 0x3f);
1670 wc = (wc >> 6) | 0xc0;
1671 /* fallthrough */
1672 case 1:
1673 utf8chars[0] = (char) wc;
1674 }
1675
1676 ToReturn += utf8chars;
1677
1678 ++Z;
1679 }
1680
1681 return ToReturn;
1682 #else
1683 #ifdef ZENLIB_USEWX
1684 return wxConvUTF8.cWC2MB(wxConvCurrent->cMB2WC(c_str())).data();
1685 #else //ZENLIB_USEWX
1686 return c_str(); //Not implemented
1687 #endif //ZENLIB_USEWX
1688 #endif
1689 }
1690
To_Local() const1691 std::string Ztring::To_Local () const
1692 {
1693 #ifdef _UNICODE
1694 #ifdef ZENLIB_USEWX
1695 wxCharBuffer C=wxConvCurrent->cWC2MB(c_str());
1696 if (C.data())
1697 return C.data();
1698 else
1699 return std::string();
1700 #else //ZENLIB_USEWX
1701 #ifdef WINDOWS
1702 int Size=WideCharToMultiByte(CP_ACP, 0, c_str(), -1, NULL, 0, NULL, NULL);
1703 if (Size!=0)
1704 {
1705 char* AnsiString=new char[Size+1];
1706 WideCharToMultiByte(CP_ACP, 0, c_str(), -1, AnsiString, Size, NULL, NULL);
1707 AnsiString[Size]='\0';
1708 std::string ToReturn(AnsiString);
1709 delete[] AnsiString; //AnsiString=NULL;
1710 return ToReturn;
1711 }
1712 else
1713 return std::string();
1714 #else //WINDOWS
1715 if (empty())
1716 return std::string();
1717
1718 size_t Size=wcstombs(NULL, c_str(), 0);
1719 if (Size!=0 && Size!=(size_t)-1)
1720 {
1721 char* AnsiString=new char[Size+1];
1722 Size=wcstombs(AnsiString, c_str(), Size);
1723 if (Size!=0 && Size!=(size_t)-1)
1724 {
1725 AnsiString[Size]='\0';
1726 std::string ToReturn(AnsiString);
1727 delete[] AnsiString; //AnsiString=NULL;
1728 return ToReturn;
1729 }
1730
1731 //Failed
1732 delete[] AnsiString; //AnsiString=NULL;
1733 }
1734
1735 //Trying with bad chars
1736 char* Result=new char[MB_CUR_MAX];
1737 std::string AnsiString;
1738 for (size_t Pos=0; Pos<size(); Pos++)
1739 {
1740 size_t Result_Size=wcrtomb(Result, operator[](Pos), 0);
1741 if (Result_Size && Result_Size!=(size_t)-1)
1742 AnsiString.append(Result, Result_Size);
1743 else
1744 AnsiString+='?';
1745 }
1746 delete[] Result; //Result=NULL;
1747 return AnsiString;
1748 #endif
1749 #endif //ZENLIB_USEWX
1750 #else
1751 return c_str();
1752 #endif
1753 }
1754
1755 //---------------------------------------------------------------------------
To_UUID() const1756 int128u Ztring::To_UUID () const
1757 {
1758 if (size()!=36)
1759 return 0;
1760
1761 Ztring Temp=*this;
1762
1763 for (size_t Pos=0; Pos<36; Pos++)
1764 {
1765 if ((Temp[Pos]< __T('0') || Temp[Pos]> __T('9'))
1766 && (Temp[Pos]< __T('A') || Temp[Pos]> __T('F'))
1767 && (Temp[Pos]< __T('a') || Temp[Pos]> __T('f')))
1768 return 0;
1769 if (Temp[Pos]>=__T('A') && Temp[Pos]<=__T('F'))
1770 {
1771 Temp[Pos]-=__T('A');
1772 Temp[Pos]+=__T('9')+1;
1773 }
1774 if (Temp[Pos]>=__T('a') && Temp[Pos]<=__T('f'))
1775 {
1776 Temp[Pos]-=__T('a');
1777 Temp[Pos]+=__T('9')+1;
1778 }
1779
1780 switch(Pos)
1781 {
1782 case 7 :
1783 case 12 :
1784 case 17 :
1785 case 22 :
1786 if (at(Pos+1)!=__T('-'))
1787 return 0;
1788 Pos++; //Skipping dash in the test
1789 }
1790 }
1791
1792 int128u I;
1793 I.hi=((int64u)((int8u)(Temp[ 0]-'0'))<<60)
1794 | ((int64u)((int8u)(Temp[ 1]-'0'))<<56)
1795 | ((int64u)((int8u)(Temp[ 2]-'0'))<<52)
1796 | ((int64u)((int8u)(Temp[ 3]-'0'))<<48)
1797 | ((int64u)((int8u)(Temp[ 4]-'0'))<<44)
1798 | ((int64u)((int8u)(Temp[ 5]-'0'))<<40)
1799 | ((int64u)((int8u)(Temp[ 6]-'0'))<<36)
1800 | ((int64u)((int8u)(Temp[ 7]-'0'))<<32)
1801 | ((int64u)((int8u)(Temp[ 9]-'0'))<<28)
1802 | ((int64u)((int8u)(Temp[10]-'0'))<<24)
1803 | ((int64u)((int8u)(Temp[11]-'0'))<<20)
1804 | ((int64u)((int8u)(Temp[12]-'0'))<<16)
1805 | ((int64u)((int8u)(Temp[14]-'0'))<<12)
1806 | ((int64u)((int8u)(Temp[15]-'0'))<< 8)
1807 | ((int64u)((int8u)(Temp[16]-'0'))<< 4)
1808 | ((int64u)((int8u)(Temp[17]-'0')) );
1809 I.lo=((int64u)((int8u)(Temp[19]-'0'))<<60)
1810 | ((int64u)((int8u)(Temp[20]-'0'))<<56)
1811 | ((int64u)((int8u)(Temp[21]-'0'))<<52)
1812 | ((int64u)((int8u)(Temp[22]-'0'))<<48)
1813 | ((int64u)((int8u)(Temp[24]-'0'))<<44)
1814 | ((int64u)((int8u)(Temp[25]-'0'))<<40)
1815 | ((int64u)((int8u)(Temp[26]-'0'))<<36)
1816 | ((int64u)((int8u)(Temp[27]-'0'))<<32)
1817 | ((int64u)((int8u)(Temp[28]-'0'))<<28)
1818 | ((int64u)((int8u)(Temp[29]-'0'))<<24)
1819 | ((int64u)((int8u)(Temp[30]-'0'))<<20)
1820 | ((int64u)((int8u)(Temp[31]-'0'))<<16)
1821 | ((int64u)((int8u)(Temp[32]-'0'))<<12)
1822 | ((int64u)((int8u)(Temp[33]-'0'))<< 8)
1823 | ((int64u)((int8u)(Temp[34]-'0'))<< 4)
1824 | ((int64u)((int8u)(Temp[35]-'0')) );
1825
1826 return I;
1827 }
1828
1829 //---------------------------------------------------------------------------
To_CC4() const1830 int32u Ztring::To_CC4 () const
1831 {
1832 int32u I;
1833 I =((int32u)((int8u)at(0))<<24)
1834 | ((int32u)((int8u)at(1))<<16)
1835 | ((int32u)((int8u)at(2))<< 8)
1836 | ((int32u)((int8u)at(3)) );
1837
1838 return I;
1839 }
1840
1841 //---------------------------------------------------------------------------
1842 //Operateur ToInt
To_int8s(int8u Radix,ztring_t Options) const1843 int8s Ztring::To_int8s (int8u Radix, ztring_t Options) const
1844 {
1845 //Integrity
1846 if (empty())
1847 return 0;
1848
1849 //Conversion
1850 int I;
1851 #if defined(STREAM_MISSING)
1852 #ifdef __MINGW32__
1853 I=_ttoi(c_str());
1854 #elif defined(UNICODE)
1855 std::string S=To_UTF8();
1856 I=atoi(S.c_str());
1857 #else //UNICODE
1858 I=atoi(c_str());
1859 #endif //UNICODE
1860 #else
1861 tStringStream Stream(*this);
1862 Stream >> setbase(Radix) >> I;
1863 if (Stream.fail())
1864 return 0;
1865 #endif
1866
1867 //Rounded
1868 if (Options==Ztring_Rounded && find(__T('.'))!=Error)
1869 {
1870 float80 F=To_float80();
1871 F-=I;
1872 if (F>=0.5f)
1873 return (int8s)I+1;
1874 }
1875
1876 return (int8s)I;
1877 }
1878
1879 //---------------------------------------------------------------------------
1880 //Operateur ToInt
To_int8u(int8u Radix,ztring_t Options) const1881 int8u Ztring::To_int8u (int8u Radix, ztring_t Options) const
1882 {
1883 //Integrity
1884 if (empty())
1885 return 0;
1886
1887 //Conversion
1888 unsigned int I;
1889 #if defined(STREAM_MISSING)
1890 #ifdef __MINGW32__
1891 I=_ttoi64(c_str()); //TODO : I>0x7FFFFFFF - Replaced by i64 version to support, but not good
1892 #elif defined(UNICODE)
1893 std::string S=To_UTF8();
1894 I=atoi(S.c_str());
1895 #else //defined(UNICODE)
1896 I=atoi(c_str());
1897 #endif //defined(UNICODE)
1898 #else
1899 tStringStream Stream(*this);
1900 Stream >> setbase(Radix) >> I;
1901 if (Stream.fail())
1902 return 0;
1903 #endif
1904
1905 //Rounded
1906 if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos)
1907 {
1908 float32 F=To_float32();
1909 F-=I;
1910 if (F>=0.5f)
1911 return (int8u)I+1;
1912 }
1913
1914 return (int8u)I;
1915 }
1916
1917 //---------------------------------------------------------------------------
1918 //Operateur ToInt
To_int16s(int8u Radix,ztring_t Options) const1919 int16s Ztring::To_int16s (int8u Radix, ztring_t Options) const
1920 {
1921 //Integrity
1922 if (empty())
1923 return 0;
1924
1925 //Conversion
1926 int I;
1927 #if defined(STREAM_MISSING)
1928 #ifdef __MINGW32__
1929 I=_ttoi(c_str());
1930 #elif defined(UNICODE)
1931 std::string S=To_UTF8();
1932 I=atoi(S.c_str());
1933 #else //defined(UNICODE)
1934 I=atoi(c_str());
1935 #endif //defined(UNICODE)
1936 #else
1937 tStringStream Stream(*this);
1938 Stream >> setbase(Radix) >> I;
1939 if (Stream.fail())
1940 return 0;
1941 #endif
1942
1943 //Rounded
1944 if (Options==Ztring_Rounded && find(__T('.'))!=Error)
1945 {
1946 float80 F=To_float80();
1947 F-=I;
1948 if (F>=0.5f)
1949 return (int16s)I+1;
1950 }
1951
1952 return (int16s)I;
1953 }
1954
1955 //---------------------------------------------------------------------------
1956 //Operateur ToInt
To_int16u(int8u Radix,ztring_t Options) const1957 int16u Ztring::To_int16u (int8u Radix, ztring_t Options) const
1958 {
1959 //Integrity
1960 if (empty())
1961 return 0;
1962
1963 //Conversion
1964 unsigned int I;
1965 #if defined(STREAM_MISSING)
1966 #ifdef __MINGW32__
1967 I=_ttoi64(c_str()); //TODO : I>0x7FFFFFFF - Replaced by i64 version to support, but not good
1968 #elif defined(UNICODE)
1969 std::string S=To_UTF8();
1970 I=atoi(S.c_str());
1971 #else //defined(UNICODE)
1972 I=atoi(c_str());
1973 #endif //defined(UNICODE)
1974 #else
1975 tStringStream Stream(*this);
1976 Stream >> setbase(Radix) >> I;
1977 if (Stream.fail())
1978 return 0;
1979 #endif
1980
1981 //Rounded
1982 if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos)
1983 {
1984 float32 F=To_float32();
1985 F-=I;
1986 if (F>=0.5f)
1987 return (int16u)I+1;
1988 }
1989
1990 return (int16u)I;
1991 }
1992
1993 //---------------------------------------------------------------------------
1994 //Operateur ToInt
To_int32s(int8u Radix,ztring_t Options) const1995 int32s Ztring::To_int32s (int8u Radix, ztring_t Options) const
1996 {
1997 //Integrity
1998 if (empty())
1999 return 0;
2000
2001 //Conversion
2002 int32s I;
2003 #if defined(STREAM_MISSING)
2004 #ifdef __MINGW32__
2005 I=_ttoi(c_str());
2006 #elif defined(UNICODE)
2007 std::string S=To_UTF8();
2008 I=atol(S.c_str());
2009 #else //defined(UNICODE)
2010 I=atol(c_str());
2011 #endif //defined(UNICODE)
2012 #else
2013 tStringStream Stream(*this);
2014 Stream >> setbase(Radix) >> I;
2015 if (Stream.fail())
2016 return 0;
2017 #endif
2018
2019 //Rounded
2020 if (Options==Ztring_Rounded && find(__T('.'))!=Error)
2021 {
2022 float80 F=To_float80();
2023 F-=I;
2024 if (F>=0.5f)
2025 return I+1;
2026 }
2027
2028 return I;
2029 }
2030
2031 //---------------------------------------------------------------------------
2032 //Operateur ToInt
To_int32u(int8u Radix,ztring_t Options) const2033 int32u Ztring::To_int32u (int8u Radix, ztring_t Options) const
2034 {
2035 //Integrity
2036 if (empty())
2037 return 0;
2038
2039 //Conversion
2040 int32u I;
2041 #if defined(STREAM_MISSING)
2042 #ifdef __MINGW32__
2043 I=_ttoi64(c_str()); //TODO : I>0x7FFFFFFF - Replaced by i64 version to support, but not good
2044 #elif defined(UNICODE)
2045 std::string S=To_UTF8();
2046 I=atol(S.c_str());
2047 #else //defined(UNICODE)
2048 I=atol(c_str());
2049 #endif //defined(UNICODE)
2050 #else
2051 tStringStream Stream(*this);
2052 Stream >> setbase(Radix) >> I;
2053 if (Stream.fail())
2054 return 0;
2055 #endif
2056
2057 //Rounded
2058 if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos)
2059 {
2060 float32 F=To_float32();
2061 F-=I;
2062 if (F>=0.5f)
2063 return I+1;
2064 }
2065
2066 return I;
2067 }
2068
2069 //---------------------------------------------------------------------------
2070 //Operateur ToInt
To_int64s(int8u Radix,ztring_t Options) const2071 int64s Ztring::To_int64s (int8u Radix, ztring_t Options) const
2072 {
2073 //Integrity
2074 if (empty())
2075 return 0;
2076
2077 //Conversion
2078 int64s I;
2079 #if defined(STREAM_MISSING)
2080 #ifdef __MINGW32__
2081 I=_ttoi64(c_str());
2082 #elif defined(UNICODE)
2083 std::string S=To_UTF8();
2084 I=atoll(S.c_str());
2085 #else //defined(UNICODE)
2086 I=atoll(c_str());
2087 #endif //defined(UNICODE)
2088 #else
2089 tStringStream Stream(*this);
2090 Stream >> setbase(Radix) >> I;
2091 if (Stream.fail())
2092 return 0;
2093 #endif
2094
2095 //Rounded
2096 if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos)
2097 {
2098 float32 F=To_float32();
2099 F-=I;
2100 if (F>0.5f)
2101 return I+1;
2102 }
2103
2104 return I;
2105 }
2106
2107 //---------------------------------------------------------------------------
2108 //Operateur ToInt
To_int64u(int8u Radix,ztring_t Options) const2109 int64u Ztring::To_int64u (int8u Radix, ztring_t Options) const
2110 {
2111 //Integrity
2112 if (empty())
2113 return 0;
2114
2115 //Conversion
2116 int64u I;
2117 #if defined(STREAM_MISSING)
2118 #ifdef __MINGW32__
2119 I=_ttoi64(c_str()); //TODO : I>0x7FFFFFFFFFFFFFFF
2120 #elif defined(UNICODE)
2121 std::string S=To_UTF8();
2122 I=atoll(S.c_str());
2123 #else //defined(UNICODE)
2124 I=atoll(c_str());
2125 #endif //defined(UNICODE)
2126 #else
2127 tStringStream Stream(*this);
2128 Stream >> setbase(Radix) >> I;
2129 if (Stream.fail())
2130 return 0;
2131 #endif
2132
2133 //Rounded
2134 if (Options==Ztring_Rounded && find(__T('.'))!=std::string::npos)
2135 {
2136 float32 F=To_float32();
2137 F-=I;
2138 if (F>=0.5f)
2139 return I+1;
2140 }
2141
2142 return I;
2143 }
2144
2145 //---------------------------------------------------------------------------
To_int128u(int8u,ztring_t) const2146 int128u Ztring::To_int128u (int8u, ztring_t) const
2147 {
2148 if (size()!=32)
2149 return 0;
2150
2151 Ztring Temp=*this;
2152
2153 for (size_t Pos=0; Pos<32; Pos++)
2154 {
2155 if ((Temp[Pos]< __T('0') || Temp[Pos]> __T('9'))
2156 && (Temp[Pos]< __T('A') || Temp[Pos]> __T('F'))
2157 && (Temp[Pos]< __T('a') || Temp[Pos]> __T('f')))
2158 return 0;
2159 if (Temp[Pos]>=__T('A') && Temp[Pos]<=__T('F'))
2160 {
2161 Temp[Pos]-=__T('A');
2162 Temp[Pos]+=__T('9')+1;
2163 }
2164 if (Temp[Pos]>=__T('a') && Temp[Pos]<=__T('f'))
2165 {
2166 Temp[Pos]-=__T('a');
2167 Temp[Pos]+=__T('9')+1;
2168 }
2169 }
2170
2171 int128u I;
2172 I.hi=((int64u)((int8u)(Temp[ 0]-'0'))<<60)
2173 | ((int64u)((int8u)(Temp[ 1]-'0'))<<56)
2174 | ((int64u)((int8u)(Temp[ 2]-'0'))<<52)
2175 | ((int64u)((int8u)(Temp[ 3]-'0'))<<48)
2176 | ((int64u)((int8u)(Temp[ 4]-'0'))<<44)
2177 | ((int64u)((int8u)(Temp[ 5]-'0'))<<40)
2178 | ((int64u)((int8u)(Temp[ 6]-'0'))<<36)
2179 | ((int64u)((int8u)(Temp[ 7]-'0'))<<32)
2180 | ((int64u)((int8u)(Temp[ 8]-'0'))<<28)
2181 | ((int64u)((int8u)(Temp[ 9]-'0'))<<24)
2182 | ((int64u)((int8u)(Temp[10]-'0'))<<20)
2183 | ((int64u)((int8u)(Temp[11]-'0'))<<16)
2184 | ((int64u)((int8u)(Temp[12]-'0'))<<12)
2185 | ((int64u)((int8u)(Temp[13]-'0'))<< 8)
2186 | ((int64u)((int8u)(Temp[14]-'0'))<< 4)
2187 | ((int64u)((int8u)(Temp[15]-'0')) );
2188 I.lo=((int64u)((int8u)(Temp[16]-'0'))<<60)
2189 | ((int64u)((int8u)(Temp[17]-'0'))<<56)
2190 | ((int64u)((int8u)(Temp[18]-'0'))<<52)
2191 | ((int64u)((int8u)(Temp[19]-'0'))<<48)
2192 | ((int64u)((int8u)(Temp[20]-'0'))<<44)
2193 | ((int64u)((int8u)(Temp[21]-'0'))<<40)
2194 | ((int64u)((int8u)(Temp[22]-'0'))<<36)
2195 | ((int64u)((int8u)(Temp[23]-'0'))<<32)
2196 | ((int64u)((int8u)(Temp[24]-'0'))<<28)
2197 | ((int64u)((int8u)(Temp[25]-'0'))<<24)
2198 | ((int64u)((int8u)(Temp[26]-'0'))<<20)
2199 | ((int64u)((int8u)(Temp[27]-'0'))<<16)
2200 | ((int64u)((int8u)(Temp[28]-'0'))<<12)
2201 | ((int64u)((int8u)(Temp[29]-'0'))<< 8)
2202 | ((int64u)((int8u)(Temp[30]-'0'))<< 4)
2203 | ((int64u)((int8u)(Temp[31]-'0')) );
2204
2205 return I;
2206 }
2207
2208 //---------------------------------------------------------------------------
2209 //Operateur ToFloat
To_float32(ztring_t) const2210 float32 Ztring::To_float32(ztring_t) const
2211 {
2212 //Integrity
2213 if (empty())
2214 return 0;
2215
2216 //Conversion
2217 #if defined(STREAM_MISSING)
2218 #ifdef UNICODE
2219 return (wcstod(c_str(),NULL));
2220 #else
2221 return (strtod(c_str(),NULL));
2222 #endif
2223 #else
2224 float32 F;
2225 tStringStream Stream(*this);
2226 Stream >> F;
2227 if (Stream.fail())
2228 return 0;
2229
2230 return F;
2231 #endif
2232 }
2233
2234 //---------------------------------------------------------------------------
2235 //Operateur ToFloat
To_float64(ztring_t) const2236 float64 Ztring::To_float64(ztring_t) const
2237 {
2238 //Integrity
2239 if (empty())
2240 return 0;
2241
2242 //Conversion
2243 #if defined(STREAM_MISSING)
2244 #ifdef UNICODE
2245 return (wcstod(c_str(),NULL)); //TODO verify no wcstold
2246 #else
2247 return (strtod(c_str(),NULL)); //TODO verify no strtold
2248 #endif
2249 #else
2250 float64 F;
2251 tStringStream Stream(*this);
2252 Stream >> F;
2253 if (Stream.fail())
2254 return 0;
2255
2256 return F;
2257 #endif
2258 }
2259
2260 //---------------------------------------------------------------------------
2261 //Operateur ToFloat
To_float80(ztring_t) const2262 float80 Ztring::To_float80(ztring_t) const
2263 {
2264 //Integrity
2265 if (empty())
2266 return 0;
2267
2268 //Conversion
2269 #if defined(STREAM_MISSING)
2270 #ifdef UNICODE
2271 return (wcstod(c_str(),NULL)); //TODO verify no wcstold
2272 #else
2273 return (strtod(c_str(),NULL)); //TODO verify no strtold
2274 #endif
2275 #else
2276 float80 F;
2277 tStringStream Stream(*this);
2278 Stream >> F;
2279 if (Stream.fail())
2280 return 0;
2281
2282 return F;
2283 #endif
2284 }
2285
2286 //***************************************************************************
2287 // Edition
2288 //***************************************************************************
2289
2290 //---------------------------------------------------------------------------
2291 // Retourne une partie de la chaine
SubString(const tstring & Begin,const tstring & End,size_type Pos,ztring_t Options) const2292 Ztring Ztring::SubString (const tstring &Begin, const tstring &End, size_type Pos, ztring_t Options) const
2293 {
2294 //Recherche Debut
2295 size_type I_Debut=find(Begin, Pos);
2296 if (I_Debut==Error)
2297 return Ztring();
2298 I_Debut+=Begin.size();
2299
2300 //gestion fin NULL
2301 if (End.empty())
2302 return substr(I_Debut);
2303
2304 //Recherche Fin
2305 size_type I_Fin=find(End, I_Debut);
2306 if (I_Fin==Error)
2307 {
2308 if (Options & Ztring_AddLastItem)
2309 return substr(I_Debut);
2310 else
2311 return Ztring();
2312 }
2313
2314 return substr(I_Debut, I_Fin-I_Debut);
2315 }
2316
2317 //---------------------------------------------------------------------------
2318 //FindAndReplace
FindAndReplace(const ZenLib::tstring & ToFind,const ZenLib::tstring & ReplaceBy,size_type Pos,ZenLib::ztring_t Options)2319 Ztring::size_type Ztring::FindAndReplace (const ZenLib::tstring &ToFind, const ZenLib::tstring &ReplaceBy, size_type Pos, ZenLib::ztring_t Options)
2320 {
2321 if (ToFind.empty())
2322 return 0;
2323
2324 size_type Count=0;
2325 size_type Middle=Pos;
2326 while (!(Count==1 && !(Options&Ztring_Recursive)) && (Middle=find(ToFind, Middle))!=npos)
2327 {
2328 replace(Middle, ToFind.length(), ReplaceBy);
2329 Middle += ReplaceBy.length();
2330 Count++;
2331 }
2332
2333 return Count;
2334 }
2335
2336 //---------------------------------------------------------------------------
2337 //test if it is a number
IsNumber() const2338 bool Ztring::IsNumber() const
2339 {
2340 if (empty())
2341 return false;
2342
2343 bool OK=true;
2344 size_t Size=size();
2345 for (size_t Pos=0; Pos<Size; Pos++)
2346 if (operator[](Pos)<__T('0') || operator[](Pos)>__T('9'))
2347 {
2348 OK=false;
2349 break;
2350 }
2351 return OK;
2352 }
2353
2354 //---------------------------------------------------------------------------
2355 //Mise en minuscules
MakeLowerCase()2356 Ztring &Ztring::MakeLowerCase()
2357 {
2358 transform(begin(), end(), begin(), (int(*)(int))tolower); //(int(*)(int)) is a patch for unix
2359 return *this;
2360 }
2361
2362 //---------------------------------------------------------------------------
2363 // Mise en majuscules
MakeUpperCase()2364 Ztring &Ztring::MakeUpperCase()
2365 {
2366 transform(begin(), end(), begin(), (int(*)(int))toupper); //(int(*)(int)) is a patch for unix
2367 return *this;
2368 }
2369
2370 //---------------------------------------------------------------------------
2371 // Remove leading whitespaces from a string
TrimLeft(Char ToTrim)2372 Ztring &Ztring::TrimLeft(Char ToTrim)
2373 {
2374 size_type First=0;
2375 while (First<size() && operator[](First)==ToTrim)
2376 First++;
2377 assign (c_str()+First);
2378 return *this;
2379 }
2380
2381 //---------------------------------------------------------------------------
2382 // Remove trailing whitespaces from a string
TrimRight(Char ToTrim)2383 Ztring &Ztring::TrimRight(Char ToTrim)
2384 {
2385 if (size()==0)
2386 return *this;
2387
2388 size_type Last=size()-1;
2389 while (Last!=(size_type)-1 && operator[](Last)==ToTrim)
2390 Last--;
2391 assign (c_str(), Last+1);
2392 return *this;
2393 }
2394
2395 //---------------------------------------------------------------------------
2396 // Remove leading and trailing whitespaces from a string
Trim(Char ToTrim)2397 Ztring &Ztring::Trim(Char ToTrim)
2398 {
2399 TrimLeft(ToTrim);
2400 TrimRight(ToTrim);
2401 return *this;
2402 }
2403
2404 //---------------------------------------------------------------------------
2405 // Quotes a string
Quote(Char ToTrim)2406 Ztring &Ztring::Quote(Char ToTrim)
2407 {
2408 assign(tstring(1, ToTrim)+c_str()+ToTrim);
2409 return *this;
2410 }
2411
2412 //***************************************************************************
2413 // Information
2414 //***************************************************************************
2415
2416 //---------------------------------------------------------------------------
2417 //Count
Count(const Ztring & ToCount,ztring_t) const2418 Ztring::size_type Ztring::Count (const Ztring &ToCount, ztring_t) const
2419 {
2420 size_type Count=0;
2421 for (size_type Pos=0; Pos<=size(); Pos++)
2422 if (find(ToCount, Pos)!=npos)
2423 {
2424 Count++;
2425 Pos+=ToCount.size()-1; //-1 because the loop will add 1
2426 }
2427 return Count;
2428 }
2429
2430 //---------------------------------------------------------------------------
2431 //Compare
Compare(const Ztring & ToCompare,const Ztring & Comparator,ztring_t Options) const2432 bool Ztring::Compare (const Ztring &ToCompare, const Ztring &Comparator, ztring_t Options) const
2433 {
2434 //Integers management
2435 if (IsNumber() && ToCompare.IsNumber())
2436 {
2437 int64s Left=To_int64s();
2438 int64s Right=ToCompare.To_int64s();
2439 if (Comparator==__T("==")) return (Left==Right);
2440 if (Comparator==__T("<")) return (Left< Right);
2441 if (Comparator==__T("<=")) return (Left<=Right);
2442 if (Comparator==__T(">=")) return (Left>=Right);
2443 if (Comparator==__T(">")) return (Left> Right);
2444 if (Comparator==__T("!=")) return (Left!=Right);
2445 if (Comparator==__T("<>")) return (Left!=Right);
2446 return false;
2447 }
2448
2449 //Case sensitive option
2450 if (!(Options & Ztring_CaseSensitive))
2451 {
2452 //Need to copy strings and make it lowercase
2453 Ztring Left (c_str());
2454 Ztring Right (ToCompare.c_str());
2455 Left.MakeLowerCase();
2456 Right.MakeLowerCase();
2457
2458 //string comparasion
2459 if (Comparator==__T("==")) return (Left==Right);
2460 if (Comparator==__T("IN")) {if (Left.find(Right)!=string::npos) return true; else return false;}
2461 if (Comparator==__T("<")) return (Left< Right);
2462 if (Comparator==__T("<=")) return (Left<=Right);
2463 if (Comparator==__T(">=")) return (Left>=Right);
2464 if (Comparator==__T(">")) return (Left> Right);
2465 if (Comparator==__T("!=")) return (Left!=Right);
2466 if (Comparator==__T("<>")) return (Left!=Right);
2467 return false;
2468 }
2469 else
2470 {
2471 //string comparasion
2472 if (Comparator==__T("==")) return (*this==ToCompare);
2473 if (Comparator==__T("IN")) {if (this->find(ToCompare)!=string::npos) return true; else return false;}
2474 if (Comparator==__T("<")) return (*this< ToCompare);
2475 if (Comparator==__T("<=")) return (*this<=ToCompare);
2476 if (Comparator==__T(">=")) return (*this>=ToCompare);
2477 if (Comparator==__T(">")) return (*this> ToCompare);
2478 if (Comparator==__T("!=")) return (*this!=ToCompare);
2479 if (Comparator==__T("<>")) return (*this!=ToCompare);
2480 return false;
2481 }
2482 }
2483
2484 } //namespace
2485