00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00036 #include <limits.h>
00037 #include <ctype.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040
00041 #include "wbxml.h"
00042
00043
00044
00045 #define WBXML_BUFFER_SPLIT_BLOCK 20
00046
00050 struct WBXMLBuffer_s
00051 {
00052 WB_UTINY *data;
00053 WB_ULONG len;
00054 WB_ULONG malloced;
00055 WB_ULONG malloc_block;
00056 };
00057
00058
00059 static WB_BOOL grow_buff(WBXMLBuffer *buffer, WB_ULONG size);
00060 static WB_BOOL insert_data(WBXMLBuffer *buffer, WB_ULONG pos, const WB_UTINY *data, WB_ULONG len);
00061
00062
00063
00064
00065
00066
00067
00068
00069 WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_create_real(const WB_UTINY *data, WB_ULONG len, WB_ULONG malloc_block)
00070 {
00071 WBXMLBuffer *buffer = NULL;
00072
00073 buffer = (WBXMLBuffer *) wbxml_malloc(sizeof(WBXMLBuffer));
00074 if (buffer == NULL)
00075 return NULL;
00076
00077 buffer->malloc_block = malloc_block;
00078
00079 if ((len <= 0) || (data == NULL)) {
00080 buffer->malloced = 0;
00081 buffer->len = 0;
00082 buffer->data = NULL;
00083 }
00084 else {
00085 if (len + 1 > malloc_block + 1)
00086 buffer->malloced = len + 1 + malloc_block;
00087 else
00088 buffer->malloced = malloc_block + 1;
00089
00090 buffer->data = (WB_UTINY *) wbxml_malloc(buffer->malloced * sizeof(WB_UTINY));
00091 if (buffer->data == NULL) {
00092 wbxml_free(buffer);
00093 return NULL;
00094 }
00095
00096 buffer->len = len;
00097 memcpy(buffer->data, data, len);
00098 buffer->data[len] = '\0';
00099 }
00100
00101 return buffer;
00102 }
00103
00104
00105 WBXML_DECLARE(void) wbxml_buffer_destroy(WBXMLBuffer *buffer)
00106 {
00107 if (buffer != NULL) {
00108 wbxml_free(buffer->data);
00109 wbxml_free(buffer);
00110 }
00111 }
00112
00113
00114 WBXML_DECLARE_NONSTD(void) wbxml_buffer_destroy_item(void *buff)
00115 {
00116 wbxml_buffer_destroy((WBXMLBuffer *) buff);
00117 }
00118
00119
00120 WBXML_DECLARE(WBXMLBuffer *) wbxml_buffer_duplicate(WBXMLBuffer *buff)
00121 {
00122 WBXMLBuffer *result = NULL;
00123
00124 if (buff == NULL)
00125 return NULL;
00126
00127 result = wbxml_buffer_create_real(wbxml_buffer_get_cstr(buff),
00128 wbxml_buffer_len(buff),
00129 wbxml_buffer_len(buff));
00130
00131 return result;
00132 }
00133
00134
00135 WBXML_DECLARE(WB_ULONG) wbxml_buffer_len(WBXMLBuffer *buffer)
00136 {
00137 if (buffer == NULL)
00138 return 0;
00139
00140 return buffer->len;
00141 }
00142
00143
00144 WBXML_DECLARE(WB_BOOL) wbxml_buffer_get_char(WBXMLBuffer *buffer, WB_ULONG pos, WB_UTINY *result)
00145 {
00146 if ((buffer == NULL) || (pos >= buffer->len) || (pos < 0))
00147 return FALSE;
00148
00149 *result = buffer->data[pos];
00150 return TRUE;
00151 }
00152
00153
00154 WBXML_DECLARE(void) wbxml_buffer_set_char(WBXMLBuffer *buffer, WB_ULONG pos, WB_UTINY ch)
00155 {
00156 if (pos < buffer->len)
00157 buffer->data[pos] = ch;
00158 }
00159
00160
00161 WBXML_DECLARE(WB_UTINY *) wbxml_buffer_get_cstr(WBXMLBuffer *buffer)
00162 {
00163 if ((buffer == NULL) || (buffer->len == 0))
00164 return WBXML_UTINY_NULL_STRING;
00165
00166 return buffer->data;
00167 }
00168
00169
00170 WBXML_DECLARE(WB_BOOL) wbxml_buffer_insert(WBXMLBuffer *to, WBXMLBuffer *buffer, WB_ULONG pos)
00171 {
00172 if ((to != NULL) && (buffer != NULL))
00173 return insert_data(to, pos, buffer->data, buffer->len);
00174
00175 return FALSE;
00176 }
00177
00178
00179 WBXML_DECLARE(WB_BOOL) wbxml_buffer_insert_cstr(WBXMLBuffer *to, WB_UTINY *str, WB_ULONG pos)
00180 {
00181 if ((to != NULL) && (str != NULL))
00182 return insert_data(to, pos, str, WBXML_STRLEN(str));
00183
00184 return FALSE;
00185 }
00186
00187
00188 WBXML_DECLARE(WB_BOOL) wbxml_buffer_append(WBXMLBuffer *dest, WBXMLBuffer *buff)
00189 {
00190 if (dest == NULL)
00191 return FALSE;
00192
00193 if (buff == NULL)
00194 return TRUE;
00195
00196 return wbxml_buffer_append_data(dest, wbxml_buffer_get_cstr(buff), wbxml_buffer_len(buff));
00197 }
00198
00199
00200 WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_data_real(WBXMLBuffer *buffer, const WB_UTINY *data, WB_ULONG len)
00201 {
00202 if (buffer == NULL)
00203 return FALSE;
00204
00205 if ((data == NULL) || (len == 0))
00206 return TRUE;
00207
00208 return insert_data(buffer, buffer->len, data, len);
00209 }
00210
00211 WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_cstr_real(WBXMLBuffer *buffer, const WB_UTINY *data)
00212 {
00213 if (data == NULL)
00214 return TRUE;
00215
00216 return wbxml_buffer_append_data(buffer, data, WBXML_STRLEN(data));
00217 }
00218
00219
00220 WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_char(WBXMLBuffer *buffer, WB_UTINY ch)
00221 {
00222 WB_UTINY c = ch;
00223
00224 if ((buffer == NULL) || (ch > UCHAR_MAX))
00225 return FALSE;
00226
00227 return insert_data(buffer, buffer->len, &c, 1);
00228 }
00229
00230
00231 WBXML_DECLARE(WB_BOOL) wbxml_buffer_append_mb_uint_32(WBXMLBuffer *buffer, WB_ULONG value)
00232 {
00233
00234
00235
00236 WB_UTINY octets[5];
00237 WB_LONG i = 0, start = 0;
00238
00239
00240
00241
00242 octets[4] = (WB_UTINY) (value & 0x7f);
00243 value >>= 7;
00244
00245 for (i = 3; value > 0 && i >= 0; i--) {
00246 octets[i] = (WB_UTINY) (0x80 | (value & 0x7f));
00247 value >>= 7;
00248 }
00249 start = i + 1;
00250
00251 return wbxml_buffer_append_data(buffer, octets + start, 5 - start);
00252 }
00253
00254
00255 WBXML_DECLARE(void) wbxml_buffer_delete(WBXMLBuffer *buffer, WB_ULONG pos, WB_ULONG len)
00256 {
00257 if (pos > buffer->len)
00258 pos = buffer->len;
00259
00260 if (pos + len > buffer->len)
00261 len = buffer->len - pos;
00262
00263 if (len > 0) {
00264 memmove(buffer->data + pos, buffer->data + pos + len,
00265 buffer->len - pos - len);
00266
00267 buffer->len -= len;
00268 buffer->data[buffer->len] = '\0';
00269 }
00270 }
00271
00272
00273 WBXML_DECLARE(void) wbxml_buffer_shrink_blanks(WBXMLBuffer *buffer)
00274 {
00275 WB_ULONG i = 0, j = 0, end = 0;
00276 WB_UTINY ch = 0;
00277
00278 if (buffer == NULL)
00279 return;
00280
00281 end = wbxml_buffer_len(buffer);
00282
00283 for (i = 0; i < end; i++)
00284 {
00285 if (wbxml_buffer_get_char(buffer, i, &ch) && isspace(ch))
00286 {
00287
00288 if (ch != ' ')
00289 wbxml_buffer_set_char(buffer, i, ' ');
00290
00291
00292 j = i = i + 1;
00293 while (wbxml_buffer_get_char(buffer, j, &ch) && isspace(ch))
00294 j++;
00295
00296 if (j - i > 1)
00297 wbxml_buffer_delete(buffer, i, j - i);
00298 }
00299 }
00300 }
00301
00302
00303 WBXML_DECLARE(void) wbxml_buffer_strip_blanks(WBXMLBuffer *buffer)
00304 {
00305 WB_ULONG start = 0, end = 0, len = 0;
00306 WB_UTINY ch = 0;
00307
00308
00309 while (wbxml_buffer_get_char(buffer, start, &ch) &&
00310 isspace(ch) &&
00311 start <= wbxml_buffer_len(buffer))
00312 {
00313 start ++;
00314 }
00315
00316 if (start > 0)
00317 wbxml_buffer_delete(buffer, 0, start);
00318
00319
00320 if ((len = wbxml_buffer_len(buffer)) > 0) {
00321 end = len = len - 1;
00322 while (wbxml_buffer_get_char(buffer, end, &ch) &&
00323 isspace(ch) &&
00324 end >= 0)
00325 {
00326 end--;
00327 }
00328 wbxml_buffer_delete(buffer, end + 1, len - end);
00329 }
00330 }
00331
00332
00333 WBXML_DECLARE(WB_LONG) wbxml_buffer_compare(WBXMLBuffer *buff1, WBXMLBuffer *buff2)
00334 {
00335 WB_LONG ret = 0, len = 0;
00336
00337 if ((buff1 == NULL) || (buff2 == NULL)) {
00338 if ((buff1 == NULL) && (buff2 == NULL))
00339 return 0;
00340
00341 if (buff1 == NULL)
00342 return -1;
00343 else
00344 return 1;
00345 }
00346
00347 if (buff1->len < buff2->len)
00348 len = buff1->len;
00349 else
00350 len = buff2->len;
00351
00352 if (len == 0)
00353 {
00354 if (buff1->len == 0 && buff2->len > 0)
00355 return -1;
00356 if (buff1->len > 0 && buff2->len == 0)
00357 return 1;
00358 return 0;
00359 }
00360
00361 if ((ret = memcmp(buff1->data, buff2->data, len)) == 0)
00362 {
00363 if (buff1->len < buff2->len)
00364 ret = -1;
00365 else {
00366 if (buff1->len > buff2->len)
00367 ret = 1;
00368 }
00369 }
00370
00371 return ret;
00372 }
00373
00374
00375 WBXML_DECLARE(WB_LONG) wbxml_buffer_compare_cstr(WBXMLBuffer *buff, const WB_TINY *str)
00376 {
00377 WB_LONG ret = 0, len = 0;
00378
00379 if ((buff == NULL) || (str == NULL)) {
00380 if ((buff == NULL) && (str == NULL))
00381 return 0;
00382
00383 if (buff == NULL)
00384 return -1;
00385 else
00386 return 1;
00387 }
00388
00389 if (buff->len < WBXML_STRLEN(str))
00390 len = buff->len;
00391 else
00392 len = WBXML_STRLEN(str);
00393
00394 if (len == 0)
00395 {
00396 if (buff->len == 0 && WBXML_STRLEN(str) > 0)
00397 return -1;
00398 if (buff->len > 0 && WBXML_STRLEN(str) == 0)
00399 return 1;
00400 return 0;
00401 }
00402
00403 if ((ret = memcmp(buff->data, str, len)) == 0)
00404 {
00405 if (buff->len < WBXML_STRLEN(str))
00406 ret = -1;
00407 else {
00408 if (buff->len > WBXML_STRLEN(str))
00409 ret = 1;
00410 }
00411 }
00412
00413 return ret;
00414 }
00415
00416
00417 WBXML_DECLARE(WBXMLList *) wbxml_buffer_split_words_real(WBXMLBuffer *buff)
00418 {
00419 WB_UTINY *p = NULL;
00420 WBXMLList *list = NULL;
00421 WBXMLBuffer *word = NULL;
00422 WB_ULONG i = 0, start = 0, end = 0;
00423
00424 if ((list = wbxml_list_create()) == NULL)
00425 return NULL;
00426
00427 p = buff->data;
00428 i = 0;
00429 while (TRUE)
00430 {
00431 while (i < buff->len && isspace(*p)) {
00432 ++p;
00433 ++i;
00434 }
00435 start = i;
00436
00437 while (i < buff->len && !isspace(*p)) {
00438 ++p;
00439 ++i;
00440 }
00441 end = i;
00442
00443 if (start == end)
00444 break;
00445
00446 if((word = wbxml_buffer_create(buff->data + start, end - start, WBXML_BUFFER_SPLIT_BLOCK)) == NULL) {
00447 wbxml_list_destroy(list, wbxml_buffer_destroy_item);
00448 return NULL;
00449 }
00450
00451 wbxml_list_append(list, word);
00452 }
00453
00454 return list;
00455 }
00456
00457
00458 WBXML_DECLARE(WB_BOOL) wbxml_buffer_search_char(WBXMLBuffer *to, WB_UTINY ch, WB_ULONG pos, WB_ULONG *result)
00459 {
00460 WB_UTINY *p = NULL;
00461
00462 if ((to == NULL) || (ch > UCHAR_MAX))
00463 return FALSE;
00464
00465 if (pos >= to->len)
00466 return FALSE;
00467
00468 if ((p = (WB_UTINY *) memchr(to->data + pos, ch, to->len - pos)) == NULL)
00469 return FALSE;
00470
00471 if (result != NULL)
00472 *result = p - to->data;
00473
00474 return TRUE;
00475 }
00476
00477
00478 WBXML_DECLARE(WB_BOOL) wbxml_buffer_search(WBXMLBuffer *to, WBXMLBuffer *search, WB_ULONG pos, WB_ULONG *result)
00479 {
00480 WB_UTINY first = 0;
00481
00482 if ((to == NULL) || (search == NULL))
00483 return FALSE;
00484
00485 if (result != NULL)
00486 *result = 0;
00487
00488
00489 if (search->len == 0)
00490 return TRUE;
00491
00492
00493 if (search->len > to->len)
00494 return FALSE;
00495
00496
00497 if (search->len == 1)
00498 return wbxml_buffer_search_char(to, search->data[0], pos, result);
00499
00500
00501
00502 first = search->data[0];
00503 while ((wbxml_buffer_search_char(to, first, pos, &pos)) &&
00504 (to->len - pos >= search->len))
00505 {
00506 if (memcmp(to->data + pos, search->data, search->len) == 0) {
00507 if (result != NULL)
00508 *result = pos;
00509 return TRUE;
00510 }
00511 pos++;
00512 }
00513
00514 return FALSE;
00515 }
00516
00517
00518 WBXML_DECLARE(WB_BOOL) wbxml_buffer_search_cstr(WBXMLBuffer *to, WB_UTINY *search, WB_ULONG pos, WB_ULONG *result)
00519 {
00520 WB_UTINY first = 0;
00521
00522 if ((to == NULL) || (search == NULL))
00523 return FALSE;
00524
00525 if (result != NULL)
00526 *result = 0;
00527
00528
00529 if (WBXML_STRLEN(search) == 0)
00530 return TRUE;
00531
00532
00533 if (WBXML_STRLEN(search) > to->len)
00534 return FALSE;
00535
00536
00537 if (WBXML_STRLEN(search) == 1)
00538 return wbxml_buffer_search_char(to, search[0], pos, result);
00539
00540
00541
00542 first = search[0];
00543 while ((wbxml_buffer_search_char(to, first, pos, &pos)) &&
00544 (to->len - pos >= WBXML_STRLEN(search)))
00545 {
00546 if (memcmp(to->data + pos, search, WBXML_STRLEN(search)) == 0) {
00547 if (result != NULL)
00548 *result = pos;
00549 return TRUE;
00550 }
00551 pos++;
00552 }
00553
00554 return FALSE;
00555 }
00556
00557
00558 WBXML_DECLARE(WB_BOOL) wbxml_buffer_contains_only_whitespaces(WBXMLBuffer *buffer)
00559 {
00560 WB_ULONG i = 0;
00561
00562 if (buffer == NULL)
00563 return FALSE;
00564
00565 for (i=0; i<buffer->len; i++) {
00566 if (!isspace(*(buffer->data + i)))
00567 return FALSE;
00568 }
00569
00570 return TRUE;
00571 }
00572
00573
00574 WBXML_DECLARE(void) wbxml_buffer_hex_to_binary(WBXMLBuffer *buffer)
00575 {
00576 WB_UTINY *p = NULL;
00577 WB_ULONG i = 0, len = 0;
00578
00579 if (buffer == NULL)
00580 return;
00581
00582 p = buffer->data;
00583 len = wbxml_buffer_len(buffer);
00584
00585
00586 for (i = 0; i < len; i++, p++) {
00587 if (*p >= '0' && *p <= '9')
00588 *p -= '0';
00589 else if (*p >= 'a' && *p <= 'f')
00590 *p = *p - 'a' + 10;
00591 else if (*p >= 'A' && *p <= 'F')
00592 *p = *p - 'A' + 10;
00593 else {
00594
00595 *p = 0;
00596 }
00597 }
00598
00599
00600 len = buffer->len / 2;
00601
00602 for (i = 0; i < len; i++)
00603 buffer->data[i] = buffer->data[i * 2] * 16 | buffer->data[i * 2 + 1];
00604
00605 buffer->len = len;
00606 buffer->data[len] = '\0';
00607 }
00608
00609
00610 WBXML_DECLARE(WB_BOOL) wbxml_buffer_binary_to_hex(WBXMLBuffer *buffer, WB_BOOL uppercase)
00611 {
00612 WB_UTINY *hexits = NULL;
00613 WB_LONG i = 0;
00614
00615 if (buffer == NULL)
00616 return FALSE;
00617
00618 if (wbxml_buffer_len(buffer) == 0)
00619 return TRUE;
00620
00621 hexits = (WB_UTINY *)(uppercase ? "0123456789ABCDEF" : "0123456789abcdef");
00622
00623
00624 grow_buff(buffer, buffer->len * 2);
00625
00626
00627
00628
00629
00630 for (i = buffer->len - 1; i >= 0; i--) {
00631 buffer->data[i * 2 + 1] = hexits[buffer->data[i] % 16];
00632 buffer->data[i * 2] = hexits[(buffer->data[i] / 16) & 0xf];
00633 }
00634
00635 buffer->len = buffer->len * 2;
00636 buffer->data[buffer->len] = '\0';
00637
00638 return TRUE;
00639 }
00640
00641
00642 WBXML_DECLARE(void) wbxml_buffer_remove_trailing_zeros(WBXMLBuffer **buffer)
00643 {
00644 WB_UTINY ch = 0;
00645
00646 if ((buffer == NULL) || (*buffer == NULL))
00647 return;
00648
00649 while ((*buffer)->len > 0) {
00650 if (wbxml_buffer_get_char(*buffer, wbxml_buffer_len(*buffer) - 1, &ch) && (ch == '\0'))
00651 wbxml_buffer_delete(*buffer, wbxml_buffer_len(*buffer) - 1, 1);
00652 else
00653 return;
00654 }
00655 }
00656
00657
00658
00659
00660
00661
00668 static WB_BOOL grow_buff(WBXMLBuffer *buffer, WB_ULONG size)
00669 {
00670 if ((buffer == NULL) || (size < 0))
00671 return FALSE;
00672
00673
00674 size++;
00675
00676 if ((buffer->len + size) > buffer->malloced) {
00677 if ((buffer->malloced + buffer->malloc_block) < (buffer->len + size))
00678 buffer->malloced = buffer->len + size + buffer->malloc_block;
00679 else
00680 buffer->malloced = buffer->malloced + buffer->malloc_block;
00681
00682 buffer->data = wbxml_realloc(buffer->data, buffer->malloced);
00683 if (buffer->data == NULL)
00684 return FALSE;
00685 }
00686
00687 return TRUE;
00688 }
00689
00690
00699 static WB_BOOL insert_data(WBXMLBuffer *buffer, WB_ULONG pos, const WB_UTINY *data, WB_ULONG len)
00700 {
00701 if ((buffer == NULL) || (len == 0) || (pos > buffer->len))
00702 return FALSE;
00703
00704 if (!grow_buff(buffer, len))
00705 return FALSE;
00706
00707 if (buffer->len > pos) {
00708
00709 memmove(buffer->data + pos + len, buffer->data + pos, buffer->len - pos);
00710 }
00711
00712 memcpy(buffer->data + pos, data, len);
00713 buffer->len += len;
00714 buffer->data[buffer->len] = '\0';
00715
00716 return TRUE;
00717 }