00001 /********************************************************************** 00002 * File: strngs.h (Formerly strings.h) 00003 * Description: STRING class definition. 00004 * Author: Ray Smith 00005 * Created: Fri Feb 15 09:15:01 GMT 1991 00006 * 00007 * (C) Copyright 1991, Hewlett-Packard Ltd. 00008 ** Licensed under the Apache License, Version 2.0 (the "License"); 00009 ** you may not use this file except in compliance with the License. 00010 ** You may obtain a copy of the License at 00011 ** http://www.apache.org/licenses/LICENSE-2.0 00012 ** Unless required by applicable law or agreed to in writing, software 00013 ** distributed under the License is distributed on an "AS IS" BASIS, 00014 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 ** See the License for the specific language governing permissions and 00016 ** limitations under the License. 00017 * 00018 **********************************************************************/ 00019 00020 #ifndef STRNGS_H 00021 #define STRNGS_H 00022 00023 #include <string.h> 00024 #include "memry.h" 00025 #include "serialis.h" 00026 00027 // STRING_IS_PROTECTED means that string[index] = X is invalid 00028 // because you have to go through strings interface to modify it. 00029 // This allows the string to ensure internal integrity and maintain 00030 // its own string length. Unfortunately this is not possible because 00031 // STRINGS are used as direct-manipulation data buffers for things 00032 // like length arrays and many places cast away the const on string() 00033 // to mutate the string. Turning this off means that internally we 00034 // cannot assume we know the strlen. 00035 #define STRING_IS_PROTECTED 0 00036 00037 class DLLSYM STRING 00038 { 00039 public: 00040 STRING(); 00041 STRING(const STRING &string); 00042 STRING(const char *string); 00043 ~STRING (); 00044 00045 BOOL8 contains(const char c) const; 00046 inT32 length() const; 00047 const char *string() const; 00048 00049 #if STRING_IS_PROTECTED 00050 const char &operator[] (inT32 index) const; 00051 // len is number of chars in s to insert starting at index in this string 00052 void insert_range(inT32 index, const char*s, int len); 00053 void erase_range(inT32 index, int len); 00054 void truncate_at(inT32 index); 00055 #else 00056 char &operator[] (inT32 index) const; 00057 #endif 00058 00059 BOOL8 operator== (const STRING & string) const; 00060 BOOL8 operator!= (const STRING & string) const; 00061 BOOL8 operator!= (const char *string) const; 00062 00063 STRING & operator= (const char *string); 00064 STRING & operator= (const STRING & string); 00065 00066 STRING operator+ (const STRING & string) const; 00067 STRING operator+ (const char ch) const; 00068 00069 STRING & operator+= (const char *string); 00070 STRING & operator+= (const STRING & string); 00071 STRING & operator+= (const char ch); 00072 00073 // Appends the given string and int (as a %d) to this. 00074 // += cannot be used for ints as there as a char += operator that would 00075 // be ambiguous, and ints usually need a string before or between them 00076 // anyway. 00077 void add_str_int(const char* str, int number); 00078 00079 // WARNING 00080 // This method leaks the underlying pointer, 00081 // but that is what the original implementation did 00082 void prep_serialise(); 00083 00084 void dump(FILE *f); 00085 void de_dump(FILE *f); 00086 00087 make_serialise (STRING) 00088 00089 // ensure capcaity but keep pointer encapsulated 00090 inline void ensure(inT32 min_capacity) { ensure_cstr(min_capacity); } 00091 00092 private: 00093 typedef struct STRING_HEADER { 00094 // How much space was allocated in the string buffer for char data. 00095 int capacity_; 00096 00097 // used_ is how much of the capacity is currently being used, 00098 // including a '\0' terminator. 00099 // 00100 // If used_ is 0 then string is NULL (not even the '\0') 00101 // else if used_ > 0 then it is strlen() + 1 (because it includes '\0') 00102 // else strlen is >= 0 (not NULL) but needs to be computed. 00103 // this condition is set when encapsulation is violated because 00104 // an API returned a mutable string. 00105 // 00106 // capacity_ - used_ = excess capacity that the string can grow 00107 // without reallocating 00108 mutable int used_; 00109 } STRING_HEADER; 00110 00111 // To preserve the behavior of the old serialization, we only have space 00112 // for one pointer in this structure. So we are embedding a data structure 00113 // at the start of the storage that will hold additional state variables, 00114 // then storing the actual string contents immediately after. 00115 STRING_HEADER* data_; 00116 00117 // returns the header part of the storage 00118 inline STRING_HEADER* GetHeader() { 00119 return data_; 00120 } 00121 inline const STRING_HEADER* GetHeader() const { 00122 return data_; 00123 } 00124 00125 // returns the string data part of storage 00126 inline char* GetCStr() { 00127 return ((char *)data_) + sizeof(STRING_HEADER); 00128 }; 00129 00130 inline const char* GetCStr() const { 00131 return ((const char *)data_) + sizeof(STRING_HEADER); 00132 }; 00133 00134 // Ensure string has requested capacity as optimization 00135 // to avoid unnecessary reallocations. 00136 // The return value is a cstr buffer with at least requested capacity 00137 char* ensure_cstr(inT32 min_capacity); 00138 00139 void FixHeader() const; // make used_ non-negative, even if const 00140 00141 char* AllocData(int used, int capacity); 00142 void DiscardData(); 00143 }; 00144 #endif