00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <Basics.H>
00025 #include "Generics.H"
00026 #include "Atom.H"
00027
00028
00029 static Basics::mutex mu;
00030 static TextStringTbl *tbl = 0;
00031
00032
00033 static const Text EmptyTxt;
00034
00035
00036
00037 class AtomInit {
00038 public:
00039 AtomInit() throw ();
00040 };
00041 static AtomInit init;
00042
00043 AtomInit::AtomInit() throw ()
00044 {
00045 mu.lock();
00046
00047 tbl = NEW_CONSTR(TextStringTbl, ( 100));
00048
00049
00050 bool inTbl = tbl->Put(EmptyTxt, EmptyTxt.cchars()); assert(!inTbl);
00051 mu.unlock();
00052 }
00053
00054
00055
00056 static const char *StrCopy(const char *str) throw ()
00057
00058 {
00059 int len = strlen(str) + 1;
00060 char* res = NEW_PTRFREE_ARRAY(char, len);
00061 memcpy(res, str, len);
00062 return res;
00063 }
00064
00065 static const char *StrCopy(const char *s, int len) throw ()
00066
00067
00068
00069 {
00070 char* res = NEW_PTRFREE_ARRAY(char, len+1);
00071 memcpy(res, s, len);
00072 res[len] = '\0';
00073 return res;
00074 }
00075
00076
00077
00078 Atom& Atom::operator = (const char* str) throw ()
00079 {
00080 this->Init(str, (void *)NULL);
00081 return *this;
00082 }
00083
00084 Atom& Atom::operator = (const Text& t) throw ()
00085 {
00086 this->Init(t.cchars(), Text::GCImpl() ? (void *)1 : (void *)NULL);
00087 return *this;
00088 }
00089
00090 Atom& Atom::operator = (const Atom& a) throw ()
00091 {
00092
00093 this->s = a.s;
00094 return *this;
00095 }
00096
00097
00098 static const char *StrConcat(const char *str1, const char *str2,
00099 bool str2mutable) throw ()
00100
00101
00102
00103
00104
00105 {
00106
00107 int len1 = strlen(str1), len2 = strlen(str2);
00108 char *res;
00109 if (len1 == 0) {
00110 return (str2mutable ? StrCopy(str2, len2) : str2);
00111 } else if (len2 == 0) {
00112 return str1;
00113 } else {
00114 char *res = NEW_PTRFREE_ARRAY(char, len1 + len2 + 1);
00115 memcpy(res, str1, len1);
00116 memcpy(res + len1, str2, len2 + 1);
00117 return res;
00118 }
00119 }
00120
00121 Atom& Atom::operator += (const char* str) throw ()
00122 {
00123 const char *catres = StrConcat(this->s, str, true);
00124 this->Init(catres, (void *)NULL);
00125 return *this;
00126 }
00127
00128 Atom& Atom::operator += (const Text& t) throw ()
00129 {
00130 const char *catres = StrConcat(this->s, t.cchars(), true);
00131 this->Init(catres, (void *)NULL);
00132 return *this;
00133 }
00134
00135 Atom& Atom::operator += (const Atom& a) throw ()
00136 {
00137 const char *catres = StrConcat(this->s, a.s, false);
00138 this->Init(catres, (void *)NULL);
00139 return *this;
00140 }
00141
00142
00143
00144 void Atom::Init(const char* str, const void* cpy) throw ()
00145 {
00146 mu.lock();
00147 Text inTxt(str);
00148 if (!(tbl->Get(inTxt, this->s))) {
00149 this->s = (cpy == (void *)NULL) ? StrCopy(str) : str;
00150 bool inTbl = tbl->Put(inTxt, this->s); assert(!inTbl);
00151 }
00152 mu.unlock();
00153 }
00154
00155 void Atom::Init(const char* bytes, int len) throw ()
00156 {
00157 const char *str = StrCopy(bytes, len);
00158 Text inTxt(str);
00159 mu.lock();
00160 if (!(tbl->Get(inTxt, this->s))) {
00161 this->s = str;
00162 bool inTbl = tbl->Put(inTxt, this->s); assert(!inTbl);
00163 }
00164 mu.unlock();
00165 }