1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2007, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexey Krivonogov ( gentee )
11 *
12 ******************************************************************************/
13
14 /*-----------------------------------------------------------------------------
15 * Id: string L "String"
16 *
17 * Summary: Strings. It is possible to use variables of the #b(str) type for
18 working with strings. The #b(str) type is inherited from the #b(buf) type.
19 So, you can also use #a(buffer, methods of the buf type).
20 *
21 * List: *Operators,str_oplen,str_opsum,str_opeq,str_opadd,str_opeqeq,
22 str_opless,str_opgr,str_types2str,str_str2types,
23 *Methods,str_append,str_appendch,str_clear,str_copy,str_crc,str_del,
24 str_dellast,str_eqlen,str_fill,str_find,
25 str_hex,str_insert,str_islast,str_lines,str_lower,str_out4,str_print,
26 str_printf,str_read,str_repeat,
27 str_replace,str_replacech,str_setlen,str_split,str_substr,str_trim,
28 str_upper,str_write,str_writeappend,
29 *Search methods,spattern,spattern_init,spattern_search,str_search
30 *
31 -----------------------------------------------------------------------------*/
32
33 define
34 {
35 CH_APOSTR = 0x27
36 }
37
38
39 define <export>{
40 /*-----------------------------------------------------------------------------
41 * Id: trimflags D
42 *
43 * Summary: Flags for str.trim method.
44 *
45 -----------------------------------------------------------------------------*/
46 TRIM_LEFT = 0x0001 // Trim the left side.
47 TRIM_RIGHT = 0x0002 // Trim the right side.
48 TRIM_ONE = 0x0004 // Delete only one character.
49 TRIM_PAIR = 0x0008 // If the character being deleted is a bracket, /
50 // look the closing bracket on the right
51 TRIM_SYS = 0x0010 // Delete characters less or equal space.
52
53 /*-----------------------------------------------------------------------------
54 * Id: fillflags D
55 *
56 * Summary: Flags for str.fill method.
57 *
58 -----------------------------------------------------------------------------*/
59 FILL_LEFT = 0x01 // Filling on the left side.
60 FILL_LEN = 0x02 // The count parameter contains the final string size.
61 FILL_CUT = 0x04 // Cut if longer than the final size. Used together /
62 // with FILL_LEN.
63
64 //-----------------------------------------------------------------------------
65 }
66
67 /*-----------------------------------------------------------------------------
68 * Id: str_opsum F4
69 *
70 * Summary: Putting two strings together and creating a resulting string.
71 *
72 * Return: The new result string.
73 *
74 -----------------------------------------------------------------------------*/
75
76 operator str +<result>( str left, str right )
77 {
78 ( result = left ) += right
79 }
80
81 /*-----------------------------------------------------------------------------
82 * Id: str_opeqeq F4
83 *
84 * Summary: Comparison operation.
85 *
86 * Return: Returns #b(1) if the strings are equal. Otherwise, it returns #b(0).
87 *
88 -----------------------------------------------------------------------------*/
89
90 operator uint ==( str left, str right )
91 {
92 if *left != *right : return 0
93 return !strcmp( left.ptr(), right.ptr() )
94 }
95
96 /*-----------------------------------------------------------------------------
97 * Id: str_opeqeq_1 FC
98 *
99 * Summary: Comparison operation.
100 *
101 * Title: str != str
102 *
103 * Return: Returns #b(0) if the strings are equal. Otherwise, it returns #b(1).
104 *
105 * Define: operator uint !=( str left, str right )
106 *
107 -----------------------------------------------------------------------------*/
108
109 /*-----------------------------------------------------------------------------
110 * Id: str_opeqeq_2 FC
111 *
112 * Summary: Comparison operation with ignore case.
113 *
114 * Return: Returns #b(1) if the strings are equal with ignore case.
115 Otherwise, it returns #b(0).
116 *
117 -----------------------------------------------------------------------------*/
118
119 operator uint %==( str left, str right )
120 {
121 if *left != *right : return 0
122 return !strcmpign( left.ptr(), right.ptr())
123 }
124
125 /*-----------------------------------------------------------------------------
126 * Id: str_opeqeq_3 FC
127 *
128 * Summary: Comparison operation with ignore case.
129 *
130 * Title: str %!= str
131 *
132 * Return: Returns #b(0) if the strings are equal with ignore case.
133 Otherwise, it returns #b(1).
134 *
135 * Define: operator uint %!=( str left, str right )
136 *
137 -----------------------------------------------------------------------------*/
138
139 /*-----------------------------------------------------------------------------
140 * Id: str_opless F4
141 *
142 * Summary: Comparison operation.
143 *
144 * Title: str < str
145 *
146 * Return: Returns #b(1) if the first string is less than the second one.
147 Otherwise, it returns #b(0).
148 *
149 -----------------------------------------------------------------------------*/
150
151 operator uint <( str left, str right )
152 {
153 if strcmp( left.ptr(), right.ptr() ) < 0 : return 1
154 return 0
155 }
156
157 /*-----------------------------------------------------------------------------
158 * Id: str_opless_1 FC
159 *
160 * Summary: Comparison operation.
161 *
162 * Title: str <= str
163 *
164 * Return: Returns #b(1) if the first string is less or equal the second one.
165 Otherwise, it returns #b(0).
166 *
167 * Define: operator uint <=( str left, str right )
168 *
169 -----------------------------------------------------------------------------*/
170
171 /*-----------------------------------------------------------------------------
172 * Id: str_opless_2 FC
173 *
174 * Summary: Comparison operation with ignore case.
175 *
176 * Title: str %< str
177 *
178 * Return: Returns #b(1) if the first string is less than the second one with
179 ignore case. Otherwise, it returns #b(0).
180 *
181 -----------------------------------------------------------------------------*/
182
183 operator uint %<( str left, str right )
184 {
185 if strcmpign( left.ptr(), right.ptr()) < 0 : return 1
186 return 0
187 }
188
189 /*-----------------------------------------------------------------------------
190 * Id: str_opless_3 FC
191 *
192 * Summary: Comparison operation with ignore case.
193 *
194 * Title: str %<= str
195 *
196 * Return: Returns #b(1) if the first string is less or equal the second one
197 with ignore case. Otherwise, it returns #b(0).
198 *
199 * Define: operator uint %<=( str left, str right )
200 *
201 -----------------------------------------------------------------------------*/
202
203 /*-----------------------------------------------------------------------------
204 * Id: str_opgr F4
205 *
206 * Summary: Comparison operation.
207 *
208 * Title: str > str
209 *
210 * Return: Returns #b(1) if the first string is greater than the second one.
211 Otherwise, it returns #b(0).
212 *
213 -----------------------------------------------------------------------------*/
214
215 operator uint >( str left, str right )
216 {
217 if strcmp( left.ptr(), right.ptr() ) > 0 : return 1
218 return 0
219 }
220
221 /*-----------------------------------------------------------------------------
222 * Id: str_opgr_1 FC
223 *
224 * Summary: Comparison operation.
225 *
226 * Title: str >= str
227 *
228 * Return: Returns #b(1) if the first string is greater or equal the second one.
229 Otherwise, it returns #b(0).
230 *
231 * Define: operator uint >=( str left, str right )
232 *
233 -----------------------------------------------------------------------------*/
234
235 /*-----------------------------------------------------------------------------
236 * Id: str_opgr_2 FC
237 *
238 * Summary: Comparison operation with ignore case.
239 *
240 * Title: str %> str
241 *
242 * Return: Returns #b(1) if the first string is greater than the second one
243 with ignore case. Otherwise, it returns #b(0).
244 *
245 -----------------------------------------------------------------------------*/
246
247 operator uint %>( str left, str right )
248 {
249 if strcmpign( left.ptr(), right.ptr() ) > 0 : return 1
250 return 0
251 }
252
253 /*-----------------------------------------------------------------------------
254 * Id: str_opgr_3 FC
255 *
256 * Summary: Comparison operation with ignore case.
257 *
258 * Title: str %>= str
259 *
260 * Return: Returns #b(1) if the first string is greater or equal the second one
261 with ignore case. Otherwise, it returns #b(0).
262 *
263 * Define: operator uint %>=( str left, str right )
264 *
265 -----------------------------------------------------------------------------*/
266
267 /*-----------------------------------------------------------------------------
268 * Id: str_types2str F3
269 *
270 * Summary: Converting types to str. Convert #b(int) to #b(str) =>
271 #b('str( int )').
272 *
273 * Title: str( type )
274 *
275 * Return: The result string.
276 *
277 -----------------------------------------------------------------------------*/
278
279 method str int.str < result >
280 {
281 result.out4( "%i", this )
282 }
283
284 /*-----------------------------------------------------------------------------
285 * Id: str_types2str_1 FB
286 *
287 * Summary: Convert #b(uint) to #b(str) => #b('str( uint )').
288 *
289 * Title: str( uint )
290 *
291 -----------------------------------------------------------------------------*/
292
293 method str uint.str < result >
294 {
295 result.out4( "%u", this )
296 }
297
298 /*-----------------------------------------------------------------------------
299 * Id: str_types2str_2 FB
300 *
301 * Summary: Convert #b(float) to #b(str) => #b('str( float )').
302 *
303 * Title: str( float )
304 *
305 -----------------------------------------------------------------------------*/
306
307 method str float.str <result>
308 {
309 double tmp = double(this)
310 result.out8( "%f", (&tmp)->ulong )
311 }
312
313 /*-----------------------------------------------------------------------------
314 * Id: str_types2str_3 FB
315 *
316 * Summary: Convert #b(long) to #b(str) => #b('str( long )').
317 *
318 * Title: str( long )
319 *
320 -----------------------------------------------------------------------------*/
321
322 method str long.str <result>
323 {
324 result.out8( "%I64i", this )
325 }
326
327 /*-----------------------------------------------------------------------------
328 * Id: str_types2str_4 FB
329 *
330 * Summary: Convert #b(ulong) to #b(str) => #b('str( ulong )').
331 *
332 * Title: str( ulong )
333 *
334 -----------------------------------------------------------------------------*/
335
336 method str ulong.str<result>
337 {
338 result.out8( "%I64u", this )
339 }
340
341 /*-----------------------------------------------------------------------------
342 * Id: str_types2str_5 FB
343 *
344 * Summary: Convert #b(double) to #b(str) => #b('str( double )').
345 *
346 * Title: str( double )
347 *
348 -----------------------------------------------------------------------------*/
349
350 method str double.str <result>
351 {
352 result.out8( "%g", (&this)->ulong )
353 }
354
355 /*-----------------------------------------------------------------------------
356 * Id: str_opadd_2 FC
357 *
358 * Summary: Append #b(int) to #b(str) => #b( str += int ).
359 *
360 -----------------------------------------------------------------------------*/
361
362 operator str +=( str left, int val )
363 {
364 return left.out4( "%i", val )
365 }
366
367 /*-----------------------------------------------------------------------------
368 * Id: str_opadd_3 FC
369 *
370 * Summary: Append #b(float) to #b(str) => #b( str += float ).
371 *
372 -----------------------------------------------------------------------------*/
373
374 operator str +=( str left, float val )
375 {
376 double tmp = double(val)
377 return left.out8( "%f", (&tmp)->ulong )
378 }
379
380 /*-----------------------------------------------------------------------------
381 * Id: str_opadd_4 FC
382 *
383 * Summary: Append #b(long) to #b(str) => #b( str += long ).
384 *
385 -----------------------------------------------------------------------------*/
386
387 operator str +=( str left, long val )
388 {
389 return left.out8( "%I64i", val )
390 }
391
392 /*-----------------------------------------------------------------------------
393 * Id: str_opadd_5 FC
394 *
395 * Summary: Append #b(ulong) to #b(str) => #b( str += ulong ).
396 *
397 -----------------------------------------------------------------------------*/
398
399 operator str +=( str left, ulong val )
400 {
401 return left.out8( "%I64u", val )
402 }
403
404 /*-----------------------------------------------------------------------------
405 * Id: str_opadd_6 FC
406 *
407 * Summary: Append #b(double) to #b(str) => #b( str += double ).
408 *
409 -----------------------------------------------------------------------------*/
410
411 operator str +=( str left, double val )
412 {
413 return left.out8( "%g", (&val)->ulong )
414 }
415
416 /*-----------------------------------------------------------------------------
417 * Id: str_str2types F3
418 *
419 * Summary: Converting string to other types. Convert #b(str) to #b(int) =>
420 #b('int( str )').
421 *
422 * Title: type( str )
423 *
424 * Return: The result value of the according type.
425 *
426 -----------------------------------------------------------------------------*/
427
428 method int str.int
429 {
430 uint end start
431
432 while this[ start ] == '0' && this[ start + 1 ] != 'x' &&
433 this[ start + 1 ] != 'X' : start++
434 return strtol( this.ptr() + start, &end, 0 )
435 }
436
437 /*-----------------------------------------------------------------------------
438 * Id: str_str2types_1 FB
439 *
440 * Summary: Convert #b(str) to #b(uint) => #b('uint( str )').
441 *
442 * Title: uint( str )
443 *
444 -----------------------------------------------------------------------------*/
445
446 method uint str.uint
447 {
448 uint end start
449
450 while this[ start ] == '0' && this[ start + 1 ] != 'x' &&
451 this[ start + 1 ] != 'X' : start++
452
453 return strtoul( this.ptr() + start, &end, 0 )
454 }
455
456 /*-----------------------------------------------------------------------------
457 * Id: str_str2types_2 FB
458 *
459 * Summary: Convert #b(str) to #b(float) => #b('float( str )').
460 *
461 * Title: float( str )
462 *
463 -----------------------------------------------------------------------------*/
464
465 method float str.float
466 {
467 return float( atof( this.ptr() ))
468 }
469
470 /*-----------------------------------------------------------------------------
471 * Id: str_str2types_3 FB
472 *
473 * Summary: Convert #b(str) to #b(long) => #b('long( str )').
474 *
475 * Title: long( str )
476 *
477 -----------------------------------------------------------------------------*/
478
479 method long str.long
480 {
481 return atoi64( this.ptr())
482 }
483
484 /*-----------------------------------------------------------------------------
485 * Id: str_str2types_4 FB
486 *
487 * Summary: Convert #b(str) to #b(double) => #b('double( str )').
488 *
489 * Title: double( str )
490 *
491 -----------------------------------------------------------------------------*/
492
493 method double str.double
494 {
495 return atof( this.ptr())
496 }
497
498 /*-----------------------------------------------------------------------------
499 * Id: str_hex F2
500 *
501 * Summary: Converting an unsigned integer in the hexadecimal form. Lower characters.
502 *
503 * Title: str.hex...
504 *
505 * Params: val - The unsigned integer value to be converted into the string.
506 *
507 * Return: #lng/retobj#
508 *
509 -----------------------------------------------------------------------------*/
510
511 method str str.hexl( uint val )
512 {
513 return this.out4( "%x", val )
514 }
515
516 /*-----------------------------------------------------------------------------
517 * Id: str_hex_1 F8
518 *
519 * Summary: Converting an unsigned integer in the hexadecimal form.
520 ( upper characters ).
521 *
522 * Params: val - The unsigned integer value to be converted into the string.
523 *
524 * Return: #lng/retobj#
525 *
526 -----------------------------------------------------------------------------*/
527
528 method str str.hexu( uint val )
529 {
530 return this.out4( "%X", val )
531 }
532
533 /*-----------------------------------------------------------------------------
534 * Id: str_hex_2 F8
535 *
536 * Summary: Converting an unsigned integer in the hexadecimal form.
537 ( lower characters ).
538 *
539 * Params: val - The unsigned integer value to be converted into the string.
540 *
541 * Return: The new result string.
542 *
543 -----------------------------------------------------------------------------*/
544
545 func str hex2strl<result>( uint val )
546 {
547 result.out4( "%x", val )
548 }
549
550 /*-----------------------------------------------------------------------------
551 * Id: str_hex_3 F8
552 *
553 * Summary: Converting an unsigned integer in the hexadecimal form.
554 ( upper characters ).
555 *
556 * Params: val - The unsigned integer value to be converted into the string.
557 *
558 * Return: The new result string.
559 *
560 -----------------------------------------------------------------------------*/
561
562 func str hex2stru<result>( uint val )
563 {
564 result.out4( "%X", val )
565 }
566
567 /*-----------------------------------------------------------------------------
568 * Id: str_appendch F2
569 *
570 * Summary: Adding a character to a string.
571 *
572 * Params: ch - The character to be added.
573 *
574 * Return: #lng/retobj#
575 *
576 -----------------------------------------------------------------------------*/
577
578 method str str.appendch( uint ch )
579 {
580 this[ *this ] = ch
581 this->buf += byte( 0 )
582
583 return this
584 }
585
586 /*-----------------------------------------------------------------------------
587 * Id: str_del F2
588 *
589 * Summary: Delete a substring.
590 *
591 * Params: off - The offset of the substring being deleted.
592 len - The size of the substring being deleted.
593 *
594 * Return: #lng/retobj#
595 *
596 -----------------------------------------------------------------------------*/
597
598 method str str.del( uint off, uint len )
599 {
600 uint slen = this->buf.use - 1
601
602 if off > slen : return this
603 if off + len > slen : len = slen - off
604 this->buf.del( off, len )
605
606 this[ this->buf.use - 1 ] = 0
607
608 return this
609 }
610
611 /*-----------------------------------------------------------------------------
612 * Id: str_find_2 FA
613 *
614 * Summary: Find the character from the end of the string.
615 *
616 * Params: symbol - Search character.
617 *
618 -----------------------------------------------------------------------------*/
619
620 method uint str.findchr( uint symbol )
621 {
622 return this.findch( 0, symbol, 1 )
623 }
624
625 /*-----------------------------------------------------------------------------
626 * Id: str_find_3 FA
627 *
628 * Summary: Find the character from the specified offset in the string.
629 *
630 * Params: symbol - Search character.
631 offset - The offset to start searching from.
632 *
633 -----------------------------------------------------------------------------*/
634
635 method uint str.findchfrom( uint symbol, uint offset )
636 {
637 return this.findch( offset, symbol, 0 )
638 }
639
640 /*-----------------------------------------------------------------------------
641 * Id: str_find_4 FA
642 *
643 * Summary: Find the #b[#glt(i)] character in the string.
644 *
645 * Params: symbol - Search character.
646 i - The number of the character starting from 1.
647 *
648 -----------------------------------------------------------------------------*/
649
650 method uint str.findchnum( uint symbol, uint i )
651 {
652 uint cur
653 uint end = *this
654
655 while i && cur < end
656 {
657 i--
658 cur = this.findch( cur, symbol, 0 )
659 if cur < end && i : cur++
660 }
661 return cur
662 }
663
664 /*-----------------------------------------------------------------------------
665 * Id: str_substr_1 FA
666 *
667 * Summary: Get a substring. The result substring will be written over the
668 existing string.
669 *
670 * Params: off - Substring offset.
671 len - Substring size.
672 *
673 -----------------------------------------------------------------------------*/
674
675 method str str.substr( uint off, uint len )
676 {
677 return this.substr( this, off, len )
678 }
679
680 func uint trimsys( uint ptr len )
681 {
682 uint end = ptr + len->uint
683
684 while ptr->ubyte <= ' ' && ptr < end : ptr++
685 while ( end - 1 )->ubyte <= ' ' && ptr < end : end--
686
687 len->uint = end - ptr
688
689 return ptr
690 }
691
692 /*-----------------------------------------------------------------------------
693 * Id: str_trim F3
694 *
695 * Summary: Trimming a string. Deleting spaces and special characters on both
696 sides.
697 *
698 * Title: str.trim...
699 *
700 * Return: #lng/retobj#
701 *
702 -----------------------------------------------------------------------------*/
703
704 method str str.trimsys()
705 {
706 uint len = *this
707 uint ptr
708
709 ptr = trimsys( this.ptr(), &len )
710 if len != *this : this.substr( this, ptr - this.ptr(), len )
711 return this
712 }
713
714 /*-----------------------------------------------------------------------------
715 * Id: str_trim_1 FB
716 *
717 * Summary: Deleting spaces and special characters on the right.
718 *
719 -----------------------------------------------------------------------------*/
720
721 method str str.trimrsys()
722 {
723 uint ptr = this.ptr()
724 uint end = ptr + *this
725
726 while ( end - 1 )->ubyte <= ' ' && ptr < end : end--
727
728 this.setlen( end - ptr )
729 return this
730 }
731
732 /*method str str.oem2char
733 {
734 OemToCharBuff( this.ptr(), this.ptr(), *this )
735 return this
736 }
737
738 method str str.char2oem
739 {
740 CharToOemBuff( this.ptr(), this.ptr(), *this )
741 return this
742 }*/
743
744 /*-----------------------------------------------------------------------------
745 * Id: str_clear F3
746 *
747 * Summary: Clearing a string.
748 *
749 * Return: #lng/retobj#
750 *
751 -----------------------------------------------------------------------------*/
752
753 method str str.clear()
754 {
755 return this.setlen( 0 )
756 }
757
758 /*-----------------------------------------------------------------------------
759 * Id: str_replace F2
760 *
761 * Summary: Replacing in a string. The method replaces data in a string.
762 *
763 * Params: offset - The offset of the data being replaced.
764 size - The size of the data being replaced.
765 value - The string being inserted.
766 *
767 * Return: #lng/retobj#
768 *
769 -----------------------------------------------------------------------------*/
770
771 method str str.replace( uint offset, uint size, str value )
772 {
773 if offset >= *this : this += value
774 else
775 {
776 value->buf.use--
777 this->buf.replace( offset, size, value->buf )
778 value->buf.use++
779 }
780 return this
781 }
782
783 /*-----------------------------------------------------------------------------
784 * Id: str_insert F2
785 *
786 * Summary: Insertion. The method inserts one string into another.
787 *
788 * Params: offset - The offset where string will be inserted.
789 value - The string being inserted.
790 *
791 * Return: #lng/retobj#
792 *
793 -----------------------------------------------------------------------------*/
794
795 method str str.insert( uint offset, str value )
796 {
797 return this.replace( offset, 0, value )
798 }
799
800 /*-----------------------------------------------------------------------------
801 * Id: str_fill F2
802 *
803 * Summary: Filling a string. Fill a string to the left or to the right.
804 *
805 * Title: str.fill...
806 *
807 * Params: val - The string that will be filled.
808 count - The number of additions.
809 flag - Flags. $$[fillflags]
810 *
811 * Return: #lng/retobj#
812 *
813 -----------------------------------------------------------------------------*/
814
815 method str str.fill( str val, uint count, uint flag )
816 {
817 uint len
818 uint elen
819 str ret
820
821 elen = ?( flag & $FILL_LEN, count, *this + count * *val )
822 len = ?( elen < *this, 0, elen - *this )
823 while *ret < len : ret += val
824 ret.setlen( len )
825
826 if len
827 {
828 if flag & $FILL_LEFT : this.insert( 0, ret )
829 else : this += ret
830 }
831 if flag & $FILL_CUT && elen < *this : this.setlen( elen )
832 return this
833 }
834
835 /*-----------------------------------------------------------------------------
836 * Id: str_fill_1 FA
837 *
838 * Summary: Fill a string with spaces to the left.
839 *
840 * Params: len - Final string size.
841 *
842 -----------------------------------------------------------------------------*/
843
844 method str str.fillspacel( uint len )
845 {
846 return this.fill( " ", len, $FILL_LEFT | $FILL_LEN )
847 }
848
849 /*-----------------------------------------------------------------------------
850 * Id: str_fill_2 FA
851 *
852 * Summary: Fill a string with spaces to the right.
853 *
854 * Params: len - Final string size.
855 *
856 -----------------------------------------------------------------------------*/
857
858 method str str.fillspacer( uint len )
859 {
860 return this.fill( " ", len, $FILL_LEN )
861 }
862
863 /*-----------------------------------------------------------------------------
864 * Id: str_repeat F2
865 *
866 * Summary: Repeating a string. Repeat a string the specified number of times.
867 *
868 * Params: count - The number of repeatitions. The result will be written /
869 into this very string.
870 *
871 * Return: #lng/retobj#
872 *
873 -----------------------------------------------------------------------------*/
874
875 method str str.repeat( uint count )
876 {
877 str pat = this
878 return this.fill( pat, count * *pat, $FILL_CUT | $FILL_LEN )
879 }
880
881 /*-----------------------------------------------------------------------------
882 * Id: str_setlen_1 FB
883 *
884 * Summary: Recalculate the size of a string to the zero character. The
885 function can be used to determine the size of a string after
886 other functions write data into it.
887 *
888 -----------------------------------------------------------------------------*/
889
890 method str str.setlenptr()
891 {
892 return this.setlen( mlen( this.ptr()))
893 }
894
895 /*-----------------------------------------------------------------------------
896 * Id: str_crc F3
897 *
898 * Summary: Calculating the checksum. The method calculates the checksum of a
899 string.
900 *
901 * Return: The string checksum is returned.
902 *
903 -----------------------------------------------------------------------------*/
904
905 method uint str.crc()
906 {
907 return crc( this.ptr(), *this, 0xFFFFFFFF )
908 }
909
910 /*-----------------------------------------------------------------------------
911 * Id: str_lower F3
912 *
913 * Summary: Converting to lowercase. The method converts characters in
914 a string to lowercase.
915 *
916 * Return: #lng/retobj#
917 *
918 -----------------------------------------------------------------------------*/
919
920 method str str.lower()
921 {
922 CharLowerBuff( this.ptr(), *this )
923 return this
924 }
925
926 /*-----------------------------------------------------------------------------
927 * Id: str_lower_1 FA
928 *
929 * Summary: Convert a substring in the specified string to lowercase.
930 *
931 * Params: off - Substring offset.
932 size - Substring size.
933 *
934 -----------------------------------------------------------------------------*/
935
936 method str str.lower( uint off, uint size )
937 {
938 off = min( off, *this - 1 )
939 size = min( size, *this - off )
940
941 CharLowerBuff( this.ptr() + off, size )
942 return this
943 }
944
945 /*-----------------------------------------------------------------------------
946 * Id: str_upper F3
947 *
948 * Summary: Converting to uppercase. The method converts characters in a string
949 to uppercase.
950 *
951 * Return: #lng/retobj#
952 *
953 -----------------------------------------------------------------------------*/
954
955 method str str.upper()
956 {
957 CharUpperBuff( this.ptr(), *this )
958 return this
959 }
960
961 /*-----------------------------------------------------------------------------
962 * Id: str_upper_1 FA
963 *
964 * Summary: Convert a substring in the specified string to uppercase.
965 *
966 * Params: off - Substring offset.
967 size - Substring size.
968 *
969 -----------------------------------------------------------------------------*/
970
971 method str str.upper( uint off, uint size )
972 {
973 off = min( off, *this - 1 )
974 size = min( size, *this - off )
975
976 CharUpperBuff( this.ptr() + off, size )
977 return this
978 }
979
980 /*-----------------------------------------------------------------------------
981 * Id: str_islast F2
982 *
983 * Summary: Check the final character.
984 *
985 * Params: symbol - The character being checked.
986 *
987 * Return: Returns 1 if the last character in the string coincides with the
988 specified one and 0 otherwise.
989 *
990 -----------------------------------------------------------------------------*/
991
992 method uint str.islast( uint symbol )
993 {
994 if !*this : return 0
995
996 if gentee_ptr(0)->_gentee.multib
997 {
998 return this.findchr( symbol ) == *this - 1
999 }
1000
1001 return this[ *this - 1 ] == symbol
1002 }
1003
1004 /*-----------------------------------------------------------------------------
1005 * Id: str_trim_2 FA
1006 *
1007 * Summary: Delete the specified character on either sides of a string.
1008 *
1009 * Params: symbol - The character being deleted.
1010 flag - Flags. $$[trimflags]
1011 *
1012 -----------------------------------------------------------------------------*/
1013
1014 method str str.trim( uint symbol, uint flag )
1015 {
1016 uint rsymbol = symbol
1017
1018 if flag & $TRIM_PAIR
1019 {
1020 switch symbol
1021 {
1022 case '(' : rsymbol = ')'
1023 case '{' : rsymbol = '}'
1024 case '[' : rsymbol = ']'
1025 case '<' : rsymbol = '>'
1026 }
1027 }
1028 if flag & $TRIM_RIGHT
1029 {
1030 while this.islast( rsymbol )
1031 {
1032 this.setlen( *this - 1 )
1033 if flag & $TRIM_ONE : break
1034 }
1035 }
1036 if flag & $TRIM_LEFT
1037 {
1038 uint cur = this.ptr()
1039 uint end = cur + *this
1040
1041 while cur < end && cur->ubyte == symbol
1042 {
1043 cur++
1044 if flag & $TRIM_ONE : break
1045 }
1046 if cur != this.ptr() : this.del( 0, cur - this.ptr())
1047 }
1048
1049 return this;
1050 }
1051
1052 /*-----------------------------------------------------------------------------
1053 * Id: str_trim_3 FB
1054 *
1055 * Summary: Deleting spaces on the right.
1056 *
1057 -----------------------------------------------------------------------------*/
1058
1059 method str str.trimrspace()
1060 {
1061 return this.trim( ' ', $TRIM_RIGHT )
1062 }
1063
1064 /*-----------------------------------------------------------------------------
1065 * Id: str_trim_4 FB
1066 *
1067 * Summary: Deleting spaces on the both sides.
1068 *
1069 -----------------------------------------------------------------------------*/
1070
1071 method str str.trimspace()
1072 {
1073 return this.trim( ' ', $TRIM_RIGHT | $TRIM_LEFT )
1074 }
1075
1076 /*-----------------------------------------------------------------------------
1077 * Id: str_eqlen F2
1078 *
1079 * Summary: Comparison. Compare a string with the specified data.
1080 The comparison is carried out only at the length of the string
1081 the method is called for.
1082 *
1083 * Title: str.eqlen...
1084 *
1085 * Params: ptr - The pointer to the data to be compared.
1086 *
1087 * Return: Returns 1 if there is an equality and 0 otherwise.
1088 *
1089 -----------------------------------------------------------------------------*/
1090
1091 method uint str.eqlen( uint ptr )
1092 {
1093 return !strcmplen( this->buf.data, ptr, this->buf.use - 1 )
1094 }
1095
1096 /*-----------------------------------------------------------------------------
1097 * Id: str_eqlen_1 FA
1098 *
1099 * Summary: Compare a string with the specified data.
1100 The comparison is carried out only at the length of the string
1101 the method is called for.
1102 *
1103 * Params: ptr - The pointer to the data to be compared. The comparison is /
1104 case-insensitive.
1105 *
1106 -----------------------------------------------------------------------------*/
1107
1108 method uint str.eqlenign( uint ptr )
1109 {
1110 uint res = !strcmpignlen( this->buf.data, ptr, this->buf.use - 1 )
1111 // print( "\(res )\n" )
1112 return res
1113 //return !strcmpignlen( this->buf.data, ptr, this->buf.use - 1 )
1114 }
1115
1116 /*-----------------------------------------------------------------------------
1117 * Id: str_eqlen_2 FA
1118 *
1119 * Summary: Compare a string with the specified string.
1120 The comparison is carried out only at the length of the string
1121 the method is called for.
1122 *
1123 * Params: src - The string to be compared.
1124 *
1125 -----------------------------------------------------------------------------*/
1126
1127 method uint str.eqlen( str src )
1128 {
1129 return this.eqlen( src.ptr())
1130 }
1131
1132 /*-----------------------------------------------------------------------------
1133 * Id: str_eqlen_3 FA
1134 *
1135 * Summary: Compare a string with the specified string.
1136 The comparison is carried out only at the length of the string
1137 the method is called for.
1138 *
1139 * Params: src - The string to be compared. The comparison is case-insensitive.
1140 *
1141 -----------------------------------------------------------------------------*/
1142
1143 method uint str.eqlenign( str src )
1144 {
1145 return this.eqlenign( src.ptr())
1146 }
1147
1148 /*-----------------------------------------------------------------------------
1149 * Id: str_append F2
1150 *
1151 * Summary: Data addition. Add data to a string.
1152 *
1153 * Params: src - The pointer to the data to be added.
1154 size - The size of the data being added.
1155 *
1156 * Return: #lng/retobj#
1157 *
1158 -----------------------------------------------------------------------------*/
1159
1160 method str str.append( uint src, uint size )
1161 {
1162 if size
1163 {
1164 this->buf.use--
1165 this->buf.append( src, size )
1166 this->buf += byte( 0 )
1167 }
1168 return this
1169 }
1170
1171 /*method str str.quote( uint ch )
1172 {
1173 str stemp
1174
1175 if this[0] == ch && this.islast( ch ) : return this
1176
1177 char2str( stemp, ch )
1178 this.insert( 0, stemp )
1179 return this.appendch( ch )
1180 }*/
1181
1182 /*-----------------------------------------------------------------------------
1183 * Id: str_replacech F2
1184 *
1185 * Summary: Replace a character. The method copies a source string with the
1186 replacing a character to a string.
1187 *
1188 * Params: src - Initial string.
1189 from - A character to be replaced.
1190 to - A string for replacing.
1191 *
1192 * Return: #lng/retobj#
1193 *
1194 -----------------------------------------------------------------------------*/
1195
1196 method str str.replacech( str src, uint from, str to )
1197 {
1198 uint i
1199
1200 this.clear()
1201 fornum i, *src
1202 {
1203 if src[ i ] == from
1204 {
1205 this += to
1206 }
1207 else : this.appendch( src[i] )
1208 }
1209 return this
1210 }
1211
1212 /*-----------------------------------------------------------------------------
1213 * Id: str_read F2
1214 *
1215 * Summary: Read a string from a file.
1216 *
1217 * Params: filename - Filename.
1218 *
1219 * Return: The size of the read data.
1220 *
1221 -----------------------------------------------------------------------------*/
1222
1223 method uint str.read( str filename )
1224 {
1225 uint len = this->buf.read( filename )
1226 this.setlen( len )
1227 return len
1228 }
1229
1230 /*-----------------------------------------------------------------------------
1231 * Id: str_write F2
1232 *
1233 * Summary: Writing a string to a file.
1234 *
1235 * Params: filename - The name of the file for writing. If the file already /
1236 exists, it will be overwritten.
1237 *
1238 * Return: The size of the written data.
1239 *
1240 -----------------------------------------------------------------------------*/
1241
1242 method uint str.write( str filename )
1243 {
1244 uint wr
1245
1246 this->buf.use--
1247 wr = this->buf.write( filename )
1248 this->buf.use++
1249 return wr
1250 }
1251
1252 /*-----------------------------------------------------------------------------
1253 * Id: str_writeappend F2
1254 *
1255 * Summary: Appending string to a file. The method appends a string to the
1256 specified file.
1257 *
1258 * Params: filename - Filename.
1259 *
1260 * Return: The size of the written data.
1261 *
1262 -----------------------------------------------------------------------------*/
1263
1264 method uint str.writeappend( str filename )
1265 {
1266 uint wr
1267
1268 this->buf.use--
1269 wr = this->buf.writeappend( filename )
1270 this->buf.use++
1271 return wr
1272 }
1273
1274 /*-----------------------------------------------------------------------------
1275 * Id: str_copy_1 FA
1276 *
1277 * Summary: The method copies data into a string.
1278 *
1279 * Params: src - The pointer to the data being copied. If data does not end /
1280 in a zero, it will be added automatically.
1281 size - The size of the data being copied.
1282 *
1283 -----------------------------------------------------------------------------*/
1284
1285 method str str.copy( uint src, uint size )
1286 {
1287 this->buf.copy( src, size )
1288 this->buf += ubyte(0)
1289 return this
1290 }
1291
1292 /*-----------------------------------------------------------------------------
1293 * Id: str_dellast F2
1294 *
1295 * Summary: Delete the last character. The method deletes the last character if
1296 it is equal the specified parameter.
1297 *
1298 * Params: ch - A character to be checked.
1299 *
1300 * Return: #lng/retobj#
1301 *
1302 -----------------------------------------------------------------------------*/
1303
1304 method str str.dellast( uint ch )
1305 {
1306 if .islast( ch ) : .setlen( *this - 1 )
1307 return this
1308 }
1309
1310 /*-----------------------------------------------------------------------------
1311 ** Id: str_split_2 FA
1312 *
1313 * Summary: The method looks for the first #i(symbol) and splits a string
1314 into two parts.
1315 *
1316 * Params: symbol - Separator.
1317 left - The substring left on the #i(symbol).
1318 right - The substring right on the #i(symbol).
1319 *
1320 * Return: Returns 1 if the separator has been found. Otherwise, return 0.
1321 *
1322 -----------------------------------------------------------------------------*/
1323
1324 method uint str.split( uint symbol, str left, str right )
1325 {
1326 uint off
1327
1328 right.clear()
1329 if ( off = this.findch( symbol )) < *this
1330 {
1331 left.substr( this, 0, off )
1332 right.substr( this, off + 1, *this - off - 1 )
1333 }
1334 else : left = this
1335 return *right > 0
1336 }
1337
1338 /*Тип str является встроенным
1339 Cтруктура str включена в компилятор
1340 type str < index = byte inherit = buf>{
1341 }
1342 В компилятор включены следующее методы и операции:
1343 str str.init() скрыт
1344 str str.load( uint ptr, uint size )
1345 str str.copy( uint ptr )
1346 str str.findch( uint off symbol fromend )
1347 str str.findch( uint symbol )
1348 uint str.fwildcard( str mask )
1349 str.print()
1350 str str.setlen( uint )
1351 str str.substr( str uint off len )
1352 str = str
1353 str += str
1354 str += uint
1355 *str
1356 str.out4( str format, uint value )
1357 str.out8( str format, ulong value )
1358 */
1359