1/* 2 * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * All rights reserved. Distributed under the terms of the MIT license. 4 */ 5#ifndef STRING_H 6#define STRING_H 7 8#include <SupportDefs.h> 9#include <string.h> 10#include <new> 11 12 13// string_hash 14// 15// from the Dragon Book: a slightly modified hashpjw() 16static inline 17uint32 18string_hash(const char *name) 19{ 20 uint32 h = 0; 21 if (name) { 22 for (; *name; name++) { 23 uint32 g = h & 0xf0000000; 24 if (g) 25 h ^= g >> 24; 26 h = (h << 4) + *name; 27 } 28 } 29 return h; 30} 31 32#ifdef __cplusplus 33 34// String 35class String { 36public: 37 inline String(); 38 inline String(const String &string); 39 inline String(const char *string, int32 length = -1); 40 inline ~String(); 41 42 inline bool SetTo(const char *string, int32 maxLength = -1); 43 inline void Unset(); 44 45 inline void Truncate(int32 newLength); 46 47 inline const char *GetString() const; 48 inline int32 GetLength() const { return fLength; } 49 50 inline uint32 GetHashCode() const { return string_hash(GetString()); } 51 52 inline String &operator=(const String &string); 53 inline bool operator==(const String &string) const; 54 inline bool operator!=(const String &string) const { return !(*this == string); } 55 56private: 57 inline bool _SetTo(const char *string, int32 length); 58 59private: 60 int32 fLength; 61 char *fString; 62}; 63 64/*! 65 \class String 66 \brief A very simple string class. 67*/ 68 69// constructor 70String::String() 71 : fLength(0), 72 fString(NULL) 73{ 74} 75 76// copy constructor 77String::String(const String &string) 78 : fLength(0), 79 fString(NULL) 80{ 81 *this = string; 82} 83 84// constructor 85String::String(const char *string, int32 length) 86 : fLength(0), 87 fString(NULL) 88{ 89 SetTo(string, length); 90} 91 92// destructor 93String::~String() 94{ 95 Unset(); 96} 97 98// SetTo 99bool 100String::SetTo(const char *string, int32 maxLength) 101{ 102 if (string) { 103 if (maxLength > 0) 104 maxLength = strnlen(string, maxLength); 105 else if (maxLength < 0) 106 maxLength = strlen(string); 107 } 108 return _SetTo(string, maxLength); 109} 110 111// Unset 112void 113String::Unset() 114{ 115 if (fString) { 116 delete[] fString; 117 fString = NULL; 118 } 119 fLength = 0; 120} 121 122// Truncate 123void 124String::Truncate(int32 newLength) 125{ 126 if (newLength < 0) 127 newLength = 0; 128 if (newLength < fLength) { 129 char *string = fString; 130 fString = NULL; 131 if (!_SetTo(string, newLength)) { 132 fString = string; 133 fLength = newLength; 134 fString[fLength] = '\0'; 135 } else 136 delete[] string; 137 } 138} 139 140// GetString 141const char * 142String::GetString() const 143{ 144 if (fString) 145 return fString; 146 return ""; 147} 148 149// = 150String & 151String::operator=(const String &string) 152{ 153 if (&string != this) 154 _SetTo(string.fString, string.fLength); 155 return *this; 156} 157 158// == 159bool 160String::operator==(const String &string) const 161{ 162 return (fLength == string.fLength 163 && (fLength == 0 || !strcmp(fString, string.fString))); 164} 165 166// _SetTo 167bool 168String::_SetTo(const char *string, int32 length) 169{ 170 bool result = true; 171 Unset(); 172 if (string && length > 0) { 173 fString = new(std::nothrow) char[length + 1]; 174 if (fString) { 175 memcpy(fString, string, length); 176 fString[length] = '\0'; 177 fLength = length; 178 } else 179 result = false; 180 } 181 return result; 182} 183 184 185#endif // __cplusplus 186 187#endif // STRING_H 188