blob: eaa1b82bca5ae805a65785777edb791d8b1045aa [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001/*==============================================================================
2
3 ds_ASString.cpp
4
5GENERAL DESCRIPTION
6 A string class with utility functions for parsing AS.
7
8EXTERNALIZED FUNCTIONS
9
10INITIALIZATION AND SEQUENCING REQUIREMENTS
11 None
12
13 Copyright (c) 2014 by Qualcomm Technologies Incorporated. All Rights Reserved.
14==============================================================================*/
15
16/*==============================================================================
17 EDIT HISTORY FOR MODULE
18
19This section contains comments describing changes made to the module.
20Notice that changes are listed in reverse chronological order.
21
22when who what, where, why
23-------- --- ----------------------------------------------------------
2405/20/15 ml Use memory from modem heap
2504/21/14 ml Created file/Initial version.
26==============================================================================*/
27#include "ds_ASString.h"
28
29//#include "ds_appsrv_mem.h"
30//#include "data_msg.h"
31#include "mbtk_type.h"
32#include <string.h>
33#include <stdlib.h>
34#include <cctype> // isspace, tolower
35
36// #define DS_ASSTRING_MAX_LEN 4294967295 // uint32 max
37#define DS_ASSTRING_MAX_LEN 400000
38
39static const char AS_ESCAPE_MARK = '&';
40static const char EMPTY_STRING[] = "";
41
42static const char* ESCAPE_CHARS[] = {"&lt;", "&gt;", "&amp;", "&apos;", "&quot;"};
43static const char UNESCAPE_CHARS[] = {'<', '>', '&', '\'', '"'};
44static const uint32 NUM_ESCAPE_CHARS = 5;
45
46
47static bool has_string_at_start(const char* buf, const char* cmp);
48
49static void memscpy(void* dest, size_t destLen, const void* src, size_t srcLen) {
50 if (srcLen <= destLen)
51 memcpy(dest, src, srcLen);
52}
53
54
55ASString::ASString()
56: str(NULL) { }
57
58
59ASString::ASString(const char* src)
60: str(NULL)
61{
62 if(NULL == src)
63 {
64 str = NULL;
65 return;
66 }
67 copy_string(src, strlen(src));
68}
69
70
71ASString::ASString(const char* src, uint32 len)
72: str(NULL)
73{
74 copy_string(src, len);
75}
76
77
78// copy constructor
79ASString::ASString(ASString& src)
80: str(NULL)
81{
82 copy_string(src.c_str(), src.size());
83}
84
85
86ASString::ASString(const ASString& src)
87: str(NULL)
88{
89 copy_string(src.c_str(), src.size());
90}
91
92
93ASString::~ASString()
94{
95 if(NULL != str)
96 {
97 free(str);
98 }
99}
100
101// Assumes this->str with no memory allocated
102void ASString::copy_string(const char* src, uint32 len)
103{
104 if(NULL == src || 0 == len)
105 {
106 str = NULL;
107 return;
108 }
109 if(len > DS_ASSTRING_MAX_LEN)
110 return;
111
112 str = (char*)malloc(sizeof(char) * (len + 1));
113 if(NULL != str)
114 {
115 memscpy(str, len, src, len);
116 }
117}
118
119
120ASString& ASString::operator=(const ASString& rhs)
121{
122 if(&rhs != this)
123 {
124 if(NULL != str)
125 {
126 free(str);
127 str = NULL;
128 }
129
130 if(NULL == rhs.str)
131 str = NULL;
132 else
133 copy_string(rhs.str, rhs.size());
134 }
135 return *this;
136}
137
138
139ASString& ASString::operator=(const char* rhs)
140{
141 if(NULL != str)
142 {
143 free(str);
144 str = NULL;
145 }
146
147 if(NULL == rhs)
148 str = NULL;
149 else
150 copy_string(rhs, strlen(rhs));
151
152 return *this;
153}
154
155
156
157char ASString::operator[](const int index) const
158{
159 return str[index];
160}
161
162
163char& ASString::operator[](int index)
164{
165 return str[index];
166}
167
168
169const char* ASString::c_str() const
170{
171 if(NULL == str)
172 return EMPTY_STRING;
173 return str;
174}
175
176
177uint32 ASString::size() const
178{
179 return length();
180}
181
182
183uint32 ASString::length() const
184{
185 if(NULL == str)
186 return 0;
187 return (uint32)strlen(str);
188}
189
190
191bool ASString::empty() const
192{
193 return (0 == length());
194}
195
196void ASString::remove_trailing_spaces()
197{
198 uint32 end = length();
199
200 if(0 == end)
201 return;
202
203 while(0 != end)
204 {
205 if(!isspace(str[--end]))
206 {
207 end++;
208 break;
209 }
210 }
211
212 str[end] = '\0';
213}
214
215
216
217
218bool ASString::resolve_xml_escapes()
219{
220 bool replaced = false;
221 uint32 counter = 0;
222 uint32 len = length();
223 char* buf = str;
224 char* new_str = NULL;
225
226 if(0 == len)
227 return true;
228
229 new_str = (char*)malloc(sizeof(char) * (len + 1) );
230 if(NULL == new_str)
231 return true;
232
233 while('\0' != *buf && counter < len)
234 {
235 if(AS_ESCAPE_MARK == *buf)
236 {
237 replaced = false;
238 for(uint32 i=0; i<NUM_ESCAPE_CHARS; i++)
239 {
240 if(has_string_at_start(buf, ESCAPE_CHARS[i]))
241 {
242 new_str[counter++] = UNESCAPE_CHARS[i];
243 buf += strlen(ESCAPE_CHARS[i]);
244 replaced = true;
245 break;
246 }
247 }
248
249 if(!replaced)
250 {
251 free(new_str);
252 return false;
253 }
254 }
255 else
256 {
257 new_str[counter++] = *buf;
258 buf++;
259 }
260 }
261
262 free(str);
263 str = new_str;
264
265 return true;
266}
267
268
269
270void ASString::to_lower()
271{
272 uint32 len = length();
273 for(uint32 i = 0; i < len; ++i)
274 {
275 str[i] = tolower(str[i]);
276 }
277}
278
279
280
281bool ASString::limit_cmp(const char* cstr, const uint32 len) const
282{
283 return (0 == strncmp(str, cstr, len));
284}
285
286
287
288void ASString::append(const char* append_str)
289{
290 if(NULL == append_str)
291 return;
292
293 append(append_str, strlen(append_str));
294}
295
296
297
298void ASString::append(const char* append_str, const uint32 len)
299{
300 uint32 prev_size, new_size;
301
302 if(NULL == append_str)
303 return;
304
305 if(strlen(append_str) < len || 0 == len)
306 return;
307
308 prev_size = length();
309 new_size = prev_size + len + 1;
310
311 if(new_size < prev_size || new_size < len || DS_ASSTRING_MAX_LEN < new_size) // overflow?
312 {
313 printf("append - append size too long");
314 return;
315 }
316
317 char* tmp = (char*)malloc(sizeof(char) * new_size);
318 if(NULL == tmp)
319 {
320 printf("append - Failed to allocate memory for result string");
321 return;
322 }
323
324 if(NULL != str)
325 {
326 // copy the current string to the new string.
327 memscpy(tmp, new_size, str, prev_size);
328 free(str);
329 str = NULL;
330 }
331 // add the new string
332 memscpy(tmp+prev_size, new_size - prev_size, append_str, len);
333
334 str = tmp;
335}
336
337
338void ASString::append(const ASString& append_str)
339{
340 if(append_str.empty())
341 return;
342 append(append_str.c_str(), append_str.length());
343}
344
345
346
347
348
349bool operator== (const ASString& lhs, const ASString& rhs)
350{
351 return (0 == strcasecmp(lhs.c_str(), rhs.c_str()));
352}
353
354bool operator!= (const ASString& lhs, const ASString& rhs)
355{
356 return (0 != strcasecmp(lhs.c_str(), rhs.c_str()));
357}
358
359
360bool operator== (const ASString& lhs, const char* rhs)
361{
362 return (0 == strcasecmp(lhs.c_str(), rhs));
363}
364
365bool operator!= (const ASString& lhs, const char* rhs)
366{
367 return (0 != strcasecmp(lhs.c_str(), rhs));
368}
369
370
371/*
372res < 0 if lhs < rhs
373res == 0 if lhs == rhs
374res > 0 if lhs < rhs
375*/
376bool operator< (const ASString& lhs, const ASString& rhs)
377{
378 return (0 > strcasecmp(lhs.c_str(), rhs.c_str()));
379}
380
381bool operator> (const ASString& lhs, const ASString& rhs)
382{
383 return (0 < strcasecmp(lhs.c_str(), rhs.c_str()));
384}
385
386
387
388
389
390
391
392static bool has_string_at_start(const char* buf, const char* cmp)
393{
394 return (0 == strncasecmp(buf, cmp, strlen(cmp)));
395}
396