acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
_impl.h
1#pragma once
2
3
4#include "_const_string_range_impl.h"
5#include "_impl_const_string_range.h"
6#include "_impl_string_base.h"
7#include "_impl_string_base_allocation.h"
8#include "_impl_string_meta_data.h"
9#include "_impl_string_range.h"
10
11#include "c/_impl.h"
12//#include "sz/_impl.h"
13
14#include "unicode_impl.h"
15
16
17#include "_u32hash.h"
18#include "_conv.h"
19#include "hex.h"
20
21
22CLASS_DECL_ACME ::i64 strtoi(const ::scoped_string & scopedstr);
23CLASS_DECL_ACME ::i64 strtoi(const ::wide_character * psz);
24
25
26namespace file
27{
28
29
30 class str;
31
32
33} // namespace file
34
35
36#if defined(__APPLE)
37
38#define noexcept
39
40#endif
41
42//
43//template <typename T>
44//inline T FormatArgument(T value) noexcept
45//{
46//
47// return value;
48//
49//}
50//
51//
52//#ifdef WINDOWS
53//inline ::u32 _gen_GetConversionACP()
54//{
55//
56// //return CP_UTF8;
57// return CodePageUtf8;
58//
59//}
60//#endif
61
62
64
65
66template < >
67inline ::hash32 as_hash32 < const ansi_string & >(const ansi_string & ansistr)
68{
69
70 return as_hash32(ansistr.c_str());
71
72}
73
74
75template < >
76inline ::hash32 as_hash32 < const wide_string & >(const wide_string & widestr)
77{
78
79 return as_hash32(widestr.c_str());
80
81}
82
83
84//inline const_char_pointer FormatArgument(const string & value) noexcept { return value.c_str(); }
85
86
87//template < typename TYPE_CHAR >
88//inline string_base < TYPE_CHAR > operator +(const string_base < TYPE_CHAR > & str1, const string_base < TYPE_CHAR > & str2)
89//{
90//
91// string_base < TYPE_CHAR > str;
92//
93// return string_concatenate(str, str1, str1.length(), str2, str2.length());
94//
95//}
96
97
98
99//template < prototype_character CHARACTER, prototype_character CHARACTER2 >
100//inline ::string_base < CHARACTER2 > operator +(const CHARACTER * pszLeft, const ::string_base < CHARACTER2 > & strRight)
101//{
102//
103// ::wstring strLeft(scopedstrLeft);
104//
105// return strLeft + strRight;
106//
107//}
108//template < prototype_character CHARACTER, prototype_character CHARACTER2 >
109//inline ::string_base < CHARACTER2 > operator +(const CHARACTER chLeft, const ::string_base < CHARACTER2 > & strRight)
110//{
111//
112// ::string_base < CHARACTER2 > strLeft(&chLeft, 1);
113//
114// return strLeft + strRight;
115//
116//}
117
118
119//#include "__c_wd16_impl.h"
120
121
122//#include "_string_base_impl.h"
123
124
125template < typename CHAR_TYPE1, typename CHAR_TYPE2 >
126void copy(::string_base < CHAR_TYPE1 >& str1, const ::string_base < CHAR_TYPE2 >& str2)
127{
128
129 str1 = str2;
130
131}
132
133
134template < typename CHAR_TYPE1, prototype_character CHARACTER, std::size_t N >
135void copy(::string_base < CHAR_TYPE1 >& str1, const CHARACTER sz[N])
136{
137
138 str1 = sz;
139
140}
141
142
143template < typename CHAR_TYPE1, prototype_character CHARACTER >
144void copy(::string_base < CHAR_TYPE1 >& str1, const CHARACTER* psz)
145{
146
147 str1 = psz;
148
149}
150
151
152
153
154
155template < prototype_string STRING, prototype_integral INTEGRAL >
156inline STRING& copy(STRING& string, const INTEGRAL& number)
157{
158
159 string.append_formatf("%lld", (::i64)number);
160
161 return string;
162
163}
164
165
166template < prototype_signed SIGNED, prototype_string STRING >
167inline void copy(SIGNED& s, const STRING& string)
168{
169
170 s = (SIGNED)string_to_signed(string);
171
172}
173
174
175template < prototype_natural NATURAL, prototype_string STRING >
176inline void copy(NATURAL& n, const STRING& string)
177{
178
179 n = (NATURAL)as_u64(string);
180
181}
182
183
184template < prototype_floating FLOATING, prototype_string STRING >
185inline void copy(FLOATING& f, const STRING& string)
186{
187
188 f = (FLOATING)string_to_floating(string);
189
190}
191
192
193template < prototype_string STRING, prototype_floating FLOATING >
194inline STRING& copy(STRING& string, const FLOATING& number)
195{
196
197 string.formatf("%f", (::f64)number);
198
199 return string;
200
201}
202
203
204
205
206
207
208
209
210
211//template < typename TYPE >
212//inline ::string as_string(const TYPE& t)
213//{
214//
215// ::string str;
216//
217// ::copy(str, t);
218//
219// return ::transfer(str);
220//
221//}
222
223
224template < prototype_number NUMBER >
225inline string as_string(NUMBER number, const_char_pointer pszFormat)
226{
227
228 ::string str;
229
230 str.formatf(pszFormat, number);
231
232 return ::transfer(str);
233
234}
235
236
237template < prototype_integral INTEGRAL >
238inline inline_number_string as_string(INTEGRAL i, ::i32 radix, enum_digit_case edigitcase)
239{
240
241 inline_number_string numberstring;
242
243 __tosz(i, numberstring.m_end, radix, edigitcase);
244
245 return numberstring;
246
247}
248
249
250// template < prototype_integral SIGNED >
251// inline inline_number_string as_string(SIGNED i, ::i32 radix, enum_digit_case edigitcase)
252// {
253
254// inline_number_string numberstring;
255
256// __tosz(i, numberstring.m_end, radix, edigitcase);
257
258// return numberstring;
259
260// }
261
262
263// inline_number_string numberstring;
264
265// __i64toansi(i, numberstring, iRadix, edigitcase, numberstring.m_iLength);
266
267// return numberstring;
268
269// }
270
271
272template < prototype_floating FLOATING >
273inline ::string as_string(FLOATING f, const_char_pointer pszFormat)
274{
275
276 ::string str;
277
278 str.formatf(pszFormat, f);
279
280 return str;
281
282}
283
284
285
286template < >
287inline ::hash32 as_hash32 < scoped_ansi_string >(const scoped_ansi_string & scopedstr) {
288
289 return _scoped_string_u32_hash((const ::scoped_string_base<const_char_pointer >&) scopedstr);
290
291}
292
293
294template < >
295inline ::hash32 as_hash32 < scoped_wd16_string >(const scoped_wd16_string & scopedstr) {
296
297 return _scoped_string_u32_hash((const ::scoped_string_base<const ::wd16_character *> &) scopedstr);
298
299}
300
301
302template < >
303inline ::hash32 as_hash32 < scoped_wd32_string >(const scoped_wd32_string & scopedstr) {
304
305 return _scoped_string_u32_hash((const ::scoped_string_base<const ::wd32_character *> &) scopedstr);
306
307}
308
309
310
311
312namespace file
313{
314
315
316 //template < prototype_character_range CHARACTER_RANGE >
317 // inline path::path(const CHARACTER_RANGE & range, enum_path epath, e_type etype, bool bNormalizePath, ::i64 iSize) :
318 // path(::ansi_string(range), epath, etype, bNormalizePath, iSize)
319 // {
320
321
322 // }
323
324
325 inline path& path::operator /= (const ::scoped_string & scopedstr)
326 {
327
328 return *this = (*this / scopedstr);
329
330 }
331
332
333 inline path path::operator * (const ::scoped_string & scopedstr) const
334 {
335
336 return ::transfer(this->sibling(scopedstr));
337
338
339 }
340
341
342 inline path& path::operator *= (const ::scoped_string & scopedstr)
343 {
344
345 this->operator = (::transfer(this->sibling(scopedstr)));
346
347 return *this;
348
349 }
350
351
352 inline bool path::operator == (const ::string & str) const
353 {
354
355 return ::string::operator == (str);
356
357 }
358
359
360 inline bool path::operator != (const ::scoped_string & scopedstr) const
361 {
362
363 return operator != (string(scopedstr));
364
365 }
366
367
368
369
370} // namespace file
371
372
373
374
375
376
377template < typename TYPE, enum_type t_etypeContainer >
378inline void implode(const numeric_array_base < TYPE, t_etypeContainer > & a, string & str, const ::scoped_string & scopedstrSeparator, ::collection::index start, ::collection::count count)
379{
380
381 if(start < 0)
382 {
383 start += a.get_size();
384 }
385 ::collection::index last;
386 if(count < 0)
387 {
388 last = a.get_size() + count;
389 }
390 else
391 {
392 last = start + count - 1;
393 }
394 if(start <= last)
395 {
396
397 ::collection::index i = start;
398
399 ::copy(str, a.element_at(i));
400
401 i++;
402 for(; i <= last; i++)
403 {
404 str += scopedstrSeparator + as_string(a.element_at(i));
405 }
406 }
407 else
408 {
409
410 str.empty();
411
412 }
413
414
415}
416
417
418template < typename TYPE, enum_type t_etypeContainer >
419inline string implode(const numeric_array_base < TYPE, t_etypeContainer > & a,const ::scoped_string & scopedstrSeparator, ::collection::index start, ::collection::count count)
420{
421
422 string str;
423
424 implode(a, str, scopedstrSeparator, start, count);
425
426 return str;
427
428}
429
430
431template < typename TYPE, ::enum_type t_etypeContainer >
432string surround_and_implode(const numeric_array_base < TYPE, t_etypeContainer > & a, const ::scoped_string & scopedstrSeparator, const ::scoped_string & pszPrefix, const ::scoped_string & scopedstrSuffix, ::collection::index iStart, ::collection::count iCount)
433{
434 string str;
435 string strSeparator(scopedstrSeparator);
436 string strPrefix(pszPrefix);
437 string strSuffix(scopedstrSuffix);
438 ::collection::index iEnd;
439 if(iStart < 0)
440 iStart = a.get_size() + iStart;
441 if(iCount < 0)
442 iEnd = a.get_size() + iCount;
443 else
444 iEnd = iStart + iCount - 1;
445 if(iStart <= iEnd)
446 {
447 ::collection::index i = iStart;
448 str = strPrefix + as_string(a.element_at(i)) + strSuffix;
449 i++;
450 for(; i <= iEnd; i++)
451 {
452 str += strSeparator + strPrefix + as_string(a.element_at(i)) + strSuffix;
453 }
454 }
455 return str;
456}
457
458
459
460
461template < typename ITERATOR_TYPE >
462inline bool const_string_range < ITERATOR_TYPE > ::operator==(const ::character_range < const CHARACTER* >& range) const
463{
464
465 return this->equals(range);
466
467}
468
469
470template < typename ITERATOR_TYPE >
471template < typename OTHER_CHARACTER >
472inline bool const_string_range < ITERATOR_TYPE > ::operator==(const ::character_range < const OTHER_CHARACTER* >& range) const
473requires other_primitive_character < OTHER_CHARACTER, CHARACTER >
474{
475 return this->equals(string_base(range));
476
477}
478
479//template < typename ITERATOR_TYPE >
480//inline bool const_string_range < ITERATOR_TYPE > ::operator==(const ::wd32_string &str) const { return this->equals(string_base(str)); }
481
482
483
484template<typename BASE_TYPE>
485::collection::count string_range < BASE_TYPE>::consume(bool(*character_is_function)(CHARACTER character), character_count minimum_count)
486{
487
488 auto c = this->begins_count(character_is_function);
489
490 if (c < minimum_count)
491 {
492
493 throw_parsing_exception("didn't reached minimum count of characters meet character_is_function requirements");
494
495 }
496
497 this->begin() += c;
498
499 return c;
500
501}
502
503
504// Convert the string_base < ITERATOR_TYPE > to lowercase
505template < typename ITERATOR_TYPE >
506string_base < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE > ::lowered() const
507{
508
509 string_base < ITERATOR_TYPE > str(*this);
510
511 str.make_lower();
512
513 return str;
514
515}
516
517
518// Convert the string_base < ITERATOR_TYPE > to uppercase
519template < typename ITERATOR_TYPE >
520string_base < ITERATOR_TYPE > const_string_range < ITERATOR_TYPE > ::uppered() const
521{
522
523 string_base < ITERATOR_TYPE > str(*this);
524
525 str.make_upper();
526
527 return str;
528
529}
530
531
532template < typename ITERATOR_TYPE >
533string_base < ITERATOR_TYPE > string_range < ITERATOR_TYPE > ::consume_quoted_value()
534{
535
536 auto pszStart = this->m_begin;
537
538 if (*pszStart != '\"' && *pszStart != '\'')
539 {
540
541 throw_parsing_exception("Quote character is required here");
542
543 return {};
544
545 }
546
547 string_base <ITERATOR_TYPE> str;
548
549 if (!defer_consume_quoted_value(str))
550 {
551
552 throw_parsing_exception("Quote character is required here, premature end");
553
554 }
555
556 return str;
557
558}
559
560
561template < typename ITERATOR_TYPE >
562bool string_range < ITERATOR_TYPE > ::defer_consume_quoted_value(string_base <ITERATOR_TYPE> & str)
563{
564
565 str.empty();
566
567 auto pszStart = this->m_begin;
568
569 if (*pszStart != '\"' && *pszStart != '\'')
570 {
571
572 return false;
573
574 }
575
576 ::i8 quoting_character = *this->m_begin;
577
578 this->m_begin++;
579
580 const typename ::string_range < ITERATOR_TYPE>::CHARACTER * pszValueStart = this->m_begin;
581
582 while (*this->m_begin != quoting_character)
583 {
584
585 skip:
586
587 this->m_begin = unicode_next(this->m_begin);
588
589 if (this->is_empty() || *this->m_begin == '\0')
590 {
591
592 return false;
593
594 }
595
596 if (*this->m_begin == '\\')
597 {
598
599 this->m_begin = unicode_next(this->m_begin);
600
601 if (this->is_empty())
602 {
603
604 return false;
605
606 }
607
608 goto skip;
609
610 }
611
612 }
613
614 str.assign(pszValueStart, this->m_begin - pszValueStart);
615
616 this->m_begin++;
617
618 auto p = str.get_buffer();
619
620 auto pend = p + str.length();
621
622 while (*p)
623 {
624
625 if (*p == '\\')
626 {
627
628 if (p[1] == '\\')
629 {
630
631 memory_transfer(p, p + 1, pend - p);
632 }
633 else if (p[1] == '\"')
634 {
635
636 memory_transfer(p, p + 1, pend - p);
637
638 }
639
640 }
641
642 p++;
643
644 }
645
646 //str.release_buffer();
647
648 return true;
649
650}
651
652
653
654
655template < >
656inline ::hash32 as_hash32 < ansi_string >(const ansi_string & ansistr)
657{
658
659 return as_hash32 < const ansi_string & >(ansistr);
660
661}
662
663
664template < >
665inline ::hash32 as_hash32 < wide_string >(const wide_string & widestr)
666{
667
668 return as_hash32 < const wide_string & >(widestr);
669
670}
671
672
673template < typename ITERATOR_TYPE >
674void string_range < ITERATOR_TYPE >::consume(const_char_pointer pszToConsume)
675{
676
677 while(*pszToConsume)
678 {
679
680 if (*this->m_begin != *pszToConsume)
681 {
682
683 throw_parsing_exception("Name does not match expected");
684
685 }
686
687 this->m_begin++;
688
689 pszToConsume++;
690
691 }
692
693}
694
695
696template < typename ITERATOR_TYPE >
697bool string_range < ITERATOR_TYPE >::begins_consume(const ::scoped_string & scopedstr)
698{
699
700 if(scopedstr.size() > 0)
701 {
702
703 if (!this->begins(scopedstr))
704 {
705
706 return false;
707
708 }
709
710 // if(this->m_erange & e_range_string)
711 // {
712 //
713 // this->m_erange = (enum_range)(this->m_erange & ~e_range_string);
714 //
715 // }
716
717 this->m_begin += scopedstr.size();
718
719 }
720
721 return true;
722
723}
724
725
726template < typename ITERATOR_TYPE >
727bool string_range < ITERATOR_TYPE >::begins_eat(const ::scoped_string & scopedstr)
728{
729
730 if(scopedstr.size() > 0)
731 {
732
733 if (!this->begins(scopedstr))
734 {
735
736 return false;
737
738 }
739
740 // if(this->m_erange & e_range_string)
741 // {
742 //
743 // this->m_erange = (enum_range)(this->m_erange & ~e_range_string);
744 //
745 // }
746
747 this->m_begin += scopedstr.size();
748
749 }
750
751 return true;
752
753}
754
755
756template < typename ITERATOR_TYPE >
757bool string_range < ITERATOR_TYPE >::ends_eat(const ::scoped_string & scopedstr)
758{
759
760 if(scopedstr.size() > 0)
761 {
762
763 if (!this->ends(scopedstr))
764 {
765
766 return false;
767
768 }
769
770// if(this->m_erange & e_range_string)
771// {
772//
773// this->m_erange = (enum_range)(this->m_erange & ~e_range_string);
774//
775// }
776
777 this->m_end -= scopedstr.size();
778
779 }
780
781 return true;
782
783}
784
785
786
787template < typename ITERATOR_TYPE >
788bool string_range < ITERATOR_TYPE >::case_insensitive_begins_eat(const ::scoped_string & scopedstr)
789{
790
791 if(scopedstr.size() > 0)
792 {
793
794 if (!this->case_insensitive_begins(scopedstr))
795 {
796
797 return false;
798
799 }
800
801// if(this->m_erange & e_range_string)
802// {
803//
804// this->m_erange = (enum_range)(this->m_erange & ~e_range_string);
805//
806// }
807
808 this->m_begin += scopedstr.size();
809
810 }
811
812 return true;
813
814}
815
816
817template < typename ITERATOR_TYPE >
818bool string_range < ITERATOR_TYPE >::case_insensitive_ends_eat(const ::scoped_string & scopedstr)
819{
820
821 if(scopedstr.size() > 0)
822 {
823
824 if (!this->case_insensitive_ends(scopedstr))
825 {
826
827 return false;
828
829 }
830
831// if(this->m_erange & e_range_string)
832// {
833//
834// this->m_erange = (enum_range)(this->m_erange & ~e_range_string);
835//
836// }
837
838 this->m_end -= scopedstr.size();
839
840 }
841
842 return true;
843
844}
845
846
847template < typename ITERATOR_TYPE >
848void string_range < ITERATOR_TYPE >::consume(const ::scoped_string & scopedstr)
849{
850
851 auto rangeToConsume = scopedstr();
852
853 while(rangeToConsume.has_character())
854 {
855
856 if(this->is_empty() || (*this->m_begin != *rangeToConsume.m_begin))
857 {
858
859 throw_parsing_exception("Name does not match expected");
860
861 break;
862
863 }
864
865 rangeToConsume.m_begin++;
866
867 this->m_begin++;
868
869 }
870
871}
872
873
874//template < typename ITERATOR_TYPE >
875//void string_range < ITERATOR_TYPE >::consume_spaces(::collection::count iMinimumCount)
876//{
877//
878// ::i32 i = 0;
879//
880// while (unicode_is_whitespace(this->m_begin))
881// {
882//
883// unicode_increment(this->m_begin);
884//
885// i++;
886//
887// }
888//
889// if (i < iMinimumCount)
890// {
891//
892// throw ::parsing_exception("At least "+ ::as_string(iMinimumCount) + " space(s) is(are) required. Found " + ::as_string(i) + " whitespace(s).");
893//
894// }
895//
896//}
897
898
899//::u64 str::consume_natural(::u64 uMax, ::u64 uMin)
900//{
901//
902// auto u = consume_natural(this->m_begin, uMax, uMin);
903//
904// return u;
905//
906//}
907
908
909template < typename ITERATOR_TYPE >
910::u64 string_range < ITERATOR_TYPE >::consume_natural(::u64 uMax, ::u64 uMin)
911{
912
913 if (uMax < uMin)
914 {
915
916 throw ::exception(error_bad_argument, "maximum should be greater than minimum");
917
918 }
919
920 auto pszStart = this->m_begin;
921
922 ::i32 i = 0;
923
924 ::u64 u;
925
926 while (unicode_is_digit(this->m_begin))
927 {
928
929 this->m_begin = unicode_next(this->m_begin);
930
931 i++;
932
933 }
934
935 if (this->m_begin == pszStart)
936 {
937
938 throw_parsing_exception("empty natural found");
939
940 }
941
942 u = ::as_u32({ pszStart, this->m_begin - pszStart });
943
944 if (u < uMin)
945 {
946
947 throw_parsing_exception("natural less than minimum");
948
949 }
950 else if (u > uMax)
951 {
952
953 throw_parsing_exception("natural greater than maximum");
954
955 }
956
957 return u;
958
959}
960
961//
962//template < typename ITERATOR_TYPE >
963//void string_base < ITERATOR_TYPE >::consume_spaces(::collection::count iMinimumCount)
964//{
965//
966// ::i32 i = 0;
967//
968// while (unicode_is_whitespace(this->m_begin))
969// {
970//
971// unicode_increment(this->m_begin);
972//
973// if (this->m_begin > this->m_end)
974// {
975//
976// throw ::parsing_exception("premature end");
977//
978// break;
979//
980// }
981//
982// i++;
983//
984// }
985//
986// if (i < iMinimumCount)
987// {
988//
989// throw ::parsing_exception("At least " + ::as_string(iMinimumCount) + " space(s) is(are) required");
990//
991// }
992//
993//}
994
995
996//template < typename ITERATOR_TYPE >
997//::string_base < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_non_spaces(const_char_pointer &psz)
998//{
999//
1000// return consume_non_spaces(scopedstr, psz + strlen(scopedstr));
1001//
1002//}
1003//
1004
1005
1006template < typename ITERATOR_TYPE >
1007string_range < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_non_spaces()
1008{
1009
1010 auto pszStart = this->m_begin;
1011
1012 while (!unicode_is_whitespace(this->m_begin))
1013 {
1014
1015 this->m_begin = unicode_next(this->m_begin);
1016
1017 if (this->is_empty())
1018 {
1019
1020 break;
1021
1022 }
1023
1024 }
1025
1026 return { pszStart, this->m_begin - pszStart };
1027
1028}
1029
1030
1031template < typename ITERATOR_TYPE >
1032string_range < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_hex()
1033{
1034
1035 auto pszStart = this->m_begin;
1036
1037 while (this->is_empty())
1038 {
1039
1040 ::i32 len;
1041
1042 ::i64 i = unicode_index_length(this->m_begin, len);
1043
1044 if ((i >= '0' && i <= '9') || (i >= 'a' && i <= 'f') || (i >= 'A' && i <= 'F'))
1045 {
1046
1047 this->m_begin += len;
1048
1049 }
1050 else
1051 {
1052
1053 break;
1054
1055 }
1056
1057 }
1058
1059 if (this->m_begin == pszStart)
1060 {
1061
1062 throw_parsing_exception("no hex consumed");
1063
1064 return {};
1065
1066 }
1067
1068 return { pszStart, this->m_begin - pszStart };
1069
1070}
1071
1072
1073template < typename ITERATOR_TYPE >
1074string_range < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_nc_name()
1075{
1076
1077 auto pszStart = this->m_begin;
1078
1079 if (this->is_empty() || !unicode_is_letter(this->m_begin))
1080 {
1081
1082 throw_parsing_exception("NCName required here");
1083
1084 return {};
1085
1086 }
1087
1088 do
1089 {
1090
1091 this->m_begin = unicode_next(this->m_begin);
1092
1093 } while(this->has_character() &&
1094 (unicode_is_letter_or_digit(this->m_begin)
1095 || *this->m_begin == '_' || *this->m_begin == '-'));
1096
1097 return { pszStart, this->m_begin - pszStart };
1098
1099}
1100
1101
1102//string consume_quoted_value(const_char_pointer &pszParse)
1103//{
1104
1105// ::str::utf8_char utf8char;
1106
1107// auto psz = pszParse;
1108// utf8char.parse(scopedstr); // quote character
1109// if(utf8char.m_chLen != 1)
1110// {
1111// throw ::parsing_exception("Quote character is required here");
1112// return "";
1113// }
1114// ::i8 strUtf8Char = utf8char.m_sz[0];
1115// if(strUtf8Char != '\"' && strUtf8Char != '\\')
1116// {
1117// throw ::parsing_exception("Quote character is required here");
1118// return "";
1119// }
1120// ::i32 iPos = utf8char.m_chLen;
1121// string str;
1122// ::i32 iPosStart = iPos;
1123// while(true)
1124// {
1125// iPos += utf8char.parse(&psz[iPos]);
1126// if(utf8char.m_chLen <= 0)
1127// {
1128// throw ::parsing_exception("Quote character is required here, premature end");
1129// return "";
1130// }
1131// if(utf8char.m_chLen == 1 && utf8char.m_sz[0] == strUtf8Char)
1132// break;
1133
1134// }
1135// str = string(&psz[iPosStart], iPos - iPosStart - 1);
1136// pszParse = &psz[iPos];
1137// return str;
1138//}
1139
1140
1141
1142
1143//template < typename ITERATOR_TYPE >
1144// void string_base < ITERATOR_TYPE >::no_escape_consume_quoted_value(char_pointer * ppsz, character_count & iBufferSize)
1145//{
1146//
1147// const_char_pointer pszStart = this->m_begin;
1148//
1149// if (*pszStart != '\"' && *pszStart != '\\')
1150// {
1151//
1152// throw ::parsing_exception("Quote character is required here");
1153//
1154// return;
1155//
1156// }
1157//
1158// ::i8 quoting_character = *this->m_begin;
1159//
1160// this->m_begin++;
1161//
1162// const_char_pointer pszValueStart = this->m_begin;
1163//
1164// while (*this->m_begin != quoting_character)
1165// {
1166//
1167// unicode_increment(this->m_begin);
1168//
1169// if (this->is_empty())
1170// {
1171//
1172// throw ::parsing_exception("Quote character is required here, premature end");
1173//
1174// return;
1175//
1176// }
1177//
1178// }
1179//
1180// character_count iNewBufferSize = this->m_begin - pszValueStart;
1181//
1182// if (iNewBufferSize > iBufferSize)
1183// {
1184//
1185// *ppsz = (char_pointer )::system()->m_pheapmanagement->memory(::heap::e_memory_main)->allocate(iNewBufferSize + 1);
1186//
1187// }
1188//
1189// ansi_count_copy(*ppsz, pszValueStart, iNewBufferSize);
1190//
1191// (*ppsz)[iNewBufferSize] = '\0';
1192//
1193// iBufferSize = iNewBufferSize;
1194//
1195// this->m_begin++;
1196//
1197//}
1198
1199
1200template < typename ITERATOR_TYPE >
1201string_base<ITERATOR_TYPE> string_range < ITERATOR_TYPE >::no_escape_consume_quoted_value()
1202{
1203
1204 const_char_pointer pszStart = this->m_begin;
1205
1206 no_escape_skip_quoted_value();
1207
1208 return { pszStart + 1, this->m_begin - pszStart - 2 };
1209
1210}
1211
1212
1213template < typename ITERATOR_TYPE >
1214void string_range < ITERATOR_TYPE >::no_escape_skip_quoted_value()
1215{
1216
1217 if (*this->m_begin != '\"' && *this->m_begin != '\\')
1218 {
1219
1220 throw_parsing_exception("Quote character is required here");
1221
1222 return;
1223
1224 }
1225
1226 ::i8 quoting_character = *this->m_begin;
1227
1228 this->m_begin++;
1229
1230 while (*this->m_begin != quoting_character)
1231 {
1232
1233 this->m_begin = unicode_next(this->m_begin);
1234
1235 if (this->is_empty())
1236 {
1237
1238 throw_parsing_exception("Quote character is required here, premature end");
1239
1240 return;
1241
1242 }
1243
1244 }
1245
1246 this->m_begin++;
1247
1248}
1249
1250
1251template < typename ITERATOR_TYPE >
1252string_base<ITERATOR_TYPE> string_range < ITERATOR_TYPE >::consume_quoted_value_ex()
1253{
1254
1256
1257 this->_consume_quoted_value_ex<true>(&str);
1258
1259 return str;
1260
1261}
1262
1263
1264template < typename ITERATOR_TYPE >
1265void string_range < ITERATOR_TYPE >::skip_quoted_value_ex()
1266{
1267
1268 this->_consume_quoted_value_ex<false>(nullptr);
1269
1270}
1271
1272
1273template < typename ITERATOR_TYPE >
1274string_range < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_spaced_value()
1275{
1276
1277 this->consume_spaces(0);
1278
1279 if (this->is_empty())
1280 {
1281
1282 return {};
1283
1284 }
1285
1286 auto pszStart = this->m_begin;
1287
1288 while (this->has_character() && !ansi_char_isspace(*this->m_begin))
1289 {
1290
1291 this->m_begin++;
1292
1293 }
1294
1295 if (this->m_begin == pszStart)
1296 {
1297
1298 throw_parsing_exception("No spaced value to consumer");
1299
1300 }
1301
1302 return { pszStart, this->m_begin - pszStart };
1303
1304}
1305
1306
1307//template < typename ITERATOR_TYPE >
1308//::string_base < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_spaced_value(const_char_pointer &psz)
1309//{
1310//
1311// string str(scopedstr);
1312//
1313// character_count iOldLen = str.length();
1314//
1315// string strResult = consume_spaced_value(str);
1316//
1317// psz += iOldLen - str.length();
1318//
1319// return strResult;
1320//
1321//}
1322
1323//template < typename ITERATOR_TYPE >
1324//::string_base < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_spaced_value(const_char_pointer &psz, const_char_pointer pszEnd)
1325//{
1326//
1327// string str(scopedstr, pszEnd - psz);
1328//
1329// character_count iOldLen = str.length();
1330//
1331// string strResult = consume_spaced_value(str);
1332//
1333// psz += iOldLen - str.length();
1334//
1335// return strResult;
1336//
1337//}
1338
1339
1340template < typename ITERATOR_TYPE >
1341string_base<ITERATOR_TYPE> string_range < ITERATOR_TYPE >::consume_command_line_argument()
1342{
1343
1344 this->consume_spaces(0);
1345
1346 if (*this->m_begin == '\"' || *this->m_begin == '\'')
1347 {
1348
1349 return this->consume_quoted_value();
1350
1351 }
1352 else
1353 {
1354
1355 return this->consume_spaced_value();
1356
1357 }
1358
1359}
1360
1361
1362template < typename ITERATOR_TYPE >
1363void string_range < ITERATOR_TYPE >::consume_until_any_character_in(const ::scoped_string & scopedstr)
1364{
1365
1366 this->m_begin = this->find_first_character_in(scopedstr);
1367
1368 if (not_found(this->m_begin))
1369 {
1370
1371 throw_parsing_exception("Not found any character in \"" + scopedstr + "\"");
1372
1373 }
1374
1375}
1376
1377
1378//template < typename ITERATOR_TYPE >
1379//::string_base < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_command_line_argument(const_char_pointer &psz)
1380//{
1381//
1382// string str(scopedstr);
1383//
1384// character_count iOldLen = str.length();
1385//
1386// string strResult = consume_command_line_argument(str);
1387//
1388// psz += iOldLen - str.length();
1389//
1390// return strResult;
1391//
1392//}
1393//
1394//template < typename ITERATOR_TYPE >
1395//::string_base < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_command_line_argument(const_char_pointer &psz, const_char_pointer pszEnd)
1396//{
1397//
1398// string str(scopedstr, pszEnd - psz);
1399//
1400// character_count iOldLen = str.length();
1401//
1402// string strResult = consume_command_line_argument(str);
1403//
1404// psz += iOldLen - str.length();
1405//
1406// return strResult;
1407//
1408//}
1409
1410
1411template < typename ITERATOR_TYPE >
1412string_base<ITERATOR_TYPE> string_range < ITERATOR_TYPE >::consume_c_quoted_value()
1413{
1414
1415 //auto pszStart = this->m_begin;
1416
1417 if (*this->m_begin != '\"' && *this->m_begin != '\\')
1418 {
1419
1420 throw_parsing_exception("Quote character is required here");
1421
1422 return "";
1423
1424 }
1425
1426 auto quoting_character = this->consume_utf8_char();
1427
1428 STRING_RANGE rangeCurrentChar;
1429
1430 STRING_BASE str;
1431
1432 STRING_RANGE rangePreviousChar;
1433
1434 while (this->has_character())
1435 {
1436
1437// unicode_increment(this->m_begin);
1438
1439 rangePreviousChar = rangeCurrentChar;
1440
1441 rangeCurrentChar = this->consume_utf8_char();
1442
1443 //string str = utf8_to_unicode(qc2);
1444
1445 if (rangeCurrentChar.is_empty())
1446 {
1447
1448 throw_parsing_exception("Quote character is required here, premature end");
1449
1450 return "";
1451
1452 }
1453
1454 if (rangePreviousChar == "\\")
1455 {
1456
1457 str += rangeCurrentChar;
1458
1459 rangeCurrentChar.m_begin = nullptr;
1460 rangeCurrentChar.m_end = nullptr;
1461
1462 }
1463 else if (rangeCurrentChar == "\\")
1464 {
1465
1466 }
1467 else
1468 {
1469
1470 if (rangeCurrentChar == quoting_character)
1471 {
1472
1473 break;
1474
1475 }
1476
1477 str += rangeCurrentChar;
1478
1479 }
1480
1481 }
1482
1483 this->consume_utf8_char();
1484 //unicode_increment(this->m_begin);
1485
1486 return str;
1487
1488}
1489
1490
1491template < typename ITERATOR_TYPE >
1492template < bool bWriteOutput >
1493void string_range < ITERATOR_TYPE >::_consume_quoted_value_ex(string_base<ITERATOR_TYPE>* pstrOut)
1494{
1495
1496 ::i8 quoting_character = *this->m_begin;
1497
1498 if (quoting_character != '\"' && quoting_character != '\'')
1499 {
1500
1501 throw_parsing_exception("Quote character is required here, premature end");
1502
1503 return;
1504
1505 }
1506
1507 this->m_begin++;
1508
1509 const_char_pointer pszNext = this->m_begin;
1510
1511 while (true)
1512 {
1513
1514 pszNext = unicode_next(this->m_begin);
1515
1516 if (pszNext > this->m_end)
1517 {
1518
1519 throw_parsing_exception("Quote character is required here, premature end");
1520
1521 if (bWriteOutput)
1522 {
1523
1524 *pstrOut = "";
1525
1526 }
1527
1528 }
1529
1530 if (*this->m_begin == '\0')
1531 {
1532
1533 throw_parsing_exception("Quote character is required here, premature end");
1534
1535 if (bWriteOutput)
1536 {
1537
1538 *pstrOut = "";
1539
1540 }
1541
1542 }
1543 else if (*this->m_begin == quoting_character)
1544 {
1545
1546 this->m_begin++;
1547
1548 break;
1549
1550 }
1551 else if (*this->m_begin == '\\')
1552 {
1553
1554 this->m_begin = pszNext;
1555
1556 pszNext = unicode_next(this->m_begin);
1557
1558 if (pszNext > this->m_end)
1559 {
1560
1561 throw_parsing_exception("Quote character is required here, premature end");
1562
1563 if (bWriteOutput)
1564 {
1565
1566 *pstrOut = "";
1567
1568 }
1569
1570 }
1571
1572 if (*this->m_begin == 'n')
1573 {
1574
1575 if (bWriteOutput)
1576 {
1577
1578 pstrOut->append_character('\n');
1579
1580 }
1581
1582 }
1583 else if (*this->m_begin == 't')
1584 {
1585
1586 if (bWriteOutput)
1587 {
1588
1589 pstrOut->append_character('\t');
1590
1591 }
1592
1593 }
1594 else if (*this->m_begin == 'r')
1595 {
1596
1597 if (bWriteOutput)
1598 {
1599
1600 pstrOut->append_character('\r');
1601
1602 }
1603
1604 }
1605 else if (*this->m_begin == 'u')
1606 {
1607
1608 this->m_begin++;
1609
1610 ::u16 u16a[2];
1611
1612 u16a[0] = ::hex::parse_u16_exc(*this);
1613
1614 if (utf16_is_1st_surrogate(u16a[0]))
1615 {
1616
1617 if (*this->m_begin != '\\')
1618 {
1619
1620 throw_parsing_exception("expect back slash here (for low surrogate)");
1621
1622 }
1623
1624 this->m_begin++;
1625
1626 if (*this->m_begin != 'u' && *this->m_begin != 'U')
1627 {
1628
1629 throw_parsing_exception("expect 'u' character here (for low surrogate)");
1630
1631 }
1632
1633 this->m_begin++;
1634
1635 u16a[1] = ::hex::parse_u16_exc(*this);
1636
1637 if (!utf16_is_2nd_surrogate(u16a[1]))
1638 {
1639
1640 throw_parsing_exception("expect low surrogate");
1641
1642 }
1643 else
1644 {
1645
1646 if (bWriteOutput)
1647 {
1648
1649 ::wd32_character uni = (::wd32_character)decode_utf16_pair(u16a);
1650
1651 string strUtf8 = wd32_to_ansi_str(&uni, 1);
1652
1653 pstrOut->append(strUtf8);
1654
1655 }
1656
1657 }
1658
1659 }
1660 else
1661 {
1662
1663 if (bWriteOutput)
1664 {
1665
1666 ::wd32_character uni = u16a[0];
1667
1668 string strUtf8 = wd32_to_ansi_str(&uni, 1);
1669
1670 pstrOut->append(strUtf8);
1671
1672 }
1673
1674 }
1675
1676 pszNext = this->m_begin;
1677
1678 }
1679 else if (*this->m_begin == '\"')
1680 {
1681
1682 if (bWriteOutput)
1683 {
1684
1685 pstrOut->append_character('\"');
1686
1687 }
1688
1689 }
1690 else
1691 {
1692
1693 if (bWriteOutput)
1694 {
1695
1696 pstrOut->append(this->m_begin, pszNext - this->m_begin);
1697
1698 }
1699
1700 }
1701
1702 }
1703 else
1704 {
1705
1706 if (bWriteOutput)
1707 {
1708
1709 pstrOut->append(this->m_begin, pszNext - this->m_begin);
1710
1711 }
1712
1713 }
1714
1715 this->m_begin = pszNext;
1716
1717 }
1718
1719}
1720
1721
1722
1723
1724template < typename ITERATOR_TYPE >
1725string_range < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::xml_consume_comment()
1726{
1727
1728 this->consume("<!--");
1729
1730 auto pszStart = this->m_begin;
1731
1732 while (this->m_begin[0] != '-' || this->m_begin[1] != '-' || this->m_begin[2] != '>')
1733 {
1734
1735 if (this->is_empty() || *this->m_begin == '\0')
1736 {
1737
1738 break;
1739
1740 }
1741
1742 this->m_begin = unicode_next(this->m_begin);
1743
1744 }
1745
1746 this->m_begin += 3;
1747
1748 return { pszStart, this->m_begin - pszStart - 3 };
1749
1750}
1751
1752
1753
1754//========================================================
1755// Name : _tcsechr
1756// Desc : similar with strchr with escape process
1757// Param : escape - will be escape character
1758// Return :
1759//--------------------------------------------------------
1760// Coder Date Desc
1761// bro 2002-10-29
1762//========================================================
1763template < typename ITERATOR_TYPE >
1765{
1766
1767 while (this->has_character() && *this->m_begin)
1768 {
1769
1770 if (escape != 0 && *this->m_begin == escape)
1771 this->m_begin++;
1772 else
1773 if (*this->m_begin == ch)
1774 return;
1775 this->m_begin++;
1776 }
1777 //return pch;
1778}
1779
1780
1781//========================================================
1782 // Name : _tcsepbrk
1783 // Desc : similar with ansi_scan with escape process
1784 // Param : escape - will be escape character
1785 // Return :
1786 //--------------------------------------------------------
1787 // Coder Date Desc
1788 // bro 2002-10-29
1789 //========================================================
1790//========================================================
1791 // Name : _tcsepbrk
1792 // Desc : similar with ansi_scan with escape process
1793 // Param : escape - will be escape character
1794 // Return :
1795 //--------------------------------------------------------
1796 // Coder Date Desc
1797 // bro 2002-10-29
1798 //========================================================
1799template < typename ITERATOR_TYPE >
1801{
1802
1803 const_char_pointer prev_escape = nullptr;
1804
1805 while (this->has_character() && *this->m_begin)
1806 {
1807
1808 if (escape != 0 && *this->m_begin == escape && prev_escape == nullptr)
1809 {
1810
1811 prev_escape = this->m_begin;
1812
1813 }
1814 else
1815 {
1816
1817 prev_escape = nullptr;
1818
1819 if (ansi_chr(chset, *this->m_begin))
1820 {
1821 return;
1822
1823 }
1824
1825 }
1826
1827 this->m_begin++;
1828
1829 }
1830
1831}
1832
1833//========================================================
1834// Name : _tcsenistr
1835// Desc : similar with _tcsistr with escape process
1836// Param : escape - will be escape character
1837// Return :
1838//--------------------------------------------------------
1839// Coder Date Desc
1840// bro 2002-10-29
1841//========================================================
1842template < typename ITERATOR_TYPE >
1843void string_range < ITERATOR_TYPE >::escape_case_insensitive_skip_to(const ::scoped_string & scopedstr, ::i32 escape)
1844{
1845
1846 const_char_pointer prev_escape = nullptr;
1847
1848 while (this->has_character() && *this->m_begin)
1849 {
1850
1851 if (escape != 0 && *this->m_begin == escape && prev_escape == nullptr)
1852 {
1853
1854 prev_escape = this->m_begin;
1855
1856 }
1857 else
1858 {
1859
1860 prev_escape = nullptr;
1861
1862 if (this->escape_case_insensitive_count_order(scopedstr, escape) == 0)
1863 {
1864
1865 return;
1866
1867 }
1868
1869 }
1870
1871 this->m_begin++;
1872
1873 }
1874
1875}
1876
1877
1878
1879
1880//========================================================
1881// Name : _tcsecpy
1882// Desc : similar with _tcscpy with escape process
1883// Param : escape - will be escape character
1884// Return :
1885//--------------------------------------------------------
1886// Coder Date Desc
1887// bro 2002-10-29
1888//========================================================
1889template < typename ITERATOR_TYPE >
1890void mutable_string_range < ITERATOR_TYPE >::escape_copy(::i8 escape, const ::const_ansi_range & rangeSource)
1891{
1892
1893 auto pTarget = this->m_begin;
1894
1895 auto pSource = rangeSource.m_begin;
1896
1897 bool bEscaping = false;
1898
1899 while(pSource < rangeSource.m_end && pTarget < this->m_end)
1900 {
1901
1902 if(bEscaping)
1903 {
1904
1905 bEscaping = false;
1906
1907 *pTarget++ = *pSource;
1908
1909 }
1910 else if(*pSource == escape)
1911 {
1912
1913 bEscaping = true;
1914
1915 }
1916 else
1917 {
1918
1919 *pTarget++ = *pSource;
1920
1921 }
1922
1923 pSource++;
1924
1925 }
1926
1927 *pTarget = '\0';
1928
1929 this->m_end = pTarget;
1930
1931}
1932
1933
1934
1935
1936template < typename ITERATOR_TYPE >
1937string_range < ITERATOR_TYPE > string_range < ITERATOR_TYPE >::consume_utf8_char()
1938{
1939
1940 auto pszStart = this->m_begin;
1941
1942 this->m_begin = unicode_next(pszStart);
1943
1944 return { pszStart, minimum(this->m_begin, this->m_end) };
1945
1946}
1947
1948
1949
1950// // template < typename FILE >
1951template < typename T >
1952inline void write_text_stream::print_string_copy(const T & t)
1953{
1954
1955 ::string str;
1956
1957 ::copy(str, t);
1958
1959 print(str);
1960
1961}
1962
1963
1964// // template < typename FILE >
1965template < prototype_character CHARACTER2, character_count sizeMaximumLength >
1966inline write_text_stream & write_text_stream::operator <<(const ::inline_string < CHARACTER2, sizeMaximumLength > & inlinestring)
1967{
1968
1969 if (this->fmtflags() & ::file::network_payload)
1970 {
1971
1972 print("\""_ansi);
1973
1974 }
1975
1976 write(inlinestring.data(), inlinestring.size());
1977
1978 if (this->fmtflags() & ::file::network_payload)
1979 {
1980
1981 print("\""_ansi);
1982
1983 }
1984
1985 if (this->fmtflags() & ::file::separated)
1986 {
1987
1988 print(m_chSeparator);
1989
1990 }
1991
1992 return *this;
1993
1994}
1995
Definition aaa_character.h:10
::std::strong_ordering escape_case_insensitive_count_order(const ::scoped_string &scopedstr, ::i32 escape) const
Definition _impl_const_string_range.h:195
Definition path.h:52
Definition fixed_alloc.h:125
void escape_copy(::i8 escape, const ::const_ansi_range &rangeSource)
Definition _impl.h:1890
Definition range.h:223
Definition string_base.h:90
void escape_skip_to_character(::i32 ch, ::i32 escape)
Definition _impl.h:1764
void escape_case_insensitive_skip_to(const ::scoped_string &scopedstr, ::i32 escape)
Definition _impl.h:1843
void escape_skip_to_first_character_in(const_char_pointer chset, ::i32 escape)
Definition _impl.h:1800
Definition write_text_stream.h:43
Definition filesystem.h:16