1 #ifndef MSTRING_H 2 #define MSTRING_H 3 4 #ifdef YARRAY_H 5 #error include yarray.h after mstring.h 6 #endif 7 8 #include "ref.h" 9 #include <stdlib.h> 10 11 /* 12 * A reference counted string buffer of arbitrary but fixed size. 13 */ 14 class MStringData { 15 public: MStringData()16 MStringData() : fRefCount(0) {} 17 18 int fRefCount; 19 char fStr[]; 20 }; 21 22 class MStringRef { 23 public: MStringRef()24 MStringRef(): fStr(nullptr) {} MStringRef(MStringData * data)25 explicit MStringRef(MStringData* data): fStr(data) {} MStringRef(size_t len)26 explicit MStringRef(size_t len) { alloc(len); } MStringRef(const char * str,size_t len)27 MStringRef(const char* str, size_t len) { create(str, len); } 28 29 void alloc(size_t len); 30 void create(const char* str, size_t len); 31 operator bool() const { return fStr; } 32 MStringData* operator->() const { return fStr; } 33 bool operator!=(const MStringRef& r) const { return fStr != r.fStr; } 34 char& operator[](size_t index) const { return fStr->fStr[index]; } 35 void operator=(MStringData* data) { fStr = data; } acquire()36 void acquire() const { fStr->fRefCount++; } release()37 void release() const { if (fStr->fRefCount-- == 1) free(fStr); } 38 39 private: 40 41 MStringData* fStr; 42 }; 43 44 /* 45 * Mutable strings with a reference counted string buffer. 46 */ 47 class mstring { 48 private: 49 friend class MStringArray; 50 friend mstring operator+(const char* s, const mstring& m); 51 52 MStringRef fRef; 53 size_t fOffset; 54 size_t fCount; 55 acquire()56 void acquire() { 57 if (fRef) { fRef.acquire(); } 58 } release()59 void release() { 60 if (fRef) { fRef.release(); } 61 } 62 mstring(const MStringRef& str, size_t offset, size_t count); 63 mstring(const char* str1, size_t len1, const char* str2, size_t len2); data()64 const char* data() const { return &fRef[fOffset]; } 65 66 public: 67 mstring(const char *str); 68 mstring(const char *str1, const char *str2); 69 mstring(const char *str1, const char *str2, const char *str3); 70 mstring(const char *str1, const char *str2, const char *str3, 71 const char *str4, const char *str5 = nullptr, 72 const char *str6 = nullptr); 73 mstring(const char *str, size_t len); 74 explicit mstring(long); 75 mstring(null_ref &)76 mstring(null_ref &): fRef(nullptr), fOffset(0), fCount(0) { } mstring()77 mstring(): fRef(nullptr), fOffset(0), fCount(0) { } 78 mstring(const mstring & r)79 mstring(const mstring &r): 80 fRef(r.fRef), 81 fOffset(r.fOffset), 82 fCount(r.fCount) 83 { 84 acquire(); 85 } ~mstring()86 ~mstring() { 87 release(); 88 } 89 length()90 size_t length() const { return fCount; } offset()91 size_t offset() const { return fOffset; } isEmpty()92 bool isEmpty() const { return 0 == fCount; } nonempty()93 bool nonempty() const { return 0 < fCount; } 94 95 mstring& operator=(const mstring& rv); 96 void operator+=(const mstring& rv); 97 mstring operator+(const mstring& rv) const; 98 99 bool operator==(const char *rv) const { return equals(rv); } 100 bool operator!=(const char *rv) const { return !equals(rv); } 101 bool operator==(const mstring &rv) const { return equals(rv); } 102 bool operator!=(const mstring &rv) const { return !equals(rv); } 103 bool operator==(null_ref &) const { return isEmpty(); } 104 bool operator!=(null_ref &) const { return nonempty(); } 105 106 mstring operator=(null_ref &) { return *this = mstring(); } 107 mstring substring(size_t pos) const; 108 mstring substring(size_t pos, size_t len) const; 109 mstring match(const char* regex, const char* flags = nullptr) const; 110 111 int operator[](int pos) const { return charAt(pos); } 112 int charAt(int pos) const; 113 int indexOf(char ch) const; 114 int lastIndexOf(char ch) const; 115 int count(char ch) const; 116 117 bool equals(const char *s) const; 118 bool equals(const char *s, size_t len) const; 119 bool equals(const mstring &s) const; 120 int collate(mstring s, bool ignoreCase = false); 121 int compareTo(const mstring &s) const; 122 bool operator<(const mstring& other) const { return compareTo(other) < 0; } 123 bool copyTo(char *dst, size_t len) const; 124 125 bool startsWith(const mstring &s) const; 126 bool endsWith(const mstring &s) const; 127 int find(const mstring &s) const; 128 129 bool split(unsigned char token, mstring *left, mstring *remain) const; 130 bool splitall(unsigned char token, mstring *left, mstring *remain) const; 131 mstring trim() const; 132 mstring replace(int position, int len, const mstring &insert) const; 133 mstring remove(int position, int len) const; 134 mstring insert(int position, const mstring &s) const; append(const mstring & str)135 mstring append(const mstring &str) const { return *this + str; } 136 mstring searchAndReplaceAll(const mstring& s, const mstring& r) const; 137 mstring lower() const; 138 mstring upper() const; 139 140 operator const char *() { return c_str(); } 141 const char* c_str(); 142 }; 143 144 inline bool operator==(const char* s, const mstring& c) { return c == s; } 145 inline bool operator!=(const char* s, const mstring& c) { return c != s; } 146 147 inline mstring operator+(const char* s, const mstring& m) { 148 return mstring(s) + m; 149 } 150 151 #endif 152 153 // vim: set sw=4 ts=4 et: 154