00001 // 00002 // htString.h 00003 // 00004 // htString: (implementation in String.cc) Just Another String class. 00005 // 00006 // Part of the ht://Dig package <http://www.htdig.org/> 00007 // Copyright (c) 1999, 2000, 2001 The ht://Dig Group 00008 // For copyright details, see the file COPYING in your distribution 00009 // or the GNU General Public License version 2 or later 00010 // <http://www.gnu.org/copyleft/gpl.html> 00011 // 00012 // $Id: htString_8h-source.html,v 1.1 2008年06月08日 10:19:41 sebdiaz Exp $ 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 /* NOSTREAM */ 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; } // Create an empty string 00030 String(int init); // initial allocated length 00031 String(const char *s); // from null terminated s 00032 String(const char *s, int len); // from s with length len 00033 String(const String &s); // Copy constructor 00034 00035 // 00036 // This can be used for performance reasons if it is known the 00037 // String will need to grow. 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 // Interpretation 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 // If it is not posible to use the constructor with an initial 00060 // allocation size, use the following member to set the size. 00061 // 00062 void allocate(int init) {reallocate_space(init);} 00063 00064 // 00065 // allocate space for a new char *, and copy the String in. 00066 // 00067 char *new_char() const; 00068 00069 // 00070 // Assignment 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 // Appending 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 // Access to specific characters 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 // Removing 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 // Comparison 00129 // Return: 00130 // 0 : 'this' is equal to 's'. 00131 // -1 : 'this' is less than 's'. 00132 // 1 : 'this' is greater than 's'. 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 // Searching for parts 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 // Manipulation 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 // SubStrings 00163 // 00164 // The string starting at postion 'start' and length 'len'. 00165 // 00166 String sub(int start, int len) const; 00167 String sub(int start) const; 00168 00169 // 00170 // IO 00171 // 00172 int Write(int fd) const; 00173 00174 #ifndef NOSTREAM 00175 void debug(ostream &o); 00176 #endif /* NOSTREAM */ 00177 00178 // 00179 // Non-member operators 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 /* NOSTREAM */ 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 // Persistent storage support 00207 // 00208 void Serialize(String &); 00209 void Deserialize(String &, int &); 00210 00211 private: 00212 int Length; // Current Length 00213 int Allocated; // Total space allocated 00214 char *Data; // The actual contents 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 // Possibly make Data bigger. 00221 // 00222 void reallocate_space(int len); 00223 00224 // 00225 // Allocate some space for the data. Delete Data if it 00226 // has been allocated. 00227 // 00228 void allocate_space(int len); 00229 // Allocate some space without rounding 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 // Inline methods. 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 // Non friend, non member operators 00278 // 00279 #endif