00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef __String_h
00015 #define __String_h
00016
00017 #include <stdarg.h>
00018 #include <stdio.h>
00019 #ifndef NOSTREAM
00020 #include <iostream.h>
00021 #endif
00022
00023 #include "Object.h"
00024 #include "ber.h"
00025
00026 class String : public Object
00027 {
00028 public:
00029 String() { Length = 0; Allocated = 0; Data = 0; }
00030 String(int init);
00031 String(const char *s);
00032 String(const char *s, int len);
00033 String(const String &s);
00034
00035
00036
00037
00038
00039 String(const String &s, int allocation_hint);
00040
00041 ~String();
00042
00043 inline int length() const;
00044 char *get();
00045 const char *get() const;
00046 operator char*() { return get(); }
00047 operator const char*() const { return get(); }
00048 operator const unsigned char*() const { return (const unsigned char*)get(); }
00049 operator int() const;
00050
00051
00052
00053
00054 int as_integer(int def = 0) const;
00055 double as_double(double def = 0) const;
00056 int empty() const { return length() == 0; }
00057
00058
00059
00060
00061
00062 void allocate(int init) {reallocate_space(init);}
00063
00064
00065
00066
00067 char *new_char() const;
00068
00069
00070
00071
00072 inline String& set(const char *s, int l) { trunc(); append(s, l); return *this; }
00073 inline String& set(char *s) { trunc(); append(s, strlen(s)); return *this; }
00074 void operator = (const String &s);
00075 void operator = (const char *s);
00076 inline void operator += (const String &s) { append(s); }
00077 inline void operator += (const char *s) { append(s); }
00078
00079
00080
00081
00082 inline String &operator << (const char *);
00083 inline String &operator << (char);
00084 inline String &operator << (unsigned char c) {return *this<<(char)c;}
00085 String &operator << (int);
00086 String &operator << (unsigned int);
00087 String &operator << (long);
00088 inline String &operator << (short i) {return *this<<(int)i;}
00089 String &operator << (const String &);
00090 String &operator << (const String *s) {return *this << *s;}
00091 inline void ber_push(int& offset, ber_t value) {
00092 int new_len = offset + BER_MAX_BYTES;
00093 int bytes = 0;
00094
00095 if(new_len + 1 >= Allocated) reallocate_space(new_len);
00096 if((bytes = ber_value2buf((unsigned char*)(Data + offset), BER_MAX_BYTES, value)) < 1) {
00097 fprintf(stderr, "String::ber_push: value2buf failed\n");
00098 } else {
00099 Length = offset + bytes;
00100 offset = Length;
00101 }
00102 }
00103
00104
00105
00106
00107 inline char &operator [] (int n);
00108 inline char operator [] (int n) const;
00109 inline char Nth (int n) { return (*this)[n]; }
00110 inline char last() const { return Length > 0 ? Data[Length - 1] : '\0'; }
00111
00112
00113
00114
00115 char operator >> (char c);
00116 inline void ber_shift(int& offset, ber_t& value) const {
00117 if(offset >= Length) {
00118 fprintf(stderr, "String::ber_shift: offset above available data\n");
00119 }
00120 int bytes = ber_buf2value((const unsigned char*)(Data + offset), Length - offset, value);
00121 if(bytes < 1) {
00122 fprintf(stderr, "String::ber_shift: ber_buf2value failed\n");
00123 }
00124 offset += bytes;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134 int compare(const Object& s) const { return compare((const String&)s); }
00135 int compare(const String& s) const;
00136 int nocase_compare(const String &s) const;
00137
00138
00139
00140
00141 int lastIndexOf(char c) const;
00142 int lastIndexOf(char c, int pos) const;
00143 int indexOf(char c) const;
00144 int indexOf(char c, int pos) const;
00145 int indexOf(const char *) const;
00146 int indexOf(const char *, int pos) const;
00147
00148
00149
00150
00151 void append(const String &s);
00152 void append(const char *s);
00153 void append(const char *s, int n);
00154 void append(char ch);
00155
00156 inline String &trunc() { Length = 0; return *this; }
00157 String &chop(int n = 1);
00158 String &chop(char ch = '\n');
00159 String &chop(const char *str = "\r\n");
00160
00161
00162
00163
00164
00165
00166 String sub(int start, int len) const;
00167 String sub(int start) const;
00168
00169
00170
00171
00172 int Write(int fd) const;
00173
00174 #ifndef NOSTREAM
00175 void debug(ostream &o);
00176 #endif
00177
00178
00179
00180
00181 friend String operator + (const String &a, const String &b);
00182 friend int operator == (const String &a, const String &b);
00183 friend int operator != (const String &a, const String &b);
00184 friend int operator < (const String &a, const String &b);
00185 friend int operator > (const String &a, const String &b);
00186 friend int operator <= (const String &a, const String &b);
00187 friend int operator >= (const String &a, const String &b);
00188
00189 #ifndef NOSTREAM
00190 friend ostream &operator << (ostream &o, const String &s);
00191
00192 friend istream &operator >> (istream &in, String &line);
00193 #endif
00194
00195 int readLine(FILE *in);
00196
00197 int lowercase();
00198 int uppercase();
00199
00200 void replace(char c1, char c2);
00201 int remove(const char *);
00202
00203 Object *Copy() const { return new String(*this); }
00204
00205
00206
00207
00208 void Serialize(String &);
00209 void Deserialize(String &, int &);
00210
00211 private:
00212 int Length;
00213 int Allocated;
00214 char *Data;
00215
00216 void copy_data_from(const char *s, int len, int dest_offset = 0);
00217 void copy(const char *s, int len, int allocation_hint);
00218
00219
00220
00221
00222 void reallocate_space(int len);
00223
00224
00225
00226
00227
00228 void allocate_space(int len);
00229
00230 void allocate_fix_space(int len);
00231
00232 friend class StringIndex;
00233 };
00234
00235 extern char *form(const char *, ...);
00236 extern char *vform(const char *, va_list);
00237
00238
00239
00240
00241 inline String &String::operator << (const char *str)
00242 {
00243 append(str);
00244 return *this;
00245 }
00246
00247 inline String &String::operator << (char ch)
00248 {
00249 append(ch);
00250 return *this;
00251 }
00252
00253 inline int String::length() const
00254 {
00255 return Length;
00256 }
00257
00258 inline char String::operator [] (int n) const
00259 {
00260 if(n < 0) n = Length + n;
00261 if(n >= Length || n < 0) return '\0';
00262
00263 return Data[n];
00264 }
00265
00266 static char null = '\0';
00267
00268 inline char &String::operator [] (int n)
00269 {
00270 if(n < 0) n = Length + n;
00271 if(n >= Length || n < 0) return null;
00272
00273 return Data[n];
00274 }
00275
00276
00277
00278
00279 #endif