home *** CD-ROM | disk | FTP | other *** search
/ PC World 1997 November / PCWorld_1997-11_cd.bin / software / programy / komix / DATA.Z / String.hxx < prev    next >
Text File  |  1996-05-31  |  15KB  |  534 lines

  1. /*---------------------------------------------------------------------------
  2.  *
  3.  *      (c)     Westmount Technology    1989, 1993
  4.  *
  5.  *      File            : @(#)String.hxx    @(#)String.hxx    1.1 (1.4) (1.7)
  6.  *      Description     : String class
  7.  *
  8.  *---------------------------------------------------------------------------
  9.  SccsId = @(#)String.hxx    1.1    (1.4) (1.7) 09 Nov 1993 */
  10.  
  11. #ifndef    STRING_HXX
  12. #define    STRING_HXX
  13.  
  14. #ifndef __STRING_H
  15. #  include <string.h>
  16. #endif
  17.  
  18. #ifndef RANGE_HXX
  19. #  include <Range.hxx>
  20. #endif
  21.  
  22. class String;
  23. class SubString;
  24. class istream;
  25. class ostream;
  26.  
  27. class StringRep            // reference counted String buffer
  28. {
  29.     friend String;
  30.  
  31.     public: // ctor, dtor, assignment
  32.     StringRep(void);
  33.     StringRep(const StringRep&);
  34.     StringRep(const char*);
  35.     StringRep(char* buf, unsigned buflen);    // buf not copied!!
  36.     ~StringRep(void);
  37.     const StringRep& operator= (const StringRep&);
  38.  
  39.     public:
  40.     operator const char* () const    { return p; }
  41.  
  42.     inline int compare(const StringRep&) const;
  43.     inline int compare(const char*) const;
  44.     inline int collate(const StringRep&) const;
  45.     inline int collate(const char*) const;
  46.  
  47.     unsigned hash(void) const;
  48.     void toAscii(void);
  49.     void toLower(void);
  50.     void toUpper(void);
  51.  
  52.     public: // reference counting
  53.     void addRef(void)        { refcount++; }
  54.     void removeRef(void)        { if ( --refcount == 0 ) delete this; }
  55.     int  shared() const        { return refcount > 1; }
  56.  
  57.     public: // buffer info
  58.     unsigned references() const    { return refcount; }
  59.     unsigned buf_len() const    { return len; }
  60.     const char* buf_ptr() const    { return p; }
  61.  
  62.     public: // buffer manipulation
  63.     void replace(const Range& r, const char* src, unsigned srclen);
  64.     void append(const char* src, unsigned srclen);
  65.  
  66.     private: // data
  67.     unsigned refcount;
  68.     unsigned len;
  69.     char*     p;
  70. };
  71.  
  72.  
  73. class SubString            // Range of characters within a string
  74. {
  75.     friend String;
  76.  
  77.     public: // comparison functions
  78.     int compare(const char*) const;
  79.     int compare(const String&) const;
  80.     int compare(const SubString&) const;
  81.  
  82.     int collate(const char*) const;
  83.     int collate(const String&) const;
  84.     int collate(const SubString&) const;
  85.  
  86.     public: // operators
  87.     inline int operator<  (const SubString& ss) const;
  88.     inline int operator>  (const SubString& ss) const;
  89.     inline int operator<= (const SubString& ss) const;
  90.     inline int operator>= (const SubString& ss) const;
  91.     inline int operator== (const SubString& ss) const;
  92.     inline int operator!= (const SubString& ss) const;
  93.  
  94.     inline int operator<  (const String&) const;
  95.     inline int operator>  (const String&) const;
  96.     inline int operator<= (const String&) const;
  97.     inline int operator>= (const String&) const;
  98.     inline int operator== (const String&) const; 
  99.     inline int operator!= (const String&) const;
  100.  
  101.     inline int operator<  (const char* cs) const;
  102.     inline int operator>  (const char* cs) const;
  103.     inline int operator<= (const char* cs) const;
  104.     inline int operator>= (const char* cs) const;
  105.     inline int operator== (const char* cs) const;
  106.     inline int operator!= (const char* cs) const;
  107.  
  108.     friend int operator<  (const char* cs, const SubString& ss);
  109.     friend int operator>  (const char* cs, const SubString& ss);
  110.     friend int operator<= (const char* cs, const SubString& ss);
  111.     friend int operator>= (const char* cs, const SubString& ss);
  112.     friend int operator== (const char* cs, const SubString& ss);
  113.     friend int operator!= (const char* cs, const SubString& ss);
  114.  
  115.     String operator+ (const String&) const;
  116.     String operator+ (const SubString&) const;
  117.     String operator+ (const char*) const;
  118.     String operator+ (char) const;
  119.  
  120.     friend String operator+ (const char*, const SubString&);
  121.     friend String operator+ (char, const SubString&);
  122.  
  123.     public: // assignment: modifies associated string
  124.     void operator= (const String&);
  125.     void operator= (const SubString&);
  126.     void operator= (const char*);
  127.  
  128.     public: // access
  129.     unsigned length() const        { return sr.length(); }
  130.     unsigned position() const    { return sr.firstIndex(); }
  131.     inline const char* ptr() const;
  132.  
  133.     public: // I/O
  134.     void dumpOn(ostream& strm) const;
  135.     void printOn(ostream& strm) const;
  136.  
  137.     protected: // constructors
  138.     SubString(const SubString& ss):    st(ss.st), sr(ss.sr) {}
  139.     SubString(const String&, const Range&);
  140.  
  141.     protected:
  142.     void checkSubStr(void) const;
  143.  
  144.     private: // data
  145.     String&    st;        // String this is a SubString of
  146.     Range    sr;        // Range of characters
  147. };
  148.  
  149.  
  150.  
  151.  
  152. class String
  153. {
  154.     friend SubString;
  155.  
  156.     protected:
  157.     void indexRangeErr(void) const;
  158.  
  159.     public: // constructors
  160.     String(void);
  161.     String(const char*);
  162.     String(const char c);
  163.     String(const char c, unsigned repeat_count);
  164.     String(const String&);
  165.     String(const SubString&);
  166.        ~String(void);
  167.  
  168.     public: // conversion
  169.     operator const char* () const    { return rep->buf_ptr(); }
  170.     const char* as_ptr() const    { return rep->buf_ptr(); }
  171.     
  172.     protected: // access to individual characters (index not checked)
  173.     char  at(unsigned i) const    { return rep->buf_ptr()[i]; }
  174.     char& at(unsigned i)        { unique(); return rep->p[i]; }
  175.  
  176.     public: // access operators ( check for overflow, see at() )
  177.     char& operator[] (unsigned i);
  178.     char  operator[] (unsigned i) const;
  179.  
  180.     public: // SubString operators
  181.     SubString    operator() (unsigned pos, unsigned lgt);
  182.     const SubString    operator() (unsigned pos, unsigned lgt) const;
  183.     SubString    operator() (const Range& r);
  184.     const SubString    operator() (const Range& r) const;
  185.  
  186.     public: // operators
  187.     void operator= (const String&);
  188.     void operator= (const SubString&);
  189.     void operator= (const char*);
  190.  
  191.     inline int operator<  (const String& s) const;
  192.     inline int operator>  (const String& s) const;
  193.     inline int operator<= (const String& s) const;
  194.     inline int operator>= (const String& s) const;
  195.     inline int operator== (const String& s) const;
  196.     inline int operator!= (const String& s) const;
  197.  
  198.     inline int operator<  (const SubString& ss) const;
  199.     inline int operator>  (const SubString& ss) const;
  200.     inline int operator<= (const SubString& ss) const;
  201.     inline int operator>= (const SubString& ss) const;
  202.     inline int operator== (const SubString& ss) const;
  203.     inline int operator!= (const SubString& ss) const;
  204.  
  205.     inline int operator<  (const char* cs) const;
  206.     inline int operator>  (const char* cs) const;
  207.     inline int operator<= (const char* cs) const;
  208.     inline int operator>= (const char* cs) const;
  209.     inline int operator== (const char* cs) const;
  210.     inline int operator!= (const char* cs) const;
  211.  
  212.     friend int operator<  (const char* cs, const String& s);
  213.     friend int operator>  (const char* cs, const String& s);
  214.     friend int operator<= (const char* cs, const String& s);
  215.     friend int operator>= (const char* cs, const String& s);
  216.     friend int operator== (const char* cs, const String& s);
  217.     friend int operator!= (const char* cs, const String& s);
  218.  
  219.     String operator+ (const String& s) const;
  220.     String operator+ (const SubString& ss) const;
  221.     String operator+ (const char* cs) const;
  222.     String operator+ (char c) const;
  223.     friend String operator+ (const char*, const String& s);
  224.     friend String operator+ (const char*, const SubString&);
  225.     friend String operator+ (char c, const String& s);
  226.     friend String operator+ (char c, const SubString& ss);
  227.  
  228.     void operator+= (const String&);
  229.     void operator+= (const SubString&);
  230.     void operator+= (const char* cs);
  231.     void operator+= (char c);
  232.     
  233.     public: // functions
  234.     unsigned length() const        { return rep->buf_len(); } 
  235.     unsigned capacity() const    { return rep->buf_len(); }
  236.  
  237.     unsigned hash(void) const    { return rep->hash(); }
  238.     void toAscii(void)        { unique(); rep->toAscii(); }
  239.     void toLower(void)        { unique(); rep->toLower(); }
  240.     void toUpper(void)        { unique(); rep->toUpper(); }
  241.  
  242.     int index(char c, unsigned start_pos =0) const;
  243.     int rindex(char c, unsigned start_pos) const;
  244.     int rindex(char c) const    { return rindex(c, rep->buf_len()); }
  245.  
  246.     void printOn(ostream& strm) const;
  247.     void scanFrom(istream& strm);
  248.  
  249.     protected: // function
  250.     void unique(void);        // copy rep if shared
  251.  
  252.     private: // data
  253.     StringRep* rep;
  254.  
  255.     static StringRep* const theEmptyRep;
  256. };
  257.  
  258.  
  259. /*
  260. ** Substring inline functions
  261. */
  262.  
  263. inline const char*
  264. SubString::ptr() const
  265.     { return &st.rep->buf_ptr()[sr.firstIndex()]; }
  266.  
  267. inline void
  268. SubString::operator=(const String& s)
  269.     { st.unique(); st.rep->replace(sr, s, s.length()); }
  270.  
  271. inline void
  272. SubString::operator=(const SubString& ss)
  273.     { st.unique(); st.rep->replace(sr, ss.ptr(), ss.length()); }
  274.  
  275. inline void
  276. SubString::operator=(const char* cs)
  277.     { st.unique(); st.rep->replace(sr, cs, strlen(cs)); }
  278.  
  279.  
  280. inline SubString
  281. String::operator() (unsigned pos, unsigned lgt)
  282.     { return SubString(*this, Range(pos, lgt)); }
  283.  
  284. inline const SubString
  285. String::operator() (unsigned pos, unsigned lgt) const
  286.     { return SubString(*this, Range(pos, lgt)); }
  287.  
  288. /*
  289. ** Comparison
  290. */
  291.  
  292. inline int
  293. StringRep::compare(const StringRep& sr) const
  294.     { return (&sr == this)? 0: strcmp(p, sr.p); }
  295.  
  296. inline int
  297. StringRep::compare(const char* cp) const
  298.     { return strcmp(p, cp); }
  299.  
  300. inline int
  301. StringRep::collate(const StringRep& sr) const
  302.     { return (&sr == this)? 0: strcoll(p, sr.p); }
  303.  
  304. inline int
  305. StringRep::collate(const char* cp) const
  306.     { return strcoll(p, cp); }
  307.  
  308.  
  309. inline int
  310. String::operator< (const String& s) const
  311.     { return rep->collate(s.rep->buf_ptr()) < 0; }
  312.  
  313. inline int
  314. SubString::operator< (const String& s) const
  315.     { return collate(s) < 0; }
  316.  
  317. inline int
  318. String::operator< (const SubString& ss) const
  319.     { return ss.collate(*this) > 0; }
  320.  
  321. inline int
  322. SubString::operator< (const SubString& ss) const
  323.     { return collate(ss) < 0; }
  324.  
  325. inline int
  326. String::operator< (const char* cp) const
  327.     { return rep->collate(cp) < 0; }
  328.  
  329. inline int
  330. SubString::operator< (const char* cp) const
  331.     { return collate(cp) < 0; }
  332.  
  333. inline int
  334. operator< (const char* cp, const String& s)
  335.     { return s.rep->collate(cp) > 0; }
  336.  
  337. inline int
  338. operator< (const char* cp, const SubString& ss)
  339.     { return ss.collate(cp) > 0; }
  340.  
  341.  
  342. inline int
  343. String::operator> (const String& s) const
  344.     { return rep->collate(s.rep->buf_ptr()) > 0; }
  345.  
  346. inline int
  347. SubString::operator> (const String& s) const
  348.     { return collate(s) > 0; }
  349.  
  350. inline int
  351. String::operator> (const SubString& ss) const
  352.     { return ss.collate(*this) < 0; }
  353.  
  354. inline int
  355. SubString::operator> (const SubString& ss) const
  356.     { return collate(ss) > 0; }
  357.  
  358. inline int
  359. String::operator> (const char* cp) const
  360.     { return rep->collate(cp) > 0; }
  361.  
  362. inline int
  363. SubString::operator> (const char* cp) const
  364.     { return collate(cp) > 0; }
  365.  
  366. inline int
  367. operator> (const char* cp, const String& s)
  368.     { return s.rep->collate(cp) < 0; }
  369.  
  370. inline int
  371. operator> (const char* cp, const SubString& ss)
  372.     { return ss.collate(cp) < 0; }
  373.  
  374.  
  375.  
  376. inline int
  377. String::operator<= (const String& s) const
  378.     { return rep->collate(s.rep->buf_ptr()) <= 0; }
  379.  
  380. inline int
  381. SubString::operator<= (const String& s) const
  382.     { return collate(s) <= 0; }
  383.  
  384. inline int
  385. String::operator<= (const SubString& ss) const
  386.     { return ss.collate(*this) >= 0; }
  387.  
  388. inline int
  389. SubString::operator<= (const SubString& ss) const
  390.     { return collate(ss) <= 0; }
  391.  
  392. inline int
  393. String::operator<= (const char* cp) const
  394.     { return rep->collate(cp) <= 0; }
  395.  
  396. inline int
  397. SubString::operator<= (const char* cp) const
  398.     { return collate(cp) <= 0; }
  399.  
  400. inline int
  401. operator<= (const char* cp, const String& s)
  402.     { return s.rep->collate(cp) >= 0; }
  403.  
  404. inline int
  405. operator<= (const char* cp, const SubString& ss)
  406.     { return ss.collate(cp) >= 0; }
  407.  
  408.  
  409. inline int
  410. String::operator>= (const String& s) const
  411.     { return rep->collate(s.rep->buf_ptr()) >= 0; }
  412.  
  413. inline int
  414. String::operator>= (const SubString& ss) const
  415.     { return ss.collate(*this) <= 0; }
  416.  
  417. inline int
  418. String::operator>= (const char* cp) const
  419.     { return rep->collate(cp) >= 0; }
  420.  
  421. inline int
  422. SubString::operator>= (const String& s) const
  423.     { return collate(s) >= 0; }
  424.  
  425. inline int
  426. SubString::operator>= (const SubString& ss) const
  427.     { return collate(ss) >= 0; }
  428.  
  429. inline int
  430. SubString::operator>= (const char* cp) const
  431.     { return collate(cp) <= 0; }
  432.  
  433. inline int
  434. operator>= (const char* cp, const String& s)
  435.     { return s.rep->collate(cp) >= 0; }
  436.  
  437. inline int
  438. operator>= (const char* cp, const SubString& ss)
  439.     { return ss.collate(cp) >= 0; }
  440.  
  441.  
  442. inline int
  443. String::operator== (const String& s) const
  444.     { return rep->compare(s.rep->buf_ptr()) == 0; }
  445.  
  446. inline int
  447. String::operator== (const SubString& ss) const
  448.     { return ss.compare(*this) == 0; }
  449.  
  450. inline int
  451. String::operator== (const char* cp) const
  452.     { return rep->compare(cp) == 0; }
  453.  
  454. inline int
  455. SubString::operator== (const String& s) const
  456.     { return compare(s) == 0; }
  457.  
  458. inline int
  459. SubString::operator== (const SubString& ss) const
  460.     { return compare(ss) == 0; }
  461.  
  462. inline int
  463. SubString::operator== (const char* cp) const
  464.     { return compare(cp) == 0; }
  465.  
  466. inline int
  467. operator== (const char* cp, const String& s)
  468.     { return s.rep->compare(cp) == 0; }
  469.  
  470. inline int
  471. operator== (const char* cp, const SubString& ss)
  472.     { return ss.compare(cp) == 0; }
  473.  
  474.  
  475. inline int
  476. String::operator!= (const String& s) const
  477.     { return rep->compare(s.rep->buf_ptr()) != 0; }
  478.  
  479. inline int
  480. String::operator!= (const SubString& ss) const
  481.     { return ss.compare(*this) != 0; }
  482.  
  483. inline int
  484. String::operator!= (const char* cp) const
  485.     { return rep->compare(cp) != 0; }
  486.  
  487. inline int
  488. SubString::operator!= (const String& s) const
  489.     { return compare(s) != 0; }
  490.  
  491. inline int
  492. SubString::operator!= (const SubString& ss) const
  493.     { return compare(ss) != 0; }
  494.  
  495. inline int
  496. SubString::operator!= (const char* cp) const
  497.     { return compare(cp) != 0; }
  498.  
  499. inline int
  500. operator!= (const char* cp, const String& s)
  501.     { return s.rep->compare(cp) != 0; }
  502.  
  503. inline int
  504. operator!= (const char* cp, const SubString& ss)
  505.     { return ss.compare(cp) != 0; }
  506.  
  507.  
  508. /*
  509. ** Stream I/O
  510. */
  511.  
  512. inline istream&
  513. operator>> (istream& strm, String& s)
  514. {
  515.     s.scanFrom(strm);
  516.     return strm;
  517. }
  518.  
  519. inline ostream&
  520. operator<< (ostream& strm, const String& s)
  521. {
  522.     s.printOn(strm);
  523.     return(strm);
  524. }
  525.  
  526. inline ostream&
  527. operator<< (ostream& strm, const SubString& ss)
  528. {
  529.     ss.printOn(strm);
  530.     return(strm);
  531. }
  532.  
  533. #endif
  534.