1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // Chain.cc
4 // ---------
5 // String class implementation
6 //
7 // Design and Implementation by Bjoern Lemke
8 //
9 // (C)opyright 2000-2016 Bjoern Lemke
10 //
11 // IMPLEMENTATION MODULE
12 //
13 // Class: Chain
14 //
15 // Description: All operations on strings
16 //
17 // Status: CLEAN
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20
21 // SYSTEM INCLUDES
22 #include <stdlib.h>
23 #include <ctype.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <wctype.h>
28
29 // BASE INCLUDES
30 #include "Exception.h"
31 #include "Chain.h"
32
33 // DEFINES
34 #define TMPBUFSIZE 100
35 #define INBUFSIZE 100
36
Chain()37 Chain::Chain()
38 {
39 _buf = 0;
40 _len = 0;
41 }
42
Chain(const char * s)43 Chain::Chain(const char *s)
44 {
45 _buf = 0;
46 _len = 0;
47
48 if ( s == 0 )
49 {
50 return;
51 }
52
53 size_t sl = strlen(s) + 1;
54
55 if ( sl < STATICBUFSIZE )
56 {
57 _buf = _staticBuf;
58 }
59 else
60 {
61 _buf = (char*)malloc(sl);
62 if ( _buf == 0 )
63 {
64 throw Exception(EXLOC, "Malloc system error");
65 }
66 }
67 strcpy(_buf, s);
68 _len=sl;
69 }
70
Chain(const char * s,int len)71 Chain::Chain(const char *s, int len)
72 {
73 _buf = 0;
74 _len = 0;
75
76 if ( s == 0 )
77 {
78 return;
79 }
80
81 if ( len+1 < STATICBUFSIZE )
82 {
83 _buf = _staticBuf;
84 }
85 else
86 {
87 _buf = (char*)malloc(len+1);
88
89 if ( _buf == 0 )
90 {
91 throw Exception(EXLOC, "Malloc system error");
92 }
93 }
94
95 memcpy(_buf, s, len);
96 _buf[len]=0;
97 _len=len+1;
98 }
99
Chain(const Chain & str)100 Chain::Chain(const Chain& str)
101 {
102 _len = 0;
103 _buf = 0;
104
105 *this = str;
106 }
107
Chain(const char c)108 Chain::Chain(const char c)
109 {
110 _buf = 0;
111 _len = 0;
112
113 if ( c > 0 )
114 {
115 _buf = _staticBuf;
116 _buf[0]=c;
117 _buf[1]=0;
118 _len=2;
119 }
120 }
121
Chain(long l)122 Chain::Chain(long l)
123 {
124 char tmpBuf[TMPBUFSIZE];
125
126 _len = snprintf(tmpBuf, TMPBUFSIZE, "%ld", l);
127 if ( _len > TMPBUFSIZE )
128 {
129 throw Exception(EXLOC, "Temp buf size exceeded");
130 }
131
132 _len++;
133
134 if (_len > STATICBUFSIZE )
135 {
136 throw Exception(EXLOC, "Static buf size exceeded");
137 }
138
139 _buf = _staticBuf;
140
141 strcpy(_buf, tmpBuf);
142 }
143
Chain(long long ll)144 Chain::Chain(long long ll)
145 {
146 char tmpBuf[TMPBUFSIZE];
147
148 _len = snprintf(tmpBuf, TMPBUFSIZE, "%lld", ll);
149 if ( _len > TMPBUFSIZE )
150 {
151 throw Exception(EXLOC, "Temp buf size exceeded");
152 }
153
154 _len++;
155
156 if (_len > STATICBUFSIZE )
157 {
158 throw Exception(EXLOC, "Static buf size exceeded");
159 }
160
161 _buf = _staticBuf;
162
163 strcpy(_buf, tmpBuf);
164 }
165
Chain(unsigned long l)166 Chain::Chain(unsigned long l)
167 {
168 char tmpBuf[TMPBUFSIZE];
169
170 _len = snprintf(tmpBuf, TMPBUFSIZE, "%lu", l);
171 if ( _len > TMPBUFSIZE )
172 {
173 throw Exception(EXLOC, "Temp buf size exceeded");
174 }
175
176 _len++;
177
178 if (_len > STATICBUFSIZE )
179 {
180 throw Exception(EXLOC, "Static buf size exceeded");
181 }
182
183 _buf = _staticBuf;
184
185 strcpy(_buf, tmpBuf);
186 }
187
Chain(unsigned long long ull)188 Chain::Chain(unsigned long long ull)
189 {
190 char tmpBuf[TMPBUFSIZE];
191
192 _len = snprintf(tmpBuf, TMPBUFSIZE, "%llu", ull);
193 if ( _len > TMPBUFSIZE )
194 {
195 throw Exception(EXLOC, "Temp buf size exceeded");
196 }
197
198 _len++;
199
200 if (_len > STATICBUFSIZE )
201 {
202 throw Exception(EXLOC, "Static buf size exceeded");
203 }
204
205 _buf = _staticBuf;
206
207 strcpy(_buf, tmpBuf);
208 }
209
Chain(unsigned ui)210 Chain::Chain(unsigned ui)
211 {
212 char tmpBuf[TMPBUFSIZE];
213
214 _len = snprintf(tmpBuf, TMPBUFSIZE, "%u", ui);
215 if ( _len > TMPBUFSIZE )
216 {
217 throw Exception(EXLOC, "Temp buf size exceeded");
218 }
219
220 _len++;
221
222 if (_len > STATICBUFSIZE )
223 {
224 throw Exception(EXLOC, "Static buf size exceeded");
225 }
226
227 _buf = _staticBuf;
228
229 strcpy(_buf, tmpBuf);
230 }
231
Chain(int i)232 Chain::Chain(int i)
233 {
234 char tmpBuf[TMPBUFSIZE];
235
236 _len = snprintf(tmpBuf, TMPBUFSIZE, "%d", i);
237 if ( _len > TMPBUFSIZE )
238 {
239 throw Exception(EXLOC, "Temp buf size exceeded");
240 }
241
242 _len++;
243
244 if (_len > STATICBUFSIZE )
245 {
246 throw Exception(EXLOC, "Static buf size exceeded");
247 }
248
249 _buf = _staticBuf;
250
251 strcpy(_buf, tmpBuf);
252 }
253
Chain(float f)254 Chain::Chain(float f)
255 {
256 char tmpBuf[TMPBUFSIZE];
257
258 int l = snprintf(tmpBuf, TMPBUFSIZE, "%f", f);
259 if ( l > TMPBUFSIZE )
260 {
261 throw Exception(EXLOC, "Temp buf size exceeded");
262 }
263
264 if ( l < 0 )
265 {
266 throw Exception(EXLOC, "Invalid format for float value");
267 }
268
269 _len = l+1;
270
271 if (_len > STATICBUFSIZE )
272 {
273 throw Exception(EXLOC, "Static buf size exceeded");
274 }
275
276 _buf = _staticBuf;
277
278 strcpy(_buf, tmpBuf);
279 }
280
Chain(double d,const char * format)281 Chain::Chain(double d, const char* format)
282 {
283 char tmpBuf[TMPBUFSIZE];
284
285 int l = snprintf(tmpBuf, TMPBUFSIZE, format, d);
286 if ( l > TMPBUFSIZE )
287 {
288 throw Exception(EXLOC, "Temp buf size exceeded");
289 }
290
291 if ( l < 0 )
292 {
293 throw Exception(EXLOC, "Invalid format for double value");
294 }
295 _len = l+1;
296
297 if (_len > STATICBUFSIZE )
298 {
299 throw Exception(EXLOC, "Static buf size exceeded");
300 }
301
302 _buf = _staticBuf;
303
304 strcpy(_buf, tmpBuf);
305 }
306
~Chain()307 Chain::~Chain()
308 {
309 if (_buf != 0 && _buf != _staticBuf)
310 {
311 free(_buf);
312 }
313 _buf = 0;
314 _len = 0;
315 }
316
setData(char * s)317 void Chain::setData(char* s)
318 {
319 _buf = s;
320 _len=strlen(s)+1;
321 }
322
length() const323 unsigned long Chain::length() const
324 {
325 return _len;
326 }
327
visibleLength() const328 unsigned long Chain::visibleLength() const
329 {
330 unsigned long vlen=0;
331 unsigned long i=0;
332
333 wchar_t t;
334 int result;
335 while ( ( result = mbtowc(&t, _buf+i, MB_CUR_MAX)) > 0 && i < _len-1 )
336 {
337 i+=result;
338 vlen++;
339 }
340 vlen++;
341 return vlen;
342 }
343
toUpper() const344 Chain Chain::toUpper() const
345 {
346 Chain s = *this;
347
348 /*
349 unsigned long i=0;
350 while ( i<_len )
351 {
352 s._buf[i] = toupper(s._buf[i]);
353 i++;
354 }
355 */
356
357
358 wchar_t* wText = new wchar_t[_len];
359 ::mbstowcs(wText, _buf, _len);
360
361 unsigned long i=0;
362 wchar_t c;
363 while (wText[i])
364 {
365 c = wText[i];
366 wText[i] = towupper(c);
367 i++;
368 }
369
370 ::wcstombs(s._buf, wText, _len);
371 free(wText);
372
373 return s;
374 }
375
toLower() const376 Chain Chain::toLower() const
377 {
378 Chain s = *this;
379
380 /*
381 unsigned long i=0;
382 while ( i <_len )
383 {
384 s._buf[i] = tolower(s._buf[i]);
385 i++;
386 }
387 */
388
389 wchar_t* wText = new wchar_t[_len];
390 ::mbstowcs(wText, _buf, _len);
391
392 unsigned long i=0;
393 wchar_t c;
394 while (wText[i])
395 {
396 c = wText[i];
397 wText[i] = towlower(c);
398 i++;
399 }
400
401 ::wcstombs(s._buf, wText, _len);
402 free(wText);
403
404
405 return s;
406 }
407
asUnsigned(bool doStrict) const408 int Chain::asUnsigned(bool doStrict) const
409 {
410 if ( _buf == 0 )
411 return 0;
412
413 long l = strtol(_buf, NULL, 0);
414
415 if ( doStrict )
416 {
417 if ( l == 0 && errno == EINVAL )
418 {
419 Chain msg = Chain("Integer conversion error : ") + Chain(strerror(errno));
420 throw Exception(EXLOC, msg);
421 }
422 }
423
424 if ( l > INT_MAX || l < 0 )
425 {
426 Chain msg = Chain("Integer conversion error : Out of range");
427 throw Exception(EXLOC, msg);
428 }
429
430 unsigned ui = (unsigned)l;
431 return ui;
432 }
433
asInteger(bool doStrict) const434 int Chain::asInteger(bool doStrict) const
435 {
436 if ( _buf == 0 )
437 return 0;
438
439 long l = strtol(_buf, NULL, 0);
440
441 if ( doStrict )
442 {
443 if ( l == 0 && errno == EINVAL )
444 {
445 Chain msg = Chain("Integer conversion error : ") + Chain(strerror(errno));
446 throw Exception(EXLOC, msg);
447 }
448 }
449
450 if ( l > INT_MAX || l < INT_MIN )
451 {
452 Chain msg = Chain("Integer conversion error : Out of range");
453 throw Exception(EXLOC, msg);
454 }
455
456 int i = (int)l;
457 return i;
458 }
459
asLong(bool doStrict) const460 long Chain::asLong(bool doStrict) const
461 {
462 if ( _buf == 0 )
463 return 0;
464
465 if ( doStrict )
466 {
467 long l = strtol(_buf, NULL, 0);
468 if ( l == 0 && errno == EINVAL )
469 {
470 Chain msg = Chain("Long conversion error : ") + Chain(strerror(errno));
471 throw Exception(EXLOC, msg);
472 }
473 return l;
474 }
475 else
476 {
477 return strtol(_buf, NULL, 0);
478 }
479 }
480
asUnsignedLong(bool doStrict) const481 unsigned long Chain::asUnsignedLong(bool doStrict) const
482 {
483 if ( _buf == 0 )
484 return 0;
485
486 if ( doStrict )
487 {
488 unsigned long ul = strtoul(_buf, NULL, 0);
489 if ( ul == 0 && errno == EINVAL )
490 {
491 Chain msg = Chain("Unsigned long conversion error : ") + Chain(strerror(errno));
492 throw Exception(EXLOC, msg);
493 }
494 return ul;
495 }
496 else
497 {
498 return strtoul(_buf, NULL, 0);
499 }
500 }
501
asLongLong(bool doStrict) const502 long long Chain::asLongLong(bool doStrict ) const
503 {
504 if ( _buf == 0 )
505 return 0;
506
507 if ( doStrict )
508 {
509 long long ll = strtoll(_buf, NULL, 0);
510 if ( ll == 0 && errno == EINVAL)
511 {
512 Chain msg = Chain("Long long conversion error : ") + Chain(strerror(errno));
513 throw Exception(EXLOC, msg);
514 }
515 return ll;
516 }
517 else
518 {
519 return strtoll(_buf, NULL, 0);
520 }
521 }
522
asUnsignedLongLong(bool doStrict) const523 unsigned long long Chain::asUnsignedLongLong(bool doStrict) const
524 {
525 if ( _buf == 0 )
526 return 0;
527
528 if ( doStrict )
529 {
530 unsigned long long ull = strtoull(_buf, NULL, 0);
531 if ( ull == 0 && errno == EINVAL)
532 {
533 Chain msg = Chain("Unsigned long long conversion error : ") + Chain(strerror(errno));
534 throw Exception(EXLOC, msg);
535 }
536 return ull;
537 }
538 else
539 {
540 return strtoull(_buf, NULL, 0);
541 }
542 }
543
asFloat() const544 float Chain::asFloat() const
545 {
546 if ( _buf == 0 )
547 return 0.0;
548
549 float f;
550 if ( sscanf((char*)(_buf), "%f", &f) == 0 )
551 throw Exception(EXLOC, "Cannot convert to float");
552 return f;
553 }
554
asDouble() const555 double Chain::asDouble() const
556 {
557 if ( _buf == 0 )
558 return (double)0.0;
559
560 double d;
561 if ( sscanf((char*)(_buf), "%lf", &d) == 0 )
562 throw Exception(EXLOC, "Cannot convert to double");
563 return d;
564 }
565
asShort() const566 short Chain::asShort() const
567 {
568 if ( _buf == 0 )
569 return 0;
570
571 short s;
572 if ( sscanf((char*)(_buf), "%hd", &s) == 0 )
573 throw Exception(EXLOC, "Cannot convert to short");
574 return s;
575 }
576
asChar() const577 char Chain::asChar() const
578 {
579 if ( _buf == 0 )
580 return 0;
581
582 char c;
583 if ( sscanf((char*)(_buf), "%c", &c) == 0 )
584 throw Exception(EXLOC, "Cannot convert to char");
585 return c;
586 }
587
asBool() const588 bool Chain::asBool() const
589 {
590 if ( _buf == 0 )
591 return false;
592
593 if ( Chain(_buf) == Chain("true") || Chain(_buf) == Chain("yes") || Chain(_buf) == Chain("Y") || atoi(_buf) > 0 )
594 return true;
595 return false;
596 }
597
isNum() const598 bool Chain::isNum() const
599 {
600 if ( _len > 1 )
601 {
602 unsigned long i=0;
603 while ( i < _len-1 )
604 {
605 if ( ! isdigit(_buf[i]) )
606 return false;
607 i++;
608 }
609 return true;
610 }
611 return false;
612 }
613
isDec() const614 bool Chain::isDec() const
615 {
616 unsigned long i=0;
617 bool dotRead = false;
618 while ( i < _len-1 )
619 {
620 if ( ! isdigit(_buf[i]) )
621 {
622 if ( _buf[i] == '.' && dotRead == false )
623 dotRead = true;
624 else
625 return false;
626 }
627 i++;
628 }
629 return true;
630 }
631
cutTrailing(const Chain & str) const632 Chain Chain::cutTrailing(const Chain& str) const
633 {
634 if ( _len > 1 )
635 {
636 int i, l,u;
637
638 l=0;
639 u=_len-1;
640 i=0;
641 while (i < str._len && l < _len)
642 {
643 if (_buf[l] == str._buf[i])
644 {
645 l++;
646 i=0;
647 }
648 else
649 {
650 i++;
651 }
652 }
653
654 i=0;
655 while (i < str._len && u > 0)
656 {
657 if (_buf[u] == str._buf[i])
658 {
659 u--;
660 i=0;
661 }
662 else
663 {
664 i++;
665 }
666 }
667 if (l <= u)
668 return subChain(l+1, u+1);
669 else
670 return Chain();
671 }
672 return *this;
673 }
674
truncLeft(const Chain & str) const675 Chain Chain::truncLeft(const Chain& str) const
676 {
677 if ( _len > 1 )
678 {
679 int i, l;
680
681 l=0;
682 i=0;
683 while (i < str._len && l < _len)
684 {
685 if (_buf[l] == str._buf[i])
686 {
687 l++;
688 i=0;
689 }
690 else
691 {
692 i++;
693 }
694 }
695 if ( l < _len )
696 return subChain(l+1, _len);
697 else
698 return Chain("");
699 }
700 return *this;
701 }
702
truncRight(const Chain & str) const703 Chain Chain::truncRight(const Chain& str) const
704 {
705 if ( _len > 1 )
706 {
707 int i, u;
708
709 u=_len-1;
710 i=0;
711 while (i < str._len && u >= 0)
712 {
713 if (_buf[u] == str._buf[i])
714 {
715 u--;
716 i=0;
717 }
718 else
719 {
720 i++;
721 }
722 }
723
724 if ( u >= 0 )
725 return subChain(1, u+1);
726 else
727 return Chain("");
728 }
729 return *this;
730 }
731
posStr(const Chain & s1,int & result,int start,int occur) const732 bool Chain::posStr(const Chain& s1, int& result, int start, int occur) const
733 {
734 int ocount=1;
735 if ( start >=0 )
736 {
737 for (int i=start; i<_len; i++)
738 {
739 if ( matchAtPos(s1, i) )
740 {
741 if ( ocount == occur )
742 {
743 result = i + 1;
744 return true;
745 }
746 else
747 ocount++;
748 }
749 }
750 }
751 else
752 {
753 for (int i=_len-1; i>0; i--)
754 {
755 if ( matchAtPos(s1, i) )
756 {
757 if ( ocount == occur )
758 {
759 result = i + 1;
760 return true;
761 }
762 else
763 ocount++;
764 }
765 }
766 }
767 return false;
768 }
769
matchAtPos(const Chain & s1,int pos) const770 bool Chain::matchAtPos(const Chain& s1, int pos) const
771 {
772 if ( _buf[pos] == s1[0] )
773 {
774 int j=0;
775 bool match = true;
776 while (match && j < s1.length()-1 && pos+j < _len)
777 {
778 if ( _buf[pos+j] != s1[j] )
779 {
780 match = false;
781 }
782 else
783 {
784 j++;
785 }
786 }
787 if (match && j == s1.length()-1)
788 {
789 return true;
790 }
791 }
792
793 return false;
794 }
795
replace(const Chain & s1,const Chain & s2,Chain & result) const796 bool Chain::replace(const Chain& s1, const Chain& s2, Chain& result) const
797 {
798 for (int i=0; i<_len; i++)
799 {
800 if ( _buf[i] == s1[0] )
801 {
802 int j=0;
803 bool match = true;
804 while (match && j < s1.length()-1 && i+j < _len)
805 {
806 if ( _buf[i+j] != s1[j] )
807 {
808 match = false;
809 }
810 else
811 {
812
813 j++;
814 }
815 }
816 if (match && j == s1.length()-1)
817 {
818
819 Chain a, c;
820 if (i > 0)
821 {
822 a = subChain(1,i);
823 }
824 if (i+j < _len)
825 {
826 c = subChain(i+1+j, _len);
827 }
828
829 result = a + s2 + c;
830
831 return true;
832 }
833 }
834 }
835 return false;
836 }
837
replaceAll(const Chain & s1,const Chain & s2,Chain & result) const838 int Chain::replaceAll(const Chain& s1, const Chain& s2, Chain& result) const
839 {
840 Chain target;
841 int count=0;
842 int l=0;
843 Chain c;
844 int i=0;
845 while( i<_len )
846 {
847 if ( _buf[i] == s1[0] )
848 {
849 int j=0;
850 bool match = true;
851 while (match && j < s1.length()-1 && i+j < _len)
852 {
853 if ( _buf[i+j] != s1[j] )
854 {
855 match = false;
856 }
857 else
858 {
859 j++;
860 }
861 }
862 if (match && j == s1.length()-1)
863 {
864 Chain a;
865 if (i > l)
866 {
867 a = subChain(l+1,i);
868 }
869 if (i+j < _len)
870 {
871 c = subChain(i+j+1, _len);
872 }
873 target += a + s2;
874 count++;
875 l=i+j;
876 i=l;
877 }
878 else
879 {
880 i++;
881 }
882 }
883 else
884 {
885 i++;
886 }
887 }
888 target += c;
889
890 if ( count > 0 )
891 result = target;
892 else
893 result = *this;
894 return count;
895 }
896
setChar(int i,char c)897 void Chain::setChar(int i, char c)
898 {
899 _buf[i] = c;
900 }
901
getHashPos(int hashSize) const902 int Chain::getHashPos(int hashSize) const
903 {
904 int val=0;
905 for ( int i=0; i<_len; i++)
906 {
907 val += (int)_buf[i] ;
908 }
909 return ( val * ( hashSize / 100 + 1)) % hashSize;
910 }
911
subChain(int l,int u) const912 Chain Chain::subChain(int l, int u) const
913 {
914
915 if (l >= 0 && u <= _len && l <= u)
916 {
917 char *tmpBuf = (char*)malloc(u-l+2);
918
919 if ( _buf == 0 )
920 {
921 throw Exception(EXLOC, "Malloc system error");
922 }
923 else
924 {
925 memcpy(tmpBuf,(char*)(this->_buf+l-1), u-l+1);
926 tmpBuf[u-l+1]='\0';
927 Chain tmpChain(tmpBuf);
928 free(tmpBuf);
929 return tmpChain;
930 }
931 }
932 else
933 {
934 throw Exception(EXLOC, "String position exceeded");
935 }
936 }
937
operator [](int i) const938 char Chain::operator [] (int i) const
939 {
940 if (i < _len)
941 {
942 return _buf[i];
943 }
944 else
945 {
946 throw Exception(EXLOC, "String position exceeded");
947 }
948 }
949
operator char*() const950 Chain::operator char* () const
951 {
952 return _buf;
953 }
954
operator =(const Chain & str)955 Chain& Chain::operator=(const Chain& str)
956 {
957
958 if (str._len == 0)
959 {
960 if (_len > 0)
961 {
962 if ( _buf != 0 && _buf != _staticBuf )
963 free(_buf);
964 _buf = 0;
965 _len = 0;
966 }
967 }
968 else if ( str._len <= _len)
969 {
970 strcpy (_buf, str._buf);
971 _len = str._len;
972 }
973 else
974 {
975
976 if (_len > 0)
977 {
978 if ( _buf != 0 && _buf != _staticBuf )
979 free(_buf);
980 _buf = 0;
981 _len = 0;
982 }
983
984 if ( str._len + 1 < STATICBUFSIZE )
985 {
986 _buf = _staticBuf;
987 }
988 else
989 {
990
991 _buf = (char*)malloc(str._len + 1);
992
993 if ( _buf == 0 )
994 {
995 throw Exception(EXLOC, "Malloc system error");
996 }
997 }
998
999 strcpy(_buf, str._buf);
1000 _len=str._len;
1001 }
1002 return (*this);
1003 }
1004
operator +=(const Chain & str)1005 Chain& Chain::operator += (const Chain& str)
1006 {
1007
1008 if ( str._len == 0 )
1009 {
1010 // nothing to do
1011 }
1012 else if ( _len == 0 )
1013 {
1014 *this = str; // just copy
1015 }
1016 else
1017 {
1018
1019 if ( _len + str._len - 1 < STATICBUFSIZE )
1020 {
1021 strcpy((char*)(_buf + _len - 1), str._buf);
1022 _len = _len + str._len -1;
1023 }
1024 else
1025 {
1026 char *tmpBuf = (char*)malloc(_len + str._len -1);
1027 if ( tmpBuf == 0 )
1028 {
1029 throw Exception(EXLOC, "Malloc system error");
1030 }
1031
1032 strcpy(tmpBuf, _buf);
1033
1034 if ( _buf != _staticBuf )
1035 free(_buf);
1036
1037 _buf = tmpBuf;
1038 strcpy((char*)(_buf + _len - 1), str._buf);
1039 _len = _len + str._len -1;
1040
1041 }
1042 }
1043
1044 return (*this);
1045 }
1046
operator ==(const Chain & str) const1047 bool Chain::operator==(const Chain& str) const
1048 {
1049
1050 if (str._buf && _buf)
1051 {
1052 if (!strcmp(str._buf, _buf))
1053 {
1054 return(true);
1055 }
1056 return (false);
1057 }
1058 return ( str._buf == _buf );
1059 }
1060
operator !=(const Chain & str) const1061 bool Chain::operator!=(const Chain& str) const
1062 {
1063 if (str._buf && _buf)
1064 {
1065 if (strcmp(str._buf, _buf))
1066 {
1067
1068 return(true);
1069 }
1070 return (false);
1071 }
1072 return ( str._buf != _buf );
1073 }
1074
operator <(const Chain & str) const1075 bool Chain::operator < (const Chain& str) const
1076 {
1077 if (str._buf && _buf)
1078 {
1079 if (strcmp(str._buf, _buf) > 0)
1080 {
1081 return(true);
1082 }
1083 return (false);
1084 }
1085 return ( str._buf != _buf );
1086 }
1087
operator >(const Chain & str) const1088 bool Chain::operator > (const Chain& str) const
1089 {
1090 if (str._buf && _buf)
1091 {
1092 if (strcmp(str._buf, _buf) < 0 )
1093 {
1094
1095 return(true);
1096 }
1097 return (false);
1098 }
1099 return ( str._buf != _buf );
1100 }
1101
operator <=(const Chain & str) const1102 bool Chain::operator <= (const Chain& str) const
1103 {
1104 if (str._buf && _buf)
1105 {
1106 if (strcmp(str._buf, _buf) >= 0)
1107 {
1108 return(true);
1109 }
1110 return (false);
1111 }
1112 return ( str._buf != _buf );
1113 }
1114
operator >=(const Chain & str) const1115 bool Chain::operator >= (const Chain& str) const
1116 {
1117 if (str._buf && _buf)
1118 {
1119 if (strcmp(str._buf, _buf) <= 0 )
1120 {
1121 return(true);
1122 }
1123 return (false);
1124 }
1125 return ( str._buf != _buf );
1126 }
1127
operator +(const Chain & str1,const Chain & str2)1128 Chain operator+( const Chain& str1, const Chain& str2)
1129 {
1130 Chain str3;
1131 str3 = str1;
1132 str3 += str2;
1133 return (str3);
1134 }
1135
operator <<(ostream & s,const Chain & str)1136 ostream& operator << (ostream& s, const Chain& str)
1137 {
1138 if ( str._buf != 0)
1139 s << str._buf;
1140 return s;
1141 }
1142
operator >>(istream & s,Chain & str)1143 istream& operator >> (istream& s, Chain& str)
1144 {
1145 char buf[INBUFSIZE];
1146 cin.getline(buf, INBUFSIZE);
1147 str = Chain(buf);
1148 return s;
1149 }
1150