File: GString.h

package info (click to toggle)
elph 1.0.1-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 324 kB
  • sloc: cpp: 4,142; makefile: 43; sh: 18
file content (203 lines) | stat: -rw-r--r-- 8,449 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
//---------------------------------------------------------------------------
#ifndef GStringH
#define GStringH
//---------------------------------------------------------------------------
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "GBase.h"

// This class uses reference counting and copy-on-write semantics 

// All indexes are zero-based.  For all functions that accept an index, a
// negative index specifies an index from the right of the string.  Also,
// for all functions that accept a length, a length of -1 specifies the rest
// of the string.
enum enTokenizeMode {
 tkFullString,
 tkCharSet
 };

class GString {
        friend GString operator+(const char* s1, const GString& s2);
        friend bool operator==(const char* s1, const GString& s2);
        friend bool operator<(const char* s1, const GString& s2);
        friend bool operator<=(const char* s1, const GString& s2);
        friend bool operator>(const char* s1, const GString& s2);
        friend bool operator>=(const char* s1, const GString& s2);
        friend bool operator!=(const char* s1, const GString& s2);
        friend void swap(GString& s1, GString& s2);
    public:
        GString();
        GString(const GString& s);
        GString(const char* s);
        GString(const int i);
        GString(const double f);        
        GString(char c, int n = 1);
        ~GString();
        operator const char* () const { return my_data->chars;} //inline here
        char& operator[](int index);
        char operator[](int index) const;
        GString& operator=(const GString& s);
        GString& operator=(const char* s);
        GString& operator=(const int i);
        GString& operator=(const double f);
        GString operator+(const GString& s) const;
        GString operator+(const char* s) const;
        GString operator+(const char c) const;
        GString operator+(const int i) const;
        GString operator+(const double f) const;
        bool operator==(const GString& s) const;
        bool operator==(const char* s) const;
        bool operator<(const GString& s) const;
        bool operator<(const char* s) const;
        bool operator<=(const GString& s) const;
        bool operator<=(const char* s) const;
        bool operator>(const GString& s) const;
        bool operator>(const char* s) const;
        bool operator>=(const GString& s) const;
        bool operator>=(const char* s) const;
        bool operator!=(const GString& s) const;
        bool operator!=(const char* s) const;
        GString& operator+=(const GString& s);
        GString& operator+=(const char* s);
        GString& operator+=(const char c);
        GString& operator+=(const int i);
        GString& operator+=(const double f);        
      //interface:
      public:
        int length() const;
        bool is_empty() const;
        bool is_space() const;
        GString substr(int index = 0, int len = -1) const;
        GString to(char c); //return the first part up to first occurence of c
                           //or whole string if c not found
        GString from(char c); //same as to, but starting from the right side
        GString copy() const;
        GString& format(const char *fmt,...);
        GString& appendfmt(const char *fmt,...);
        GString& cut(int index = 0, int len = -1); //delete a specified length
        //paste a string at the specified position
        GString& paste(const GString& s, int index = 0, int len=-1);
        GString& paste(const char* s, int index = 0, int len = -1);
        GString& replace(const char* from, const char* to=NULL);
        GString& insert(const GString& s, int index = 0);
        GString& insert(const char* s, int index = 0);
        GString& append(const char* s);
        GString& append(const GString& s);
        GString& upper();
        GString& lower();
        GString& clear();//make empty
        //character translation or removal:
        GString& tr(char* from, char* to=NULL);
        //number of occurences of a char in the string:
        int count(char c);
        void startTokenize(const char* delimiter, enTokenizeMode tokenizemode=tkCharSet);
        bool nextToken(GString& token);
        int asInt(int base=10);
        double asReal();
        int index(const GString& s, int start_index = 0) const;
        int index(const char* s, int start_index = 0) const;
        int index(char c, int start_index = 0) const;
        int rindex(char c) const;
        int rindex(char* str) const;
        bool contains(const GString& s) const;
        bool contains(const char* s) const;
        bool contains(char c) const;
        GString split(char* delim);
        GString split(char c);
           /* splits "this" in two parts, at the first (leftmost) 
                 encounter of delim:
                 1st would stay in "this" 
                 (which this way is truncated)
                 2nd will go to the returned string
           */
        GString splitr(char* delim);
        GString splitr(char c);
           /* splits "this" in two parts, at the last (rightmost) 
                 encounter of delim:
                 1st would stay in "this"
                 2nd will be returned
           */

        int peelInt() const; //extract an integer, (left to right), from a
                //mixed alphanumeric string, e.g. 'T24HC1234b'=> 2
        int peelIntR() const; //same as above, but starts from the right side
        //e.g. 'T2HC1234b'=> 1234
        GString& trim(char c);
        GString& trim(char* c=" \t\n\r");
        GString& trimR(char* c=" \t\n\r"); //trim only right end
        GString& trimR(char c=' ');
        GString& trimL(char* c=" \t\n\r"); //trim only left end
        GString& trimL(char c=' ');
        GString& padR(int len, char c=' '); //align it in len spaces to the right
        GString& padL(int len, char c=' '); //align it in len spaces to the left
        GString& padC(int len, char c=' '); //center it
        size_t read(FILE* stream, char* delimiter="\n", size_t bufsize=4096);
          //read next token from stream, using the given string as
          //a marker where the block should stop

        static const int max_token_size = 200;
        static const int max_line_size = 600;
        const char* chars() const;
        const char* text() const;
    protected:
        char* fTokenDelimiter;
        int fLastTokenStart;
        enTokenizeMode fTokenizeMode;
        void* readbuf; //file read buffer for the read() function
        size_t readbufsize; //last setting for the readbuf 
        static void invalid_args_error(const char* fname);
        static void invalid_index_error(const char* fname);
        struct Data {//structure holding actual
                     //string data and reference count information
               Data() { ref_count=0; length=0; chars[0] = '\0'; }
               unsigned int ref_count;
               int length;
               char chars[1];
              };
        static Data* new_data(int length); //alloc a specified length string's Data
        static Data* new_data(const char* str); //alloc a copy of a specified string
        void replace_data(int length);
        void replace_data(Data* data);
        void make_unique();
        char* chrs(); // this is dangerous, length should not be affected
        static Data null_data; //a null (empty) string Data is available here
        Data* my_data; //pointer to a Data object holding actual string data
};

/***************************************************************************/

inline int GString::length() const {
 return my_data->length;
 }


inline const char *GString::chars() const {
 return my_data->chars;
 }

inline char *GString::chrs() { //protected version, allows modification of the chars
 return my_data->chars;
 }

inline const char *GString::text() const {
 return my_data->chars;
 }


inline bool operator>=(const char *s1, const GString& s2) {
 return (strcmp(s1, s2.chars()) >= 0);
 }

inline bool operator!=(const char *s1, const GString& s2) {
 return (strcmp(s1, s2.chars()) != 0);
 }

inline void swap(GString& s1, GString& s2) {
 GString::Data *tmp = s1.my_data; s1.my_data = s2.my_data;
 s2.my_data = tmp;
 }


#endif