00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "rstring.h"
00022
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <assert.h>
00026 #include <wchar.h>
00027
00028
00029 #define RSTRING_INCSTEP 3
00030
00031
00032 rwstring *
00033 rws_create (size_t length)
00034 {
00035 rwstring *rws;
00036 rws = malloc (sizeof (rwstring));
00037 if (rws == NULL)
00038 return NULL;
00039
00040 rws->text = calloc (length + 1, sizeof (wchar_t));
00041 if (rws->text == NULL)
00042 {
00043 free (rws);
00044 return NULL;
00045 }
00046
00047 rws->max = length;
00048 return rws;
00049 }
00050
00051
00052 void
00053 rws_free (rwstring ** rws)
00054 {
00055 assert (rws != NULL);
00056 if (*rws != NULL)
00057 {
00058 if ((*rws)->text != NULL)
00059 {
00060 free ((*rws)->text);
00061 (*rws)->text = NULL;
00062 }
00063 free (*rws);
00064 *rws = NULL;
00065 }
00066
00067 }
00068
00069
00070 rstring_code
00071 rws_resize (rwstring * rws, size_t length)
00072 {
00073 wchar_t *temp;
00074 assert (rws != NULL);
00075
00076 temp = realloc (rws->text, sizeof (wchar_t) * (length + 1));
00077 if (temp == NULL)
00078 {
00079 free (rws);
00080 return RS_MEMORY;
00081 }
00082 rws->text = temp;
00083 rws->max = length;
00084 rws->text[rws->max] = L'\0';
00085 return RS_OK;
00086 }
00087
00088
00089 rwstring *
00090 rws_duplicate (rwstring * copied)
00091 {
00092 rwstring *copy;
00093 assert (copied != NULL);
00094
00095 copy = rws_create (copy->max);
00096 if (copy == NULL)
00097 return NULL;
00098
00099 wcsncpy (copy->text, copied->text, wcslen (copied->text));
00100 return copy;
00101 }
00102
00103
00104 size_t
00105 rws_length (rwstring * rws)
00106 {
00107 assert (rws != NULL);
00108 return wcslen (rws->text);
00109 }
00110
00111
00112 rstring_code
00113 rws_copyrws (rwstring * to, const rwstring * from)
00114 {
00115 size_t from_length;
00116 assert (from != NULL);
00117 assert (to != NULL);
00118
00119 from_length = wcslen (from->text);
00120
00121 if (to->max < from_length)
00122 {
00123 if (rws_resize (to, from_length + 1) != RS_OK)
00124 return RS_MEMORY;
00125 }
00126 wcsncpy (to->text, from->text, from_length);
00127 to->text[from_length] = L'\0';
00128 return RS_OK;
00129 }
00130
00131
00132 rstring_code
00133 rws_copywcs (rwstring * to, const wchar_t * from, const size_t length)
00134 {
00135 assert (from != NULL);
00136 assert (to != NULL);
00137
00138
00139 if (to->max < length)
00140 {
00141 if (rws_resize (to, length + 1) != RS_OK)
00142 return RS_MEMORY;
00143 }
00144 wcsncpy (to->text, from, length);
00145 to->text[length] = L'\0';
00146 return RS_OK;
00147 }
00148
00149
00150 rstring_code
00151 rws_catrws (rwstring * pre, const rwstring * pos)
00152 {
00153 size_t pre_length, pos_length;
00154 assert (pre != NULL);
00155 assert (pos != NULL);
00156
00157 pre_length = wcslen (pre->text);
00158 pos_length = wcslen (pos->text);
00159 if (pos == NULL)
00160 return RS_OK;
00161
00162 if (pre->max < pre_length + pos_length + 1)
00163 {
00164 if (rws_resize (pre, pre_length + pos_length + 1) != RS_OK)
00165 return RS_MEMORY;
00166 }
00167 wcsncpy (pre->text + pre_length, pos->text, pos_length);
00168 pre->text[pre_length + pos_length] = L'\0';
00169 return RS_OK;
00170 }
00171
00172
00173 rstring_code
00174 rws_catrcs (rwstring * pre, const rcstring * pos)
00175 {
00176 size_t utf8pos;
00177 wchar_t wc;
00178 char i;
00179
00180 assert (pre != NULL);
00181 assert (pos != NULL);
00182
00183
00184 utf8pos = 0;
00185
00186 while (utf8pos < strlen (pos->text))
00187 {
00188 if ((pos->text[utf8pos] & 0x80) == 0)
00189 {
00190 if (rws_catc (pre, pos->text[utf8pos++]) != RS_OK)
00191 {
00192 return RS_MEMORY;
00193 }
00194 }
00195 else if ((pos->text[utf8pos] & 0xE0) == 0xC0)
00196 {
00197 wc = (pos->text[utf8pos++] & 0x1F) << 6;
00198 if ((pos->text[utf8pos] & 0xC0) == 0x80)
00199 {
00200 wc |= (pos->text[utf8pos++] & 63);
00201
00202 }
00203 else
00204 {
00205 return RS_UNKNOWN;
00206 }
00207 if (rws_catwc (pre, wc) != RS_OK)
00208 {
00209 return RS_MEMORY;
00210 }
00211 }
00212 else if ((pos->text[utf8pos] & 0xF0) == 0xE0)
00213 {
00214 wc = pos->text[utf8pos++] & 0xF << 12;
00215 for (i = 1; i >= 0; i--)
00216 {
00217 if ((pos->text[utf8pos] & 0xC0) == 0x80)
00218 {
00219 wc &= pos->text[utf8pos++] & 0x3F << i;
00220 }
00221 else
00222 {
00223 return RS_UNKNOWN;
00224 }
00225 }
00226 if (rws_catwc (pre, wc) != RS_OK)
00227 {
00228 return RS_MEMORY;
00229 }
00230
00231 }
00232 else if ((pos->text[utf8pos] & 0xF8) == 0xF0)
00233 {
00234 wc = pos->text[utf8pos++] & 0xF << 12;
00235 for (i = 2; i >= 0; i--)
00236 {
00237 if ((pos->text[utf8pos] & 0xC0) == 0x80)
00238 {
00239 wc &= pos->text[utf8pos++] & 0x3F << i;
00240 }
00241 else
00242 {
00243 return RS_UNKNOWN;
00244
00245 }
00246 }
00247 if (rws_catwc (pre, wc) != RS_OK)
00248 {
00249 return RS_MEMORY;
00250 }
00251
00252 }
00253 else if ((pos->text[utf8pos] & 0xFC) == 0xF8)
00254 {
00255 for (i = 3; i >= 0; i--)
00256 {
00257 if ((pos->text[utf8pos] & 0xC0) == 0x80)
00258 {
00259 wc &= pos->text[utf8pos++] & 0x3F << i;
00260 }
00261 else
00262 {
00263 return RS_UNKNOWN;
00264
00265 }
00266 }
00267 if (rws_catwc (pre, wc) != RS_OK)
00268 {
00269 return RS_MEMORY;
00270 }
00271 }
00272 else if ((pos->text[utf8pos] & 0xFE) == 0xFC)
00273 {
00274 for (i = 4; i >= 0; i--)
00275 {
00276 if ((pos->text[utf8pos] & 0xC0) == 0x80)
00277 {
00278 wc &= pos->text[utf8pos++] & 0x3F << i;
00279 }
00280 else
00281 {
00282 return RS_UNKNOWN;
00283 }
00284 }
00285 if (rws_catwc (pre, wc) != RS_OK)
00286 {
00287 return RS_MEMORY;
00288 }
00289 }
00290 else
00291 {
00292 return RS_UNKNOWN;
00293 }
00294 }
00295
00296 return RS_OK;
00297 }
00298
00299
00300 rstring_code
00301 rws_catwcs (rwstring * pre, const wchar_t * pos, const size_t length)
00302 {
00303 size_t pre_length;
00304
00305 assert (pre != NULL);
00306 assert (pos != NULL);
00307
00308 pre_length = wcslen (pre->text);
00309
00310 if (pre->max < pre_length + length)
00311 {
00312 if (rws_resize (pre, pre_length + length + 1) != RS_OK)
00313 return RS_MEMORY;
00314 }
00315 wcsncpy (pre->text + pre_length, pos, length);
00316 pre->text[pre_length + length] = L'\0';
00317 return RS_OK;
00318 }
00319
00320
00321 rstring_code
00322 rws_catcs (rwstring * pre, const char *pos, const size_t length)
00323 {
00324 size_t pre_length;
00325
00326 assert (pre != NULL);
00327 assert (pos != NULL);
00328
00329 pre_length = wcslen (pre->text);
00330
00331 if (pre->max < pre_length + length)
00332 {
00333 if (rws_resize (pre, pre_length + length + 1) != RS_OK)
00334 return RS_MEMORY;
00335 }
00336 mbsrtowcs (pre->text + pre_length, &pos, length, NULL);
00337 pre->text[pre_length + length] = L'\0';
00338 return RS_OK;
00339 }
00340
00341
00342 rstring_code
00343 rws_catwc (rwstring * pre, const wchar_t c)
00344 {
00345 size_t pre_length;
00346
00347 assert (pre != NULL);
00348
00349 pre_length = wcslen (pre->text);
00350 if (pre->max <= pre_length)
00351 {
00352 pre->max += RSTRING_INCSTEP;
00353 if (rws_resize (pre, pre->max) != RS_OK)
00354 return RS_MEMORY;
00355 }
00356 pre->text[pre_length] = c;
00357 pre->text[pre_length + 1] = L'\0';
00358 return RS_OK;
00359 }
00360
00361
00362 rstring_code
00363 rws_catc (rwstring * pre, const char c)
00364 {
00365 wchar_t newc;
00366
00367 assert (pre != NULL);
00368 mbtowc (&newc, &c, 1);
00369 return rws_catwc (pre, newc);
00370 }
00371
00372
00373 rwstring *
00374 rws_wrap (wchar_t * wcs)
00375 {
00376 rwstring *wrapper;
00377
00378 assert (wcs != NULL);
00379 wrapper = malloc (sizeof (rwstring));
00380 if (wrapper == NULL)
00381 return NULL;
00382 wrapper->max = wcslen (wcs);
00383 wrapper->text = wcs;
00384 return wrapper;
00385 }
00386
00387
00388 wchar_t *
00389 rws_unwrap (rwstring * rws)
00390 {
00391 wchar_t *out;
00392 assert (rws != NULL);
00393 if (rws->text == NULL)
00394 out = NULL;
00395 else
00396 out = realloc (rws->text, sizeof (wchar_t) * (wcslen (rws->text) + 1));
00397 free (rws);
00398 return out;
00399 }
00400
00401
00402 rcstring *
00403 rcs_create (size_t length)
00404 {
00405 rcstring *rcs;
00406 rcs = malloc (sizeof (rcstring));
00407 if (rcs == NULL)
00408 return NULL;
00409
00410 rcs->max = length;
00411
00412 rcs->text = calloc (rcs->max + 1, sizeof (char));
00413 if (rcs->text == NULL)
00414 {
00415 free (rcs);
00416 return NULL;
00417 }
00418
00419 return rcs;
00420 }
00421
00422
00423 void
00424 rcs_free (rcstring ** rcs)
00425 {
00426 assert (rcs != NULL);
00427 if (*rcs != NULL)
00428 {
00429 if ((*rcs)->text != NULL)
00430 {
00431 free ((*rcs)->text);
00432 (*rcs)->text = NULL;
00433 }
00434 free (*rcs);
00435 *rcs = NULL;
00436 }
00437
00438 }
00439
00440
00441 rstring_code
00442 rcs_resize (rcstring * rcs, size_t length)
00443 {
00444 char *temp;
00445 assert (rcs != NULL);
00446
00447 temp = realloc (rcs->text, sizeof (char) * (length + 1));
00448 if (temp == NULL)
00449 {
00450 free (rcs);
00451 return RS_MEMORY;
00452 }
00453 rcs->text = temp;
00454 rcs->max = length;
00455 rcs->text[rcs->max] = L'\0';
00456 return RS_OK;
00457 }
00458
00459
00460 rcstring *
00461 rcs_duplicate (rcstring * copied)
00462 {
00463 rcstring *copy;
00464 assert (copied != NULL);
00465
00466 copy = rcs_create (copy->max);
00467 if (copy == NULL)
00468 return NULL;
00469
00470 strncpy (copy->text, copied->text, strlen (copied->text));
00471 return copy;
00472 }
00473
00474
00475 size_t
00476 rcs_length (rcstring * rcs)
00477 {
00478
00479 assert (rcs != NULL);
00480 return strlen (rcs->text);
00481 }
00482
00483
00484 rstring_code
00485 rcs_copyrcs (rcstring * to, const rcstring * from)
00486 {
00487 size_t from_length;
00488 assert (from != NULL);
00489 assert (to != NULL);
00490
00491 from_length = strlen (from->text);
00492
00493 if (to->max < from_length)
00494 {
00495 if (rcs_resize (to, from_length + 1) != RS_OK)
00496 return RS_MEMORY;
00497 }
00498 strncpy (to->text, from->text, from_length);
00499 to->text[from_length] = '\0';
00500 return RS_OK;
00501 }
00502
00503
00504 rstring_code
00505 rcs_copycs (rcstring * to, const char *from, const size_t length)
00506 {
00507 assert (to != NULL);
00508
00509 if (from == NULL)
00510 return RS_OK;
00511
00512
00513 if (to->max < length)
00514 {
00515 if (rcs_resize (to, length + 1) != RS_OK)
00516 return RS_MEMORY;
00517 }
00518 strncpy (to->text, from, length);
00519 to->text[length] = '\0';
00520 return RS_OK;
00521 }
00522
00523
00524 rstring_code
00525 rcs_catrcs (rcstring * pre, const rcstring * pos)
00526 {
00527 size_t pre_length, pos_length;
00528 assert (pre != NULL);
00529 assert (pos != NULL);
00530
00531 pre_length = strlen (pre->text);
00532 pos_length = strlen (pos->text);
00533
00534 if (pre->max < pre_length + pos_length + 1)
00535 {
00536 if (rcs_resize (pre, pre_length + pos_length + 1) != RS_OK)
00537 return RS_MEMORY;
00538 }
00539 strncpy (pre->text + pre_length, pos->text, pos_length);
00540 pre->text[pre_length + pos_length] = '\0';
00541 return RS_OK;
00542 }
00543
00544
00545 rstring_code
00546 rcs_catcs (rcstring * pre, const char *pos, const size_t length)
00547 {
00548 size_t pre_length;
00549
00550 assert (pre != NULL);
00551 assert (pos != NULL);
00552
00553 pre_length = strlen (pre->text);
00554
00555 if (pre->max < pre_length + length)
00556 {
00557 if (rcs_resize (pre, pre_length + length + 5) != RS_OK)
00558 return RS_MEMORY;
00559 }
00560 strncpy (pre->text + pre_length, pos, length);
00561 pre->text[pre_length + length] = '\0';
00562 return RS_OK;
00563 }
00564
00565
00566 rstring_code
00567 rcs_catwcs (rcstring * pre, const wchar_t * pos, const size_t length)
00568 {
00569 size_t i;
00570 rstring_code code;
00571 assert (pre != NULL);
00572 assert (pos != NULL);
00573
00574 for (i = 0; i < length; i++)
00575 {
00576 code = rcs_catwc (pre, pos[i]);
00577 if (code != RS_OK)
00578 {
00579 return code;
00580 }
00581 }
00582
00583 return RS_OK;
00584 }
00585
00586
00587 rstring_code
00588 rcs_catwc (rcstring * pre, const wchar_t wc)
00589 {
00590 assert (pre != NULL);
00591
00592
00593 if (wc <= 0x7F)
00594 {
00595 rcs_catc (pre, wc);
00596 }
00597 else if (wc <= 0x7FF)
00598 {
00599 rcs_catc (pre, (wc >> 6) | 192);
00600 rcs_catc (pre, (wc & 63) | 128);
00601 }
00602 else if (wc <= 0xFFFF)
00603 {
00604 rcs_catc (pre, wc >> 12 | 224);
00605 rcs_catc (pre, (wc >> 6 & 63) | 128);
00606 rcs_catc (pre, (wc & 63) | 128);
00607 }
00608 else if (wc <= 0x1FFFFF)
00609 {
00610 rcs_catc (pre, wc >> 18 | 240);
00611 rcs_catc (pre, (wc >> 12 & 63) | 128);
00612 rcs_catc (pre, (wc >> 6 & 63) | 128);
00613 rcs_catc (pre, (wc & 63) | 128);
00614 }
00615 else if (wc <= 0x3FFFFFF)
00616 {
00617 rcs_catc (pre, wc >> 24 | 248);
00618 rcs_catc (pre, (wc >> 18 & 63) | 128);
00619 rcs_catc (pre, (wc >> 12 & 63) | 128);
00620 rcs_catc (pre, (wc >> 6 & 63) | 128);
00621 rcs_catc (pre, (wc & 63) | 128);
00622 }
00623 else if (wc <= 0x7FFFFFFF)
00624 {
00625 rcs_catc (pre, wc >> 30 | 252);
00626 rcs_catc (pre, (wc >> 24 & 63) | 128);
00627 rcs_catc (pre, (wc >> 18 & 63) | 128);
00628 rcs_catc (pre, (wc >> 12 & 63) | 128);
00629 rcs_catc (pre, (wc >> 6 & 63) | 128);
00630 rcs_catc (pre, (wc & 63) | 128);
00631 }
00632 return RS_OK;
00633 }
00634
00635
00636 rstring_code
00637 rcs_catc (rcstring * pre, const char c)
00638 {
00639 size_t pre_length;
00640
00641 assert (pre != NULL);
00642
00643 pre_length = strlen (pre->text);
00644 if (pre->max <= pre_length)
00645 {
00646 pre->max += RSTRING_INCSTEP;
00647 if (rcs_resize (pre, pre->max) != RS_OK)
00648 return RS_MEMORY;
00649 }
00650 pre->text[pre_length] = c;
00651 pre->text[pre_length + 1] = '\0';
00652 return RS_OK;
00653 }
00654
00655
00656 rcstring *
00657 rcs_wrap (char *cs)
00658 {
00659 rcstring *wrapper;
00660 assert (cs != NULL);
00661
00662 wrapper = malloc (sizeof (rcstring));
00663 if (wrapper == NULL)
00664 return NULL;
00665 wrapper->max = strlen (cs);
00666 wrapper->text = cs;
00667 return wrapper;
00668 }
00669
00670
00671 char *
00672 rcs_unwrap (rcstring * rcs)
00673 {
00674 char *out;
00675 assert (rcs != NULL);
00676
00677 if (rcs->text == NULL)
00678 out = NULL;
00679 else
00680 out = realloc (rcs->text, sizeof (char) * (strlen (rcs->text) + 1));
00681
00682 free (rcs);
00683 return out;
00684 }