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: Alexander Krivonogov ( gentee )
11 *
12 ******************************************************************************/
13
14 /*-----------------------------------------------------------------------------
15 * Id: arrustr L "Array Of Unicode Strings"
16 *
17 * Summary: Array of unicode strings. You can use variables of the #b(arrustr)
18 type for working with arrays of unicode strings. The #b(arrustr) type is
19 inherited from the #b(arr) type. So, you can also use
20 #a(array, methods of the arr type).
21 *
22 * List: *Operators,arrustr_opeq,arrustr_opeqa,arrustr_opadd,
23 *Methods,arrustr_insert,arrustr_load,arrustr_read,arrustr_setmultiustr,
24 arrustr_sort,arrustr_unite,arrustr_write,
25 *@Related Methods,buf_getmultiustr,ustr_lines,ustr_split,
26 *Type,tarrustr
27 *
28 -----------------------------------------------------------------------------*/
29
30 /*-----------------------------------------------------------------------------
31 * Id: tarrustr T arrustr
32 *
33 * Summary: The main structure of array of unicode strings.
34 *
35 -----------------------------------------------------------------------------*/
36
37 type arrustr <inherit=arr index=ustr>
38 {
39 }
40
41 //-----------------------------------------------------------------------------
42 /*method arrstr.oftype( uint ctype )
43 {
44 return
45 }*/
46
47 method arrustr.init()
48 {
49 this->arr.oftype( ustr )
50 }
51
52 /*-----------------------------------------------------------------------------
53 * Id: ustr_split F2
54 *
55 * Summary: Splitting a unicode string. The method splits a string into
56 substrings taking into account the specified separator.
57 *
58 * Params: ret - The result array of unicode strings.
59 symbol - Separator.
60 flag - Flags. $$[splitflags]
61 *
62 * Return: The result array of strings.
63 *
64 -----------------------------------------------------------------------------*/
65
66 method arrustr ustr.split( arrustr ret, ushort symbol, uint flag )
67 {
68 uint cur = this.ptr()
69 uint end = cur + (*this<<1)
70 uint found
71 uint i ptr len
72 uint search
73 // Очищаем массив
74 if !( flag & $ASTR_APPEND ) : ret.clear()
75 while ( cur <= end )
76 {
77 search = symbol
78
79 if flag & $SPLIT_QUOTE
80 {
81 ptr = cur
82 while ptr->ushort && ptr->ushort <= 0x0020 : ptr+=2
83 if ptr->ushort == 0x0022 || ptr->ushort == $CH_APOSTR
84 {
85 search = ptr->ushort
86 cur = ptr + 2
87 }
88 }
89 if !( flag & $SPLIT_FIRST ) || !*ret || search != symbol
90 {
91 found = this.findch( (cur - this.ptr())>>1, search ) + (( this.ptr() - cur )>>1)
92 }
93 else : found = (end - cur)>>1
94 ptr = cur
95 len = found
96 /*if len
97 {
98 if flag & $SPLIT_NOSYS : ptr = trimsys( ptr, &len )
99 elif flag & $ASTR_LINES :
100 } */
101 if len || flag & $SPLIT_EMPTY
102 {
103 uint i as ret[ ret.expand( 1 ) ]
104 i.copy( ptr, len<<1 )
105 i.setlen( len )
106 if flag & $SPLIT_NOSYS : i.trim( 0, $TRIM_SYS | $TRIM_RIGHT )
107 elif flag & $ASTR_LINES : i.trim( 0x000D, $TRIM_RIGHT )
108 /*i as ret[ ret.expand( 1 ) ]
109 i.copy( ptr, len + 1 )
110 i.setlen( len )*/
111 }
112 cur += ((found + 1)<<1)
113 if search != symbol
114 {
115 while cur < end && cur->ushort <= 0x0020 : cur+=2
116 if cur->ubyte == symbol : cur+=2
117 }
118 }
119 return ret
120 }
121
122 /*-----------------------------------------------------------------------------
123 * Id: ustr_split_1 FA
124 *
125 * Summary: The method splits a unicode string into the new result array of
126 unicode strings.
127 *
128 * Params: symbol - Separator.
129 flag - Flags. $$[splitflags]
130 *
131 * Return: The new result array of unicode strings.
132 *
133 -----------------------------------------------------------------------------*/
134
135 method arrustr ustr.split <result> ( uint symbol, uint flag )
136 {
137 this.split( result, symbol, flag )
138 }
139
140 /*-----------------------------------------------------------------------------
141 * Id: ustr_lines F2
142 *
143 * Summary: Convert a multi-line unicode string to an array of
144 unicode strings.
145 *
146 * Params: ret - The result array of unicode strings.
147 flag - Flags. $$[splitflags]
148 *
149 * Return: The result array of unicode strings.
150 *
151 -----------------------------------------------------------------------------*/
152
153 method arrustr ustr.lines( arrustr ret, uint flag )
154 {
155 return this.split( ret, 0x000A, flag | $ASTR_LINES )
156 /*uint i = *this
157
158 if !( flag & $ASTR_APPEND ) : ret.clear()
159
160 this.split( ret, 0x000A, 0 )
161 fornum i, *ret
162 {
163 if flag & $ASTR_TRIM : ret[i].trimsys()
164 else : ret[i].dellast( 0x000D )
165 }*/
166 }
167
168 /*-----------------------------------------------------------------------------
169 * Id: ustr_lines_1 FA
170 *
171 * Summary: Convert a multi-line unicode string to an array of unicode strings.
172 *
173 * Params: trim - Specify 1 if you want to trim all characters less or /
174 equal space in lines.
175 *
176 * Return: The new result array of unicode strings.
177 *
178 -----------------------------------------------------------------------------*/
179
180 method arrustr ustr.lines<result>( uint trim )
181 {
182 this.lines( result, trim )
183 }
184
185 /*-----------------------------------------------------------------------------
186 * Id: ustr_lines_2 FA
187 *
188 * Summary: Convert a multi-line unicode string to an array of unicode
189 strings.
190 *
191 * Params: ret - The result array of strings.
192 *
193 -----------------------------------------------------------------------------*/
194
195 method arrustr ustr.lines( arrustr ret )
196 {
197 return this.lines( ret, 0 )
198 }
199
200 /*-----------------------------------------------------------------------------
201 * Id: ustr_lines_3 FB
202 *
203 * Summary: Convert a multi-line unicode string to an array of unicode
204 strings.
205 *
206 * Return: The new result array of unicode strings.
207 *
208 -----------------------------------------------------------------------------*/
209
210 method arrustr ustr.lines<result>()
211 {
212 this.lines( result, 0 )
213 }
214
215 /*-----------------------------------------------------------------------------
216 * Id: arrustr_load F2
217 *
218 * Summary: Add lines to the array of unicode strings from multi-line unicode
219 string.
220 *
221 * Params: input - The input unicode string.
222 flag - Flags. $$[astrloadflags]
223 *
224 * Return: #lng/retobj#.
225 *
226 -----------------------------------------------------------------------------*/
227
228 method arrustr arrustr.load( ustr input, uint flag )
229 {
230 return input.lines( this, flag )
231 }
232
233 /*-----------------------------------------------------------------------------
234 * Id: arrustr_load_1 FA
235 *
236 * Summary: Add lines to the array of unicode strings from multi-line unicode
237 string with trimming.
238 *
239 * Params: input - The input unicode string.
240 *
241 -----------------------------------------------------------------------------*/
242
243 method arrustr arrustr.loadtrim( ustr input )
244 {
245 return input.lines( this, $ASTR_TRIM )
246 }
247
248 /*-----------------------------------------------------------------------------
249 * Id: arrustr_opeq F4
250 *
251 * Summary: Convert types to the array of unicode strings.
252 Convert a multi-line unicode string to an array of unicode strings.
253 *
254 * Title: arrustr = type
255 *
256 * Return: The array of unicode strings.
257 *
258 -----------------------------------------------------------------------------*/
259
260 operator arrustr =( arrustr dest, ustr src )
261 {
262 src.lines( dest, 0 )
263 return dest
264 }
265
266 /*-----------------------------------------------------------------------------
267 * Id: arrustr_unite F2
268 *
269 * Summary: Unite unicode strings of the array. The method unites all items of
270 the array to a unicode string with the specified separator string.
271 *
272 * Title: arrustr.unite...
273 *
274 * Params: dest - The result unicode string.
275 separ - A separator of the strings.
276 *
277 * Return: The result unicode string.
278 *
279 -----------------------------------------------------------------------------*/
280
281 method ustr arrustr.unite( ustr dest, ustr separ )
282 {
283 uint i
284 fornum i, *this
285 {
286 if i: dest@separ
287 dest@this[i]
288 }
289 return dest
290 }
291
292 /*
293 method ustr arrustr.unite<result>( ustr splitter )
294 {
295 this.unite( result )
296 }
297 */
298 /*-----------------------------------------------------------------------------
299 * Id: arrustr_unite_1 FA
300 *
301 * Summary: The method unites items of the array to a multi-line unicode string.
302 It inserts new-line characters between the each string of the array.
303 *
304 * Params: dest - The result unicode string.
305 *
306 -----------------------------------------------------------------------------*/
307
308 method ustr arrustr.unitelines( ustr dest )
309 {
310 return this.unite( dest, ustr("\l") )
311 }
312
313 /*
314 method ustr arrustr.unitelines<result>()
315 {
316 this.unite( result, ustr("\l") )
317 }*/
318
319 /*-----------------------------------------------------------------------------
320 * Id: arrustr_opeqa F4
321 *
322 * Summary: Convert an array of unicode strings to a multi-line unicode string.
323 *
324 * Return: The result string.
325 *
326 -----------------------------------------------------------------------------*/
327
328 operator ustr =( ustr dest, arrustr src )
329 {
330 return src.unitelines( dest )
331 }
332
333 /*-----------------------------------------------------------------------------
334 * Id: arrustr_read F2
335 *
336 * Summary: Read a multi-line text file to array of unicode strings.
337 *
338 * Params: filename - The filename.
339 *
340 * Return: #lng/retf#
341 *
342 -----------------------------------------------------------------------------*/
343
344 method uint arrustr.read( str filename )
345 {
346 ustr sfile
347
348 if sfile.read( filename )
349 {
350 sfile.lines( this, 0 )
351 return 1
352 }
353 return 0
354
355 }
356
357 /*-----------------------------------------------------------------------------
358 * Id: arrustr_write F2
359 *
360 * Summary: Write an array of unicode strings to a multi-line text file.
361 *
362 * Params: filename - The filename.
363 *
364 * Return: The size of written data.
365 *
366 -----------------------------------------------------------------------------*/
367
368 method uint arrustr.write( str filename )
369 {
370 ustr sfile
371 uint i
372 fornum i, *this
373 {
374 if i: sfile@"\l"
375 sfile@this[i]
376 }
377 return sfile.write( filename )
378 }
379
380 /*-----------------------------------------------------------------------------
381 * Id: arrustr_insert F2
382 *
383 * Summary: Insert a unicode string to an array of unicode strings.
384 *
385 * Params: index - The index of the item where the string will be inserted.
386 newstr - The inserting unicode string.
387 *
388 * Return: #lng/retobj#
389 *
390 -----------------------------------------------------------------------------*/
391
392 method arrustr arrustr.insert( uint index, ustr newstr )
393 {
394 this->arr.insert( index )
395 this[ index ] = newstr
396 return this
397 }
398
399
400 method arrustr arrustr.append( ustr newstr )
401 {
402 .insert( *this, newstr )
403 return this
404 }
405
406 method arrustr arrustr.append( arrustr src )
407 {
408 uint i, j
409 j = this.expand( *src )
410 fornum i, *src
411 {
412 this[j++] = src[i]
413 }
414 return this
415 }
416
417 /*-----------------------------------------------------------------------------
418 * Id: arrustr_opeq_1 FC
419 *
420 * Summary: Copy one array of unicode strings to another array of unicode
421 strings.
422 *
423 -----------------------------------------------------------------------------*/
424
425 operator arrustr =( arrustr dest, arrustr src )
426 {
427 uint i
428 dest.clear()
429 dest.expand( *src )
430 fornum i, *src
431 {
432 dest[i] = src[i]
433 }
434 return dest
435 }
436
437 /*-----------------------------------------------------------------------------
438 * Id: arrustr_opadd F4
439 *
440 * Summary: Append types to an array of unicode strings. The operator appends a
441 unicode string at the end of the array of unicode strings.
442 *
443 * Title: arrustr += type
444 *
445 * Return: #lng/retobj#
446 *
447 -----------------------------------------------------------------------------*/
448
449 operator arrustr +=( arrustr dest, ustr newstr )
450 {
451 return dest.append( newstr )
452 }
453
454 /*-----------------------------------------------------------------------------
455 * Id: arrustr_opadd_1 FC
456 *
457 * Summary: The operator appends one array of unicode strings to another array
458 of unicode strings.
459 *
460 -----------------------------------------------------------------------------*/
461
462 operator arrustr +=( arrustr dest, arrustr src )
463 {
464 return dest.append( src )
465 }
466 /*
467 //поменять местами
468 method arrustr.exchange( uint curpos, newpos )
469 {
470 ustr tmp
471 curpos = min( curpos, *this )
472 newpos = min( newpos, *this )
473
474 tmp = this[newpos]
475 this[newpos] = this[curpos]
476 this[curpos] = tmp
477 }
478 */
479 /*-----------------------------------------------------------------------------
480 * Id: arrustr_opeq_2 FC
481 *
482 * Summary: Copy a collection of strings (simple or unicode) to the array of
483 unicode strings.
484 *
485 -----------------------------------------------------------------------------*/
486
487 operator arrustr =( arrustr left, collection right )
488 {
489 uint i
490 fornum i=0, *right
491 {
492 if right.gettype(i) == ustr
493 {
494 left += right[i]->ustr
495 }
496 elif right.gettype(i) == str
497 {
498 left += right[i]->str
499 }
500 }
501 return left
502 }
503
504 /*-----------------------------------------------------------------------------
505 * Id: buf_getmultiustr F2
506 *
507 * Summary: Convert a buffer to array of unicode strings. Load the array of
508 string from
509 multi-string buffer where strings are divided by zero character.
510 *
511 * Params: ret - The result array of unicode strings.
512 *
513 * Return: The result array of unicode strings.
514 *
515 -----------------------------------------------------------------------------*/
516
517 method arrustr buf.getmultiustr( arrustr ret )
518 {
519 uint endl end
520 uint start
521 uint curstr
522
523 ret.clear()
524 end = ( *this >> 1 ) - 1
525
526 while start < end
527 {
528 endl = this.findsh( start, 0 )
529 //if start == endl: break
530 curstr as ret[ ret.expand( 1 ) ]
531 curstr->buf.copy( this.ptr() + ( start << 1 ),
532 ( endl - start + 1 ) << 1/* - 1*/ )
533 start = endl + 1
534 }
535 return ret
536 }
537
538 /*method arrustr buf.getmultiustr( arrustr ret )
539 {
540 this.getmultiustr( ret )
541 return ret
542 }
543
544 method arrustr buf.getmultiustr<result>( )
545 {
546 this.getmultiustr( result )
547 }*/
548
549 /*-----------------------------------------------------------------------------
550 * Id: arrustr_setmultiustr F2
551 *
552 * Summary: Create a multi-string buffer. The method writes unicode strings to
553 a buffer.
554 *
555 * Params: dest - The result buffer.
556 *
557 * Return: The result buffer.
558 *
559 -----------------------------------------------------------------------------*/
560
561 method buf arrustr.setmultiustr( buf dest )
562 {
563 uint i
564 fornum i, *this
565 {
566 //if i: dest@'\h 0 0'
567 dest@this[i]
568 //dest@'\h2 0' ???
569 }
570 dest@'\h2 0'
571 return dest
572 }
573 /*
574 method buf arrustr.setmultiustr <result>
575 {
576 this.setmultiustr( result )
577 }
578 */
579 /*-----------------------------------------------------------------------------
580 ** Id: arrustr_sort F2
581 *
582 * Summary: Sort unicode strings in the array.
583 *
584 * Params: mode - Specify 1 to sort with ignore-case sensitive. /
585 In default, specify 0.
586 *
587 -----------------------------------------------------------------------------*/
588
589 method arrustr.sort( uint mode )
590 {
591 fastsort( this.ptr(), *this, this.isize, ?( mode, 4, 3 ))
592 }
593