Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / UAS / Base / UAS_String.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 // $XConsortium: UAS_String.cc /main/3 1996/06/11 16:40:32 cde-hal $
24 # include <string.h>
25 # include "UAS_String.hh"
26 # include "UAS_List.hh"
27
28 UAS_StringRep::UAS_StringRep (const char *data,int data_size,UAS_Owner owner) {
29     fRefCnt = 0;
30     fOwner = owner;
31     fDataSize = data_size;
32     if (fOwner == UAS_OWNER) {
33         fData = new char[fDataSize + 1];
34         (void) memcpy (fData, data, fDataSize);;
35         fData[fDataSize] = 0;
36     } else {
37         fData = (char *) data;
38     }
39 }
40
41 UAS_StringRep::~UAS_StringRep () {
42     if (fOwner == UAS_OWNER)
43         delete fData;
44 }
45
46 void
47 UAS_StringRep::incRef () {
48     fRefCnt ++;
49 }
50
51 void
52 UAS_StringRep::decRef () {
53     if (--fRefCnt == 0)
54         delete this;
55 }
56
57 static UAS_StringRep *gNullString = 0;
58
59 UAS_String::UAS_String () {
60     fStringRep = 0;
61     if (!gNullString) {
62         gNullString = new UAS_StringRep ("", 0, UAS_NOT_OWNER);
63         gNullString->incRef (); // So it stays around forever
64     }
65     setString (gNullString);
66 }
67
68 UAS_String::UAS_String (const UAS_String &str) {
69     fStringRep = 0;
70     setString (str.fStringRep);
71 }
72
73 UAS_String::UAS_String (const char *data, int data_size, UAS_Owner owner) {
74     fStringRep = 0;
75     if (!data) {
76         if (!gNullString) {
77             gNullString = new UAS_StringRep ("", 0, UAS_NOT_OWNER);
78             gNullString->incRef (); // So it stays around forever
79         }
80         setString (gNullString);
81     } else {
82         if (data_size < 0) {
83             data_size = strlen (data);
84         }
85         setString (new UAS_StringRep (data, data_size, owner));
86     }
87 }
88
89 UAS_String&
90 UAS_String::append(const UAS_String& post_fix)
91 {
92     int length = fStringRep->fDataSize + post_fix.fStringRep->fDataSize;
93     char* new_string = new char[length + 1];
94     memcpy(new_string, fStringRep->fData, fStringRep->fDataSize);
95     memcpy(new_string + fStringRep->fDataSize, post_fix.fStringRep->fData,
96                                         post_fix.fStringRep->fDataSize);
97     new_string[length] = '\0';
98     
99     UAS_StringRep* strrep =
100                 new UAS_StringRep(new_string, length, UAS_NOT_OWNER);
101     strrep->fOwner = UAS_OWNER;
102     setString(strrep);
103
104     return *this;
105 }
106
107 UAS_String::operator char * () const {
108     return fStringRep->fData;
109 }
110
111 int
112 UAS_String::length () const {
113     return fStringRep->fDataSize;
114 }
115
116 UAS_String &
117 UAS_String::operator = (const UAS_String &s) {
118     setString (s.fStringRep);
119     return *this;
120 }
121
122 UAS_String::~UAS_String () {
123     unsetString ();
124 }
125
126 void
127 UAS_String::setString (UAS_StringRep *sr) {
128     //
129     //  Important to incRef first in the case that
130     //  sr == fStringRep
131     //
132     sr->incRef ();
133     unsetString ();
134     fStringRep = sr;
135 }
136
137 void
138 UAS_String::unsetString () {
139     if (fStringRep) {
140         fStringRep->decRef ();
141         fStringRep = 0;
142     }
143 }
144
145 void
146 UAS_String::split (const char field, UAS_String &left, UAS_String &right) const{
147     int i;
148     for (i = 0; i < fStringRep->fDataSize; i ++)
149         if (fStringRep->fData[i] == field)
150             break;
151     if (i >= fStringRep->fDataSize) {
152         left = UAS_String ();
153         right = *this;
154     } else {
155         left = UAS_String (fStringRep->fData, i);
156         i ++;
157         right = UAS_String (fStringRep->fData + i, fStringRep->fDataSize - i);
158     }
159 }
160
161 int
162 operator == (const UAS_String &s1, const UAS_String &s2) {
163     if (s1.length() != s2.length())
164         return 0;
165     return !memcmp ((char *) s1, (char *) s2, s1.length());
166 }
167
168 int
169 operator != (const UAS_String &s1, const UAS_String &s2) {
170     return !(s1 == s2);
171 }
172
173 int
174 operator == (const UAS_String &s1, const char *cp) {
175     if (!cp) {
176         return s1.length() == 0;
177     }
178     if (strlen (cp) != s1.length())
179         return 0;
180     return !memcmp (cp, (char *) s1, s1.length());
181 }
182
183 int
184 operator != (const UAS_String &s1, const char *cp) {
185     return !(s1 == cp);
186 }
187
188 int
189 operator < (const UAS_String &s1, const UAS_String &s2)
190 {
191     return (strcmp((const char*)s1, (const char*)s2) < 0);
192 }
193
194 UAS_List<UAS_String>
195 UAS_String::splitFields (const char separator) const {
196     UAS_List<UAS_String> rval;
197     UAS_Pointer<UAS_String> cur;
198     int start = 0;
199     for (int i = 0; i < fStringRep->fDataSize; i ++) {
200         if (fStringRep->fData[i] == separator) {
201             cur = new UAS_String(&(fStringRep->fData[start]),
202                                 i - start, UAS_OWNER);
203             rval.insert_item(cur);
204             start = i + 1;
205         }
206     }
207     if (i != start) {
208         cur = new UAS_String(&(fStringRep->fData[start]), i - start, UAS_OWNER);
209         rval.insert_item(cur);
210     }
211     return rval;
212 }
213
214 UAS_String
215 UAS_String::operator + (const UAS_String &more) {
216     int newLength = length() + more.length();
217     char *ptr = new char[newLength + 1];
218     (void) memcpy (ptr, fStringRep->fData, fStringRep->fDataSize);
219     (void) memcpy (ptr + fStringRep->fDataSize,
220                    more.fStringRep->fData,
221                    more.fStringRep->fDataSize);
222     ptr[newLength] = 0;
223     //
224     // The following two lines are weird but serve to
225     // remove and extra malloc/copy.
226     //
227     UAS_String rval (ptr, newLength, UAS_NOT_OWNER);
228     rval.fStringRep->fOwner = UAS_OWNER;
229     return rval;
230 }