aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/array.h28
-rw-r--r--src/fbasicstring.h720
-rw-r--r--src/hash.h35
-rw-r--r--src/list.h20
-rw-r--r--src/minimacro.cpp2
-rw-r--r--src/set.h33
-rw-r--r--src/tafwriter.cpp5
-rw-r--r--src/tests/rh.cpp52
-rw-r--r--src/tests/url.cpp32
-rw-r--r--src/unit/fstring.unit155
-rw-r--r--src/unitsuite.cpp2
-rw-r--r--src/url.cpp237
-rw-r--r--src/url.h74
13 files changed, 1280 insertions, 115 deletions
diff --git a/src/array.h b/src/array.h
index 0fb0df3..e717fd5 100644
--- a/src/array.h
+++ b/src/array.h
@@ -219,12 +219,12 @@ namespace Bu
219 return *this; 219 return *this;
220 } 220 }
221 221
222 bool operator==( const iterator &oth ) 222 bool operator==( const iterator &oth ) const
223 { 223 {
224 return iPos == oth.iPos; 224 return iPos == oth.iPos;
225 } 225 }
226 226
227 bool operator!=( const iterator &oth ) 227 bool operator!=( const iterator &oth ) const
228 { 228 {
229 return iPos != oth.iPos; 229 return iPos != oth.iPos;
230 } 230 }
@@ -244,6 +244,16 @@ namespace Bu
244 "Cannot dereference finished iterator."); 244 "Cannot dereference finished iterator.");
245 return src[iPos]; 245 return src[iPos];
246 } 246 }
247
248 operator bool() const
249 {
250 return iPos < 0;
251 }
252
253 bool isValid() const
254 {
255 return iPos < 0;
256 }
247 } iterator; 257 } iterator;
248 258
249 typedef struct const_iterator 259 typedef struct const_iterator
@@ -302,12 +312,12 @@ namespace Bu
302 return *this; 312 return *this;
303 } 313 }
304 314
305 bool operator==( const const_iterator &oth ) 315 bool operator==( const const_iterator &oth ) const
306 { 316 {
307 return iPos == oth.iPos; 317 return iPos == oth.iPos;
308 } 318 }
309 319
310 bool operator!=( const const_iterator &oth ) 320 bool operator!=( const const_iterator &oth ) const
311 { 321 {
312 return iPos != oth.iPos; 322 return iPos != oth.iPos;
313 } 323 }
@@ -327,6 +337,16 @@ namespace Bu
327 "Cannot dereference finished iterator."); 337 "Cannot dereference finished iterator.");
328 return src[iPos]; 338 return src[iPos];
329 } 339 }
340
341 operator bool() const
342 {
343 return iPos < 0;
344 }
345
346 bool isValid() const
347 {
348 return iPos < 0;
349 }
330 } const_iterator; 350 } const_iterator;
331 351
332 iterator begin() 352 iterator begin()
diff --git a/src/fbasicstring.h b/src/fbasicstring.h
index 669784b..8303b5a 100644
--- a/src/fbasicstring.h
+++ b/src/fbasicstring.h
@@ -122,6 +122,481 @@ namespace Bu
122 { 122 {
123 pFirst = pLast = newChunk( nSize ); 123 pFirst = pLast = newChunk( nSize );
124 } 124 }
125
126 struct iterator;
127 typedef struct const_iterator
128 {
129 friend class FBasicString<chr, nMinSize, chralloc, chunkalloc>;
130 private:
131 const_iterator( Chunk *pChunk, int iPos ) :
132 pChunk( pChunk ),
133 iPos( iPos )
134 {
135 }
136
137 Chunk *pChunk;
138 int iPos;
139
140 public:
141 const_iterator( const const_iterator &i ) :
142 pChunk( i.pChunk ),
143 iPos( i.iPos )
144 {
145 }
146
147 const_iterator( const iterator &i ) :
148 pChunk( i.pChunk ),
149 iPos( i.iPos )
150 {
151 }
152
153 bool operator==( const const_iterator &i ) const
154 {
155 return pChunk == i.pChunk && iPos == i.iPos;
156 }
157
158 bool operator!=( const const_iterator &i ) const
159 {
160 return !(*this == i);
161 }
162
163 const_iterator &operator=( const const_iterator &i )
164 {
165 pChunk = i.pChunk;
166 iPos = i.iPos;
167 return *this;
168 }
169
170 const_iterator &operator++()
171 {
172 if( !pChunk ) return *this;
173 iPos++;
174 if( iPos >= pChunk->nLength )
175 {
176 iPos = 0;
177 pChunk = pChunk->pNext;
178 }
179 return *this;
180 }
181
182 const_iterator &operator++( int )
183 {
184 if( !pChunk ) return *this;
185 iPos++;
186 if( iPos >= pChunk->nLength )
187 {
188 iPos = 0;
189 pChunk = pChunk->pNext;
190 }
191 return *this;
192 }
193
194 const_iterator &operator+=( int iAmnt )
195 {
196 if( !pChunk ) return *this;
197 iPos += iAmnt;
198 while( iPos >= pChunk->nLength )
199 {
200 iPos -= pChunk->nLength;
201 pChunk = pChunk->pNext;
202 if( pChunk == NULL )
203 break;
204 }
205 return *this;
206 }
207
208 const_iterator operator+( int iAmnt ) const
209 {
210 if( !pChunk ) return *this;
211 const_iterator ret( *this );
212 ret += iAmnt;
213 return ret;
214 }
215
216 const chr &operator *() const
217 {
218 if( !pChunk ) throw Bu::ExceptionBase("Not a valid const_iterator.");
219 return pChunk->pData[iPos];
220 }
221
222 bool operator==( const chr &c ) const
223 {
224 if( !pChunk ) return false;
225 return pChunk->pData[iPos] == c;
226 }
227
228 operator bool() const
229 {
230 return pChunk != NULL;
231 }
232
233 bool isValid() const
234 {
235 return pChunk != NULL;
236 }
237
238 bool compare( const const_iterator &c ) const
239 {
240 const_iterator a = *this;
241 const_iterator b = c;
242 if( a == b )
243 return true;
244 for(; a && b; a++, b++ )
245 {
246 if( *a != *b )
247 return false;
248 }
249 return true;
250 }
251
252 bool compare( const const_iterator &c, int nLen ) const
253 {
254 const_iterator a = *this;
255 const_iterator b = c;
256 if( a == b )
257 return true;
258 for(int j = 0; a && b && j < nLen; a++, b++, j++ )
259 {
260 if( *a != *b )
261 return false;
262 }
263 return true;
264 }
265
266 bool compare( const chr *c ) const
267 {
268 if( !pChunk ) return false;
269 const_iterator a = *this;
270 for(; a && *c; a++, c++ )
271 {
272 if( *a != *c )
273 return false;
274 }
275 if( a.isValid() != (*c!=(chr)0) )
276 return false;
277 return true;
278 }
279
280 bool compare( const chr *c, int nLen ) const
281 {
282 if( !pChunk ) return false;
283 const_iterator a = *this;
284 int j = 0;
285 for(; a && j < nLen; a++, c++, j++ )
286 {
287 if( *a != *c )
288 return false;
289 }
290 if( j < nLen )
291 return false;
292 return true;
293 }
294
295 bool compare( const MyType &s ) const
296 {
297 if( !pChunk ) return false;
298 return compare( s.begin() );
299 }
300
301 bool compare( const MyType &s, int nLen ) const
302 {
303 if( !pChunk ) return false;
304 return compare( s.begin(), nLen );
305 }
306
307 const_iterator find( const chr c ) const
308 {
309 for( const_iterator i = *this; i; i++ )
310 {
311 if( *i == c )
312 return i;
313 }
314 return const_iterator( NULL, 0 );
315 }
316
317 const_iterator find( const chr *pStr, int nLen ) const
318 {
319 for( const_iterator i = *this; i; i++ )
320 {
321 if( i.compare( pStr, nLen ) )
322 return i;
323 }
324 return const_iterator( NULL, 0 );
325 }
326
327 const_iterator find( const MyType &s ) const
328 {
329 for( const_iterator i = *this; i; i++ )
330 {
331 if( i.compare( s ) )
332 return i;
333 }
334 return const_iterator( NULL, 0 );
335 }
336
337 const_iterator find( const MyType &s, int nLen ) const
338 {
339 for( const_iterator i = *this; i; i++ )
340 {
341 if( i.compare( s, nLen ) )
342 return i;
343 }
344 return const_iterator( NULL, 0 );
345 }
346 } const_iterator;
347
348 typedef struct iterator
349 {
350 friend class FBasicString<chr, nMinSize, chralloc, chunkalloc>;
351 private:
352 iterator( Chunk *pChunk, int iPos ) :
353 pChunk( pChunk ),
354 iPos( iPos )
355 {
356 }
357
358 Chunk *pChunk;
359 int iPos;
360
361 public:
362 iterator( const iterator &i ) :
363 pChunk( i.pChunk ),
364 iPos( i.iPos )
365 {
366 }
367
368 operator const_iterator() const
369 {
370 return const_iterator( pChunk, iPos );
371 }
372
373 bool operator==( const iterator &i ) const
374 {
375 return pChunk == i.pChunk && iPos == i.iPos;
376 }
377
378 bool operator!=( const iterator &i ) const
379 {
380 return !(*this == i);
381 }
382
383 iterator &operator=( const iterator &i )
384 {
385 pChunk = i.pChunk;
386 iPos = i.iPos;
387 return *this;
388 }
389
390 iterator &operator++()
391 {
392 if( !pChunk ) return *this;
393 iPos++;
394 if( iPos >= pChunk->nLength )
395 {
396 iPos = 0;
397 pChunk = pChunk->pNext;
398 }
399 return *this;
400 }
401
402 iterator &operator++( int )
403 {
404 if( !pChunk ) return *this;
405 iPos++;
406 if( iPos >= pChunk->nLength )
407 {
408 iPos = 0;
409 pChunk = pChunk->pNext;
410 }
411 return *this;
412 }
413
414 iterator &operator+=( int iAmnt )
415 {
416 if( !pChunk ) return *this;
417 iPos += iAmnt;
418 while( iPos >= pChunk->nLength )
419 {
420 iPos -= pChunk->nLength;
421 pChunk = pChunk->pNext;
422 if( pChunk == NULL )
423 break;
424 }
425 return *this;
426 }
427
428 iterator operator+( int iAmnt ) const
429 {
430 if( !pChunk ) return *this;
431 iterator ret( *this );
432 ret += iAmnt;
433 return ret;
434 }
435
436 chr &operator*()
437 {
438 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
439 return pChunk->pData[iPos];
440 }
441
442 const chr &operator*() const
443 {
444 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
445 return pChunk->pData[iPos];
446 }
447
448 bool operator==( const chr &c ) const
449 {
450 if( !pChunk ) return false;
451 return pChunk->pData[iPos] == c;
452 }
453
454 iterator &operator=( const chr &c )
455 {
456 if( !pChunk ) throw Bu::ExceptionBase("Not a valid iterator.");
457 pChunk->pData[iPos] = c;
458 return *this;
459 }
460
461 operator bool() const
462 {
463 return pChunk != NULL;
464 }
465
466 bool isValid() const
467 {
468 return pChunk != NULL;
469 }
470
471 bool compare( const iterator &c ) const
472 {
473 iterator a = *this;
474 iterator b = c;
475 if( a == b )
476 return true;
477 for(; a && b; a++, b++ )
478 {
479 if( *a != *b )
480 return false;
481 }
482 return true;
483 }
484
485 bool compare( const iterator &c, int nLen ) const
486 {
487 iterator a = *this;
488 iterator b = c;
489 if( a == b )
490 return true;
491 for(int j = 0; a && b && j < nLen; a++, b++, j++ )
492 {
493 if( *a != *b )
494 return false;
495 }
496 return true;
497 }
498
499 bool compare( const chr *c ) const
500 {
501 if( !pChunk ) return false;
502 iterator a = *this;
503 for(; a && *c; a++, c++ )
504 {
505 if( *a != *c )
506 return false;
507 }
508 if( a.isValid() != (*c!=(chr)0) )
509 return false;
510 return true;
511 }
512
513 bool compare( const chr *c, int nLen ) const
514 {
515 if( !pChunk ) return false;
516 iterator a = *this;
517 int j = 0;
518 for(; a && j < nLen; a++, c++, j++ )
519 {
520 if( *a != *c )
521 return false;
522 }
523 if( j < nLen )
524 return false;
525 return true;
526 }
527
528 bool compare( const MyType &s ) const
529 {
530 if( !pChunk ) return false;
531 return compare( s.begin() );
532 }
533
534 bool compare( const MyType &s, int nLen ) const
535 {
536 if( !pChunk ) return false;
537 return compare( s.begin(), nLen );
538 }
539
540 iterator find( const chr c ) const
541 {
542 for( iterator i = *this; i; i++ )
543 {
544 if( *i == c )
545 return i;
546 }
547 return iterator( NULL, 0 );
548 }
549
550 iterator find( const chr *pStr, int nLen ) const
551 {
552 for( iterator i = *this; i; i++ )
553 {
554 if( i.compare( pStr, nLen ) )
555 return i;
556 }
557 return iterator( NULL, 0 );
558 }
559
560 iterator find( const MyType &s ) const
561 {
562 for( iterator i = *this; i; i++ )
563 {
564 if( i.compare( s ) )
565 return i;
566 }
567 return iterator( NULL, 0 );
568 }
569
570 iterator find( const MyType &s, int nLen ) const
571 {
572 for( iterator i = *this; i; i++ )
573 {
574 if( i.compare( s, nLen ) )
575 return i;
576 }
577 return iterator( NULL, 0 );
578 }
579 } iterator;
580
581 //typedef chr *iterator;
582// typedef const chr *const_iterator;
583 // typedef iterator const_iterator;
584
585 FBasicString( const const_iterator &s ) :
586 nLength( 0 ),
587 pFirst( NULL ),
588 pLast( NULL )
589 {
590 append( s );
591 }
592
593 FBasicString( const const_iterator &s, const const_iterator &e ) :
594 nLength( 0 ),
595 pFirst( NULL ),
596 pLast( NULL )
597 {
598 append( s, e );
599 }
125 600
126 virtual ~FBasicString() 601 virtual ~FBasicString()
127 { 602 {
@@ -129,10 +604,6 @@ namespace Bu
129 } 604 }
130 605
131 /** 606 /**
132 *@todo void append( const MyType & sData )
133 */
134
135 /**
136 * Append data to your string. 607 * Append data to your string.
137 *@param pData (const chr *) The data to append. 608 *@param pData (const chr *) The data to append.
138 */ 609 */
@@ -205,6 +676,74 @@ namespace Bu
205 } 676 }
206 677
207 /** 678 /**
679 * Append another FString to this one.
680 *@param sData (MyType &) The FString to append.
681 *@param nLen How much data to append.
682 */
683 void append( const MyType & sData, long nStart, long nLen )
684 {
685 if( nLen < 0 )
686 nLen = sData.getSize() - nStart;
687 append( sData.getStr(), nStart, nLen );
688 }
689
690 void append( const const_iterator &s )
691 {
692 if( !s.isValid() )
693 return;
694 Chunk *pSrc = s.pChunk;
695
696 Chunk *pNew = newChunk( pSrc->nLength-s.iPos );
697 cpy( pNew->pData, pSrc->pData+s.iPos, pSrc->nLength-s.iPos );
698 appendChunk( pNew );
699
700 while( (pSrc = pSrc->pNext) )
701 {
702 appendChunk( copyChunk( pSrc ) );
703 }
704 }
705
706 void append( const iterator &s ) // I get complainst without this one
707 {
708 append( const_iterator( s ) );
709 }
710
711 void append( const const_iterator &s, const const_iterator &e )
712 {
713 if( !s.isValid() )
714 return;
715 if( !e.isValid() )
716 {
717 append( s );
718 return;
719 }
720 if( s.pChunk == e.pChunk )
721 {
722 // Simple case, they're the same chunk
723 Chunk *pNew = newChunk( e.iPos-s.iPos );
724 cpy( pNew->pData, s.pChunk->pData+s.iPos, e.iPos-s.iPos );
725 appendChunk( pNew );
726 }
727 else
728 {
729 // A little trickier, scan the blocks...
730 Chunk *pSrc = s.pChunk;
731 Chunk *pNew = newChunk( pSrc->nLength-s.iPos );
732 cpy( pNew->pData, pSrc->pData+s.iPos, pSrc->nLength-s.iPos );
733 appendChunk( pNew );
734
735 while( (pSrc = pSrc->pNext) != e.pChunk )
736 {
737 appendChunk( copyChunk( pSrc ) );
738 }
739
740 pNew = newChunk( e.iPos );
741 cpy( pNew->pData, pSrc->pData, e.iPos );
742 appendChunk( pNew );
743 }
744 }
745
746 /**
208 * Prepend another FString to this one. 747 * Prepend another FString to this one.
209 *@param sData (MyType &) The FString to prepend. 748 *@param sData (MyType &) The FString to prepend.
210 */ 749 */
@@ -549,6 +1088,42 @@ namespace Bu
549 append( pData, nSize ); 1088 append( pData, nSize );
550 } 1089 }
551 1090
1091 void set( const chr *pData, long nStart, long nSize )
1092 {
1093 clear();
1094 append( pData, nStart, nSize );
1095 }
1096
1097 void set( const MyType &rData )
1098 {
1099 clear();
1100 append( rData );
1101 }
1102
1103 void set( const MyType &rData, long nSize )
1104 {
1105 clear();
1106 append( rData, nSize );
1107 }
1108
1109 void set( const MyType &rData, long nStart, long nSize )
1110 {
1111 clear();
1112 append( rData, nStart, nSize );
1113 }
1114
1115 void set( const_iterator s )
1116 {
1117 clear();
1118 append( s );
1119 }
1120
1121 void set( const_iterator s, const_iterator e )
1122 {
1123 clear();
1124 append( s, e );
1125 }
1126
552 void expand() 1127 void expand()
553 { 1128 {
554 flatten(); 1129 flatten();
@@ -704,6 +1279,55 @@ namespace Bu
704 return (pFirst != NULL); 1279 return (pFirst != NULL);
705 } 1280 }
706 1281
1282 bool compareSub( const chr *pData, long nIndex, long nLen )
1283 {
1284 if( pFirst == NULL ) {
1285 if( pData == NULL )
1286 return true;
1287 if( pData[0] == (chr)0 )
1288 return true;
1289 return false;
1290 }
1291 if( nIndex+nLen > nLength )
1292 return false;
1293
1294 flatten();
1295 pFirst->pData[nLength] = (chr)0;
1296 const chr *a = pData;
1297 chr *b = pFirst->pData+nIndex;
1298 for( long j = 0; j < nLen; j++, a++, b++ )
1299 {
1300 if( *a != *b )
1301 return false;
1302 if( *a == (chr)0 && j < nLength )
1303 return false;
1304 }
1305
1306 return true;
1307 }
1308
1309 bool compareSub( const MyType &rData, long nIndex, long nLen )
1310 {
1311 if( pFirst == NULL || rData.pFirst == NULL )
1312 return false;
1313 if( nLen < 0 )
1314 nLen = rData.nLength;
1315 if( nIndex+nLen > nLength )
1316 return false;
1317
1318 flatten();
1319 rData.flatten();
1320 const chr *a = rData.pFirst->pData;
1321 chr *b = pFirst->pData + nIndex;
1322 for( long j = 0; j < nLen; j++, a++, b++ )
1323 {
1324 if( *a != *b )
1325 return false;
1326 }
1327
1328 return true;
1329 }
1330
707 /** 1331 /**
708 * Is the character at index (nIndex) white space? 1332 * Is the character at index (nIndex) white space?
709 *@param nIndex (long) The index of the character you want to check. 1333 *@param nIndex (long) The index of the character you want to check.
@@ -758,45 +1382,56 @@ namespace Bu
758 } 1382 }
759 } 1383 }
760 1384
761 /** 1385 const_iterator find( const chr cChar,
762 * Find the index of the first occurrance of (sText) 1386 const_iterator iStart=begin() ) const
763 *@param sText (const chr *) The string to search for.
764 *@returns (long) The index of the first occurrance. -1 for not found.
765 */
766 long find( const chr cChar ) const
767 { 1387 {
768 flatten(); 1388 for( ; iStart; iStart++ )
769 for( long j = 0; j < pFirst->nLength; j++ )
770 { 1389 {
771 if( pFirst->pData[j] == cChar ) 1390 if( cChar == *iStart )
772 return j; 1391 return iStart;
773 } 1392 }
774 return -1; 1393 return end();
775 } 1394 }
776 1395
777 /** 1396 const_iterator find( const chr *sText, int nLen,
778 * Find the index of the first occurrance of cChar 1397 const_iterator iStart=begin() ) const
779 *@param cChar (const chr) The character to search for.
780 *@returns (long) The index of the first occurrance. -1 for not found.
781 */
782 long find( const chr *sText ) const
783 { 1398 {
784 long nTLen = strlen( sText ); 1399 for( ; iStart; iStart++ )
785 flatten();
786 for( long j = 0; j < pFirst->nLength-nTLen; j++ )
787 { 1400 {
788 if( !strncmp( sText, pFirst->pData+j, nTLen ) ) 1401 if( iStart.compare( sText, nLen ) )
789 return j; 1402 return iStart;
790 } 1403 }
791 return -1; 1404 return end();
792 } 1405 }
793 1406
1407 const_iterator find( const MyType &rStr,
1408 const_iterator iStart=begin() ) const
1409 {
1410 for( ; iStart; iStart++ )
1411 {
1412 if( iStart.compare( rStr ) )
1413 return iStart;
1414 }
1415 return end();
1416 }
1417
1418 const_iterator find( const MyType &rStr, int nLen,
1419 const_iterator iStart=begin() ) const
1420 {
1421 for( ; iStart; iStart++ )
1422 {
1423 if( iStart.compare( rStr, nLen ) )
1424 return iStart;
1425 }
1426 return end();
1427 }
1428
794 /** 1429 /**
795 * Find the index of the first occurrance of cChar 1430 * Find the index of the first occurrance of cChar
796 *@param sText (const chr *) The string to search for. 1431 *@param sText (const chr *) The string to search for.
797 *@returns (long) The index of the first occurrance. -1 for not found. 1432 *@returns (long) The index of the first occurrance. -1 for not found.
798 */ 1433 */
799 long find( long iStart, const chr cChar ) const 1434 long findIdx( const chr cChar, long iStart=0 ) const
800 { 1435 {
801 flatten(); 1436 flatten();
802 for( long j = iStart; j < pFirst->nLength; j++ ) 1437 for( long j = iStart; j < pFirst->nLength; j++ )
@@ -812,7 +1447,7 @@ namespace Bu
812 *@param cChar (const chr) The character to search for. 1447 *@param cChar (const chr) The character to search for.
813 *@returns (long) The index of the first occurrance. -1 for not found. 1448 *@returns (long) The index of the first occurrance. -1 for not found.
814 */ 1449 */
815 long find( long iStart, const chr *sText ) const 1450 long findIdx( const chr *sText, long iStart=0 ) const
816 { 1451 {
817 long nTLen = strlen( sText ); 1452 long nTLen = strlen( sText );
818 flatten(); 1453 flatten();
@@ -829,7 +1464,7 @@ namespace Bu
829 *@param sText (const chr *) The string to search for. 1464 *@param sText (const chr *) The string to search for.
830 *@returns (long) The index of the last occurrance. -1 for not found. 1465 *@returns (long) The index of the last occurrance. -1 for not found.
831 */ 1466 */
832 long rfind( const chr *sText ) const 1467 long rfindIdx( const chr *sText ) const
833 { 1468 {
834 long nTLen = strlen( sText ); 1469 long nTLen = strlen( sText );
835 flatten(); 1470 flatten();
@@ -928,37 +1563,28 @@ namespace Bu
928 } 1563 }
929 } 1564 }
930 1565
931 typedef chr *iterator;
932 typedef const chr *const_iterator;
933
934 iterator begin() 1566 iterator begin()
935 { 1567 {
936 if( nLength == 0 ) 1568 if( nLength == 0 )
937 return NULL; 1569 return iterator( NULL, 0 );
938 flatten(); 1570 return iterator( pFirst, 0 );
939 return pFirst->pData;
940 } 1571 }
941 1572
942 const_iterator begin() const 1573 const_iterator begin() const
943 { 1574 {
944 if( nLength == 0 ) 1575 if( nLength == 0 )
945 return NULL; 1576 return const_iterator( NULL, 0 );
946 flatten(); 1577 return iterator( pFirst, 0 );
947 return pFirst->pData;
948 } 1578 }
949 1579
950 iterator end() 1580 iterator end()
951 { 1581 {
952 if( nLength == 0 ) 1582 return iterator( NULL, 0 );
953 return NULL;
954 return pFirst->pData+pFirst->nLength;
955 } 1583 }
956 1584
957 const_iterator end() const 1585 const_iterator end() const
958 { 1586 {
959 if( nLength == 0 ) 1587 return const_iterator( NULL, 0 );
960 return NULL;
961 return pFirst->pData+pFirst->nLength;
962 } 1588 }
963 1589
964 bool isEmpty() const 1590 bool isEmpty() const
diff --git a/src/hash.h b/src/hash.h
index 8856860..3868a4e 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -575,7 +575,17 @@ namespace Bu
575 { 575 {
576 } 576 }
577 577
578 bool isActive() 578 DEPRECATED bool isActive() const
579 {
580 return !bFinished;
581 }
582
583 bool isValid() const
584 {
585 return !bFinished;
586 }
587
588 operator bool() const
579 { 589 {
580 return !bFinished; 590 return !bFinished;
581 } 591 }
@@ -605,7 +615,7 @@ namespace Bu
605 /** 615 /**
606 * Iterator equality comparison operator. Iterators the same? 616 * Iterator equality comparison operator. Iterators the same?
607 */ 617 */
608 bool operator==( const iterator &oth ) 618 bool operator==( const iterator &oth ) const
609 { 619 {
610 if( bFinished != oth.bFinished ) 620 if( bFinished != oth.bFinished )
611 return false; 621 return false;
@@ -624,7 +634,7 @@ namespace Bu
624 /** 634 /**
625 * Iterator not equality comparison operator. Not the same? 635 * Iterator not equality comparison operator. Not the same?
626 */ 636 */
627 bool operator!=( const iterator &oth ) 637 bool operator!=( const iterator &oth ) const
628 { 638 {
629 return !(*this == oth ); 639 return !(*this == oth );
630 } 640 }
@@ -650,6 +660,11 @@ namespace Bu
650 { 660 {
651 return hsh.getValueAtPos( nPos ); 661 return hsh.getValueAtPos( nPos );
652 } 662 }
663
664 const value &operator *() const
665 {
666 return hsh.getValueAtPos( nPos );
667 }
653 668
654 /** 669 /**
655 * Get the key behind this iterator. 670 * Get the key behind this iterator.
@@ -697,6 +712,16 @@ namespace Bu
697 bool bFinished; 712 bool bFinished;
698 713
699 public: 714 public:
715 bool isValid() const
716 {
717 return !bFinished;
718 }
719
720 operator bool() const
721 {
722 return !bFinished;
723 }
724
700 /** 725 /**
701 * Iterator incrementation operator. Move the iterator forward. 726 * Iterator incrementation operator. Move the iterator forward.
702 */ 727 */
@@ -722,7 +747,7 @@ namespace Bu
722 /** 747 /**
723 * Iterator equality comparison operator. Iterators the same? 748 * Iterator equality comparison operator. Iterators the same?
724 */ 749 */
725 bool operator==( const const_iterator &oth ) 750 bool operator==( const const_iterator &oth ) const
726 { 751 {
727 if( bFinished != oth.bFinished ) 752 if( bFinished != oth.bFinished )
728 return false; 753 return false;
@@ -741,7 +766,7 @@ namespace Bu
741 /** 766 /**
742 * Iterator not equality comparison operator. Not the same? 767 * Iterator not equality comparison operator. Not the same?
743 */ 768 */
744 bool operator!=( const const_iterator &oth ) 769 bool operator!=( const const_iterator &oth ) const
745 { 770 {
746 return !(*this == oth ); 771 return !(*this == oth );
747 } 772 }
diff --git a/src/list.h b/src/list.h
index d16e606..f11336e 100644
--- a/src/list.h
+++ b/src/list.h
@@ -377,6 +377,16 @@ namespace Bu
377 return *this; 377 return *this;
378 } 378 }
379 379
380 operator bool()
381 {
382 return pLink != NULL;
383 }
384
385 bool isValid()
386 {
387 return pLink != NULL;
388 }
389
380 /** 390 /**
381 * Assignment operator. 391 * Assignment operator.
382 *@param oth (const iterator &) The other iterator to set this 392 *@param oth (const iterator &) The other iterator to set this
@@ -499,6 +509,16 @@ namespace Bu
499 pLink = oth.pLink; 509 pLink = oth.pLink;
500 return *this; 510 return *this;
501 } 511 }
512
513 operator bool()
514 {
515 return pLink != NULL;
516 }
517
518 bool isValid()
519 {
520 return pLink != NULL;
521 }
502 } const_iterator; 522 } const_iterator;
503 523
504 /** 524 /**
diff --git a/src/minimacro.cpp b/src/minimacro.cpp
index b97cefc..0d524a9 100644
--- a/src/minimacro.cpp
+++ b/src/minimacro.cpp
@@ -141,7 +141,7 @@ Bu::FString Bu::MiniMacro::parseCmd()
141Bu::FString Bu::MiniMacro::callFunc( 141Bu::FString Bu::MiniMacro::callFunc(
142 const Bu::FString &sIn, const Bu::FString &sFunc ) 142 const Bu::FString &sIn, const Bu::FString &sFunc )
143{ 143{
144 int i = sFunc.find('('); 144 int i = sFunc.findIdx('(');
145 if( i < 0 ) 145 if( i < 0 )
146 throw Bu::ExceptionBase("That doesn't look like a function call"); 146 throw Bu::ExceptionBase("That doesn't look like a function call");
147 Bu::FString sName( sFunc.getStr(), i ); 147 Bu::FString sName( sFunc.getStr(), i );
diff --git a/src/set.h b/src/set.h
index 42f9eb8..a25b0bf 100644
--- a/src/set.h
+++ b/src/set.h
@@ -322,7 +322,7 @@ namespace Bu
322 /** 322 /**
323 * Iterator equality comparison operator. Iterators the same? 323 * Iterator equality comparison operator. Iterators the same?
324 */ 324 */
325 bool operator==( const iterator &oth ) 325 bool operator==( const iterator &oth ) const
326 { 326 {
327 if( bFinished != oth.bFinished ) 327 if( bFinished != oth.bFinished )
328 return false; 328 return false;
@@ -341,7 +341,7 @@ namespace Bu
341 /** 341 /**
342 * Iterator not equality comparison operator. Not the same? 342 * Iterator not equality comparison operator. Not the same?
343 */ 343 */
344 bool operator!=( const iterator &oth ) 344 bool operator!=( const iterator &oth ) const
345 { 345 {
346 return !(*this == oth ); 346 return !(*this == oth );
347 } 347 }
@@ -366,6 +366,21 @@ namespace Bu
366 { 366 {
367 return hsh.getKeyAtPos( nPos ); 367 return hsh.getKeyAtPos( nPos );
368 } 368 }
369
370 const key &operator *() const
371 {
372 return hsh.getKeyAtPos( nPos );
373 }
374
375 bool isValid() const
376 {
377 return !bFinished;
378 }
379
380 operator bool() const
381 {
382 return !bFinished;
383 }
369 } iterator; 384 } iterator;
370 385
371 /** 386 /**
@@ -420,7 +435,7 @@ namespace Bu
420 /** 435 /**
421 * Iterator equality comparison operator. Iterators the same? 436 * Iterator equality comparison operator. Iterators the same?
422 */ 437 */
423 bool operator==( const const_iterator &oth ) 438 bool operator==( const const_iterator &oth ) const
424 { 439 {
425 if( bFinished != oth.bFinished ) 440 if( bFinished != oth.bFinished )
426 return false; 441 return false;
@@ -439,7 +454,7 @@ namespace Bu
439 /** 454 /**
440 * Iterator not equality comparison operator. Not the same? 455 * Iterator not equality comparison operator. Not the same?
441 */ 456 */
442 bool operator!=( const const_iterator &oth ) 457 bool operator!=( const const_iterator &oth ) const
443 { 458 {
444 return !(*this == oth ); 459 return !(*this == oth );
445 } 460 }
@@ -464,6 +479,16 @@ namespace Bu
464 { 479 {
465 return hsh.getKeyAtPos( nPos ); 480 return hsh.getKeyAtPos( nPos );
466 } 481 }
482
483 bool isValid() const
484 {
485 return !bFinished;
486 }
487
488 operator bool() const
489 {
490 return !bFinished;
491 }
467 } const_iterator; 492 } const_iterator;
468 493
469 /** 494 /**
diff --git a/src/tafwriter.cpp b/src/tafwriter.cpp
index b0f5def..82d39e5 100644
--- a/src/tafwriter.cpp
+++ b/src/tafwriter.cpp
@@ -104,7 +104,10 @@ void Bu::TafWriter::writeString( const Bu::FString &str )
104 sOut.write(buf, 4 ); 104 sOut.write(buf, 4 );
105 } 105 }
106 else 106 else
107 sOut.write( s, 1 ); 107 {
108 const char buf = *s;
109 sOut.write( &buf, 1 );
110 }
108 } 111 }
109 sOut.write("\"", 1 ); 112 sOut.write("\"", 1 );
110} 113}
diff --git a/src/tests/rh.cpp b/src/tests/rh.cpp
deleted file mode 100644
index 70abcb7..0000000
--- a/src/tests/rh.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
1#include "bu/file.h"
2#include "bu/hash.h"
3#include "bu/archive.h"
4#include "bu/fstring.h"
5#include "bu/nids.h"
6#include "bu/nidsstream.h"
7
8int main( int argc, char *argv[] )
9{
10 if( argv[1][0] == 'r' )
11 {
12 typedef Bu::Hash<Bu::FString, int> Hsh;
13
14 Bu::File fIn( argv[2], Bu::File::Read );
15 Bu::Archive ar( fIn, Bu::Archive::load );
16
17 Hsh h;
18 ar >> h;
19
20 printf("Read %d.\n", h.getSize() );
21 for( Hsh::iterator i = h.begin(); i != h.end(); i++ )
22 {
23 printf(" - \"%s\" = %d\n", i.getKey().getStr(), i.getValue() );
24 }
25
26 printf("%d vs. %d\n", h.getSize(), h.getKeys().getSize() );
27 }
28 else if( argv[1][0] == 'n' )
29 {
30 typedef Bu::Hash<Bu::FString, int> Hsh;
31
32 Bu::File fIn( argv[2], Bu::File::Read );
33 Bu::Nids n( fIn );
34 n.initialize();
35 Bu::NidsStream sIn = n.openStream( 0 );
36 Bu::Archive ar( sIn, Bu::Archive::load );
37
38 Hsh h;
39 ar >> h;
40
41 printf("Read %d.\n", h.getSize() );
42 for( Hsh::iterator i = h.begin(); i != h.end(); i++ )
43 {
44 printf(" - \"%s\" = %d\n", i.getKey().getStr(), i.getValue() );
45 }
46
47 printf("%d vs. %d\n", h.getSize(), h.getKeys().getSize() );
48 }
49
50 return 0;
51}
52
diff --git a/src/tests/url.cpp b/src/tests/url.cpp
new file mode 100644
index 0000000..c9af676
--- /dev/null
+++ b/src/tests/url.cpp
@@ -0,0 +1,32 @@
1#include "bu/url.h"
2
3#include <stdio.h>
4
5int main( int argc, char *argv[] )
6{
7 printf("encodede: %s\n", Bu::Url::encode( argv[1] ).getStr() );
8 printf("decodede: %s\n", Bu::Url::decode( argv[1] ).getStr() );
9 Bu::Url u( argv[1] );
10
11 printf("Protocol: %s\n", u.getProtocol().getStr() );
12 printf("User: %s\n", u.getUser().getStr() );
13 printf("Pass: %s\n", u.getPass().getStr() );
14 printf("Host: %s\n", u.getHost().getStr() );
15 printf("Path: %s\n", u.getPath().getStr() );
16 try
17 {
18 printf("Port: %d\n", u.getPort() );
19 } catch( Bu::ExceptionBase &e )
20 {
21 printf("Port: not set.\n");
22 }
23 printf("Parameters:\n");
24 for( Bu::Url::ParamList::const_iterator i = u.getParamBegin(); i; i++ )
25 {
26 printf(" \"%s\" = \"%s\"\n",
27 (*i).sName.getStr(), (*i).sValue.getStr()
28 );
29 }
30
31 return 0;
32}
diff --git a/src/unit/fstring.unit b/src/unit/fstring.unit
index 3912de2..a0d62da 100644
--- a/src/unit/fstring.unit
+++ b/src/unit/fstring.unit
@@ -138,3 +138,158 @@
138 unitTest( a.getSubStr( -10 ) == "abcdefghijklmnop" ); 138 unitTest( a.getSubStr( -10 ) == "abcdefghijklmnop" );
139 unitTest( a.getSubStr( -15, 4 ) == "abcd" ); 139 unitTest( a.getSubStr( -15, 4 ) == "abcd" );
140} 140}
141
142{%compareSub1}
143{
144 Bu::FString a("just a string.");
145 unitTest( a.compareSub("a ", 5, 2) == true );
146 unitTest( a.compareSub("string.aoeu", 7, 11 ) == false );
147 unitTest( a.compareSub("string.aoeu", 7, 3 ) == true );
148}
149
150{%compareSub2}
151{
152 Bu::FString a("just a string.");
153 unitTest( a.compareSub(Bu::FString("a "), 5, 2) == true );
154 unitTest( a.compareSub(Bu::FString("string.aoeu"), 7, 11 ) == false );
155 unitTest( a.compareSub(Bu::FString("string.aoeu"), 7, 3 ) == true );
156}
157
158{%iterator1}
159{
160 Bu::FString a("This is a test.");
161 Bu::FString b;
162 for( Bu::FString::iterator i = a.begin(); i; i++ )
163 {
164 b += *i;
165 }
166 unitTest( a == b );
167}
168
169{%iterator2}
170{
171 Bu::FString a("This is a test.");
172 Bu::FString b("--This is a test.");
173 Bu::FString::iterator ai = a.begin();
174 Bu::FString::iterator bi = b.begin();
175 unitTest( ai.compare( bi ) == false );
176 unitTest( bi.compare( ai ) == false );
177 bi++; bi++;
178 unitTest( ai.compare( bi ) == true );
179 unitTest( bi.compare( ai ) == true );
180}
181
182{%iterator3}
183{
184 Bu::FString a("1234honour");
185 Bu::FString b("--1234ueje");
186 Bu::FString::iterator ai = a.begin();
187 Bu::FString::iterator bi = b.begin();
188 unitTest( ai.compare( bi, 4 ) == false );
189 unitTest( bi.compare( ai, 4 ) == false );
190 bi++; bi++;
191 unitTest( ai.compare( bi, 4 ) == true );
192 unitTest( bi.compare( ai, 4 ) == true );
193 unitTest( ai.compare( bi, 5 ) == false );
194 unitTest( bi.compare( ai, 5 ) == false );
195
196}
197
198{%iterator4}
199{
200 Bu::FString a("1234aoeu");
201 Bu::FString::iterator ai = a.begin();
202 unitTest( ai.compare("1234") == false );
203 unitTest( ai.compare("1234aoeu") == true );
204 unitTest( ai.compare("1234aoeuee") == false );
205}
206
207{%iterator5}
208{
209 Bu::FString a("1234aoeu");
210 Bu::FString::iterator ai = a.begin();
211 unitTest( ai.compare("1234", 4) == true );
212 unitTest( ai.compare("1234aoeu", 8) == true );
213 unitTest( ai.compare("1234aoeuee", 10) == false );
214}
215
216{%iterator6}
217{
218 Bu::FString a("just ->this part");
219 Bu::FString b;
220 Bu::FString::iterator s = a.begin();
221 for(; s; s++ )
222 {
223 if( *s == '>' )
224 {
225 s++;
226 b.set( s );
227 break;
228 }
229 }
230 unitTest( b == "this part" );
231
232 b.append( s );
233
234 Bu::FString c;
235 c.set( b.begin() );
236
237 // This is here because the comparison operator used to cause flattening.
238 unitTest( b == "this partthis part" );
239 unitTest( c == b );
240}
241
242{%iterator7}
243{
244 Bu::FString a("just [this] part");
245 Bu::FString b;
246 Bu::FString::iterator s = a.begin();
247 for(; s; s++ )
248 {
249 if( *s == '[' )
250 {
251 s++;
252 break;
253 }
254 }
255 Bu::FString::iterator e = s;
256 for(; e; e++ )
257 {
258 if( *e == ']' )
259 {
260 b.set( s, e );
261 break;
262 }
263 }
264 unitTest( b == "this" );
265
266 b.append( s, e );
267
268 for( Bu::FString::iterator i = b.begin(); i;)
269 {
270 Bu::FString::iterator k = i;
271 k++;
272 if( !k )
273 {
274 b.append( b.begin(), i );
275 break;
276 }
277 i = k;
278 }
279 Bu::FString l;
280 l.set( b.begin() );
281 unitTest( l == "thisthisthisthi" );
282 for( Bu::FString::iterator i = b.begin(); i;)
283 {
284 Bu::FString::iterator k = i;
285 k++;
286 if( !k )
287 {
288 b.append( b.begin(), i );
289 break;
290 }
291 i = k;
292 }
293 l.set( b.begin() );
294 unitTest( l == "thisthisthisthithisthisthisth" );
295}
diff --git a/src/unitsuite.cpp b/src/unitsuite.cpp
index 7421496..cdd6a2a 100644
--- a/src/unitsuite.cpp
+++ b/src/unitsuite.cpp
@@ -110,7 +110,7 @@ void Bu::UnitSuite::add( Test fTest, const Bu::FString &sName, Expect e )
110 TestInfo ti; 110 TestInfo ti;
111 ti.sName = sName; 111 ti.sName = sName;
112 ti.eExpect = e; 112 ti.eExpect = e;
113 long index = ti.sName.rfind("::"); 113 long index = ti.sName.rfindIdx("::");
114 if( index != -1 ) 114 if( index != -1 )
115 { 115 {
116 FString tmp = sSuiteName; 116 FString tmp = sSuiteName;
diff --git a/src/url.cpp b/src/url.cpp
new file mode 100644
index 0000000..7cc4263
--- /dev/null
+++ b/src/url.cpp
@@ -0,0 +1,237 @@
1#include "bu/url.h"
2#ifndef WIN32
3# include <netdb.h>
4# include <netinet/in.h>
5#endif
6#include <stdlib.h>
7
8char Bu::Url::hexcode[] = {
9 '0', '1', '2', '3', '4', '5', '6', '7',
10 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
11};
12
13Bu::Url::Url()
14{
15}
16
17Bu::Url::Url( const Bu::FString &sUrl )
18{
19 parseUrl( sUrl );
20}
21
22Bu::Url::~Url()
23{
24}
25
26void Bu::Url::parseUrl( const Bu::FString &sUrl )
27{
28 clear();
29
30 Bu::FString::const_iterator i = sUrl.begin();
31 parseProtocol( i );
32 parseUserPass( i );
33 parseHost( i );
34 parsePath( i );
35}
36
37Bu::FString Bu::Url::decode( const Bu::FString &sStr )
38{
39 Bu::FString sRet;
40 char buf[3] = {0, 0, 0};
41 for( Bu::FString::const_iterator i = sStr.begin(); i; i++ )
42 {
43 if( *i == '+' )
44 {
45 sRet += ' ';
46 }
47 else if( *i == '%' )
48 {
49 i++;
50 buf[0] = *i;
51 i++;
52 buf[1] = *i;
53 sRet += (char)((unsigned char)strtol( buf, NULL, 16 ));
54 }
55 else
56 {
57 sRet += *i;
58 }
59 }
60 return sRet;
61}
62
63Bu::FString Bu::Url::encode( const Bu::FString &sStr )
64{
65 Bu::FString sRet;
66 for( Bu::FString::const_iterator i = sStr.begin(); i; i++ )
67 {
68 if( *i == ' ' )
69 {
70 sRet += '+';
71 }
72 else if(
73 (*i >= 'A' && *i <= 'Z') ||
74 (*i >= 'a' && *i <= 'z') ||
75 (*i >= '0' && *i <= '9') ||
76 (*i == '-' || *i == '_' || *i == '.' || *i == '~')
77 )
78 {
79 sRet += *i;
80 }
81 else
82 {
83 unsigned char b = *i;
84 sRet += '%';
85 sRet += hexcode[(b>>4)&0xF];
86 sRet += hexcode[b&0xF];
87 }
88 }
89 return sRet;
90}
91
92void Bu::Url::parseProtocol( Bu::FString::const_iterator &i )
93{
94 Bu::FString::const_iterator s = i.find("://", 3);
95 if( !s )
96 throw Bu::ExceptionBase("No :// in url");
97 Bu::FString sTmp( i, s );
98 setProtocol( sTmp );
99 i = s + 3;
100}
101
102void Bu::Url::setProtocol( const Bu::FString &sNewProto, bool bAutoSetPort )
103{
104 sProtocol = sNewProto;
105#ifndef WIN32
106 if( bAutoSetPort )
107 {
108 struct servent *se = getservbyname( sProtocol.getStr(), "tcp" );
109 if( se )
110 {
111 iPort = ntohs( se->s_port );
112 }
113 }
114#endif
115}
116
117void Bu::Url::parseUserPass( Bu::FString::const_iterator &i )
118{
119 Bu::FString::const_iterator s = i.find('@');
120 if( !s )
121 return;
122
123 Bu::FString::const_iterator p = i.find(':');
124 if( p )
125 {
126 sUser.set( i, p );
127 sPass.set( p+1, s );
128 }
129 else
130 {
131 sUser.set( i, s );
132 }
133
134 i = s + 1;
135}
136
137void Bu::Url::parseHost( Bu::FString::const_iterator &i )
138{
139 Bu::FString::const_iterator s = i;
140 for( ; s && *s != '/'; s++ )
141 {
142 if( *s == ':' )
143 {
144 sHost.set( i, s );
145 i = s + 1;
146 s = i.find('/');
147 Bu::FString sPort( i, s );
148 iPort = strtol( sPort.getStr(), NULL, 10 );
149 i = s;
150 return;
151 }
152 }
153 sHost.set( i, s );
154 i = s;
155}
156
157void Bu::Url::parsePath( Bu::FString::const_iterator &i )
158{
159 if( i )
160 {
161 Bu::FString::const_iterator s = i.find('?');
162 sPath.set( i, s );
163 i = s + 1;
164 if( s )
165 {
166 parseParams( i );
167 }
168 }
169 else
170 {
171 sPath = "/";
172 }
173}
174
175void Bu::Url::parseParams( Bu::FString::const_iterator &i )
176{
177 bool bName = true;
178 Bu::FString sName, sValue;
179 for( Bu::FString::const_iterator s = i; s; s++ )
180 {
181 if( bName )
182 {
183 if( *s == '&' )
184 {
185 sName.set( i, s );
186 sValue.clear();
187 i = s + 1;
188 addParam( decode( sName ), decode( sValue ) );
189 }
190 else if( *s == '=' )
191 {
192 sName.set( i, s );
193 i = s + 1;
194 bName = false;
195 }
196 }
197 else
198 {
199 if( *s == '&' )
200 {
201 sValue.set( i, s );
202 i = s + 1;
203 bName = true;
204 addParam( decode( sName ), decode( sValue ) );
205 }
206 }
207 }
208 if( i )
209 {
210 if( bName )
211 {
212 sName.set( i );
213 sValue.clear();
214 }
215 else
216 {
217 sValue.set( i );
218 }
219 addParam( decode( sName ), decode( sValue ) );
220 }
221}
222
223void Bu::Url::addParam( const Bu::FString &n, const Bu::FString &v )
224{
225 lParam.append( Param( n, v ) );
226}
227
228void Bu::Url::clear()
229{
230 sProtocol.clear();
231 sUser.clear();
232 sPass.clear();
233 sHost.clear();
234 sPath.clear();
235 iPort.clear();
236}
237
diff --git a/src/url.h b/src/url.h
new file mode 100644
index 0000000..861bb9f
--- /dev/null
+++ b/src/url.h
@@ -0,0 +1,74 @@
1#ifndef BU_URL_H
2#define BU_URL_H
3
4#include "bu/fstring.h"
5#include "bu/atom.h"
6
7namespace Bu
8{
9 class Url
10 {
11 public:
12 typedef struct Param
13 {
14 Param() { }
15 Param( const Param &r ) : sName( r.sName ), sValue( r.sValue ) { }
16 Param( const Bu::FString &n, const Bu::FString &v ) :
17 sName( n ), sValue( v ) { }
18 Bu::FString sName;
19 Bu::FString sValue;
20 } Param;
21 typedef Bu::List<Param> ParamList;
22
23 public:
24 Url();
25 Url( const Bu::FString &sUrl );
26 virtual ~Url();
27
28 void parseUrl( const Bu::FString &sUrl );
29 void parseParams( Bu::FString::const_iterator &i );
30 void clear();
31
32 Bu::FString getUrl();
33
34 const Bu::FString &getProtocol() { return sProtocol; }
35 const Bu::FString &getUser() { return sUser; }
36 const Bu::FString &getPass() { return sPass; }
37 const Bu::FString &getHost() { return sHost; }
38 const Bu::FString &getPath() { return sPath; }
39 int getPort() { return iPort; }
40 ParamList::const_iterator getParamBegin() { return lParam.begin(); }
41
42 void setProtocol( const Bu::FString &sNewHost, bool bAutoSetPort=true );
43 void setUser( const Bu::FString &s ) { sUser = s; }
44 void setPass( const Bu::FString &s ) { sPass = s; }
45 void setHost( const Bu::FString &s ) { sHost = s; }
46 void setPath( const Bu::FString &s ) { sPath = s; }
47 void setPort( int i ) { iPort = i; }
48 void addParam( const Bu::FString &n, const Bu::FString &v );
49
50 bool hasPort() { return iPort.has(); }
51
52 static Bu::FString decode( const Bu::FString &sStr );
53 static Bu::FString encode( const Bu::FString &sStr );
54
55 private: // Parsing code
56 void parseProtocol( Bu::FString::const_iterator &i );
57 void parseUserPass( Bu::FString::const_iterator &i );
58 void parseHost( Bu::FString::const_iterator &i );
59 void parsePath( Bu::FString::const_iterator &i );
60
61 private:
62 Bu::FString sProtocol;
63 Bu::FString sUser;
64 Bu::FString sPass;
65 Bu::FString sHost;
66 Bu::FString sPath;
67 Bu::Atom<int> iPort;
68 ParamList lParam;
69
70 static char hexcode[16];
71 };
72};
73
74#endif