str.c

Go to the documentation of this file.
00001 
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #if defined(unix) || defined(__unix__) || defined(__MACH__)
00015 #include <unistd.h>
00016 #endif
00017 #include <errno.h>
00018 #ifdef _WINDOWS
00019 #include <io.h>
00020 #endif
00021 
00022 #include "str.h"
00023 #include "common.h"
00024 #include "log.h"
00025 
00026 cp_string *cp_string_create(char *data, int len)
00027 {
00028     cp_string *str;
00029     
00030 #ifdef DEBUG
00031     if (len < 0) 
00032     {
00033         cp_error(CP_INVALID_VALUE, "negative length (%d)", len);
00034         return NULL;
00035     }
00036 #endif
00037     
00038     str = calloc(1, sizeof(cp_string));
00039 
00040     if (str)
00041     {
00042         str->len = len;
00043         str->size = str->len + 1;
00044         str->data = malloc(str->size * sizeof(char));
00045         if (str->data)
00046             memcpy(str->data, data, str->len);
00047         else
00048         {
00049             cp_error(CP_MEMORY_ALLOCATION_FAILURE, "can\'t create string (%d bytes)", str->len);
00050             free(str);
00051             str = NULL;
00052         }
00053     }
00054 
00055     return str;
00056 }
00057 
00058 cp_string *cp_string_create_empty(int initial_size)
00059 {
00060     cp_string *str = calloc(1, sizeof(cp_string));
00061 
00062     if (str)
00063     {
00064         str->len = 0;
00065         str->size = initial_size + 1;
00066         str->data = (char *) malloc(str->size * sizeof(char));
00067         if (str->data == NULL)
00068         {
00069             free(str);
00070             str = NULL;
00071         }
00072     }
00073 
00074     return str;
00075 }
00076 
00077 void cp_string_delete(cp_string *str)
00078 {
00079     if (str)
00080     {
00081         if (str->data)
00082             free(str->data);
00083 
00084         free(str);
00085     }
00086 }
00087 
00088 void cp_string_drop_wrap(cp_string *str)
00089 {
00090     if (str) free(str);
00091 }
00092 
00093 void cp_string_drop_content(char *str)
00094 {
00095     if (str) free(str);
00096 }
00097 
00098 void cp_string_destroy(cp_string *str)
00099 {
00100     cp_string_delete(str);
00101 }
00102 
00103 void cp_string_clear(cp_string *str)
00104 {
00105     if (str)
00106         memset(str, 0, sizeof(cp_string));
00107 }
00108 
00109 void cp_string_reset(cp_string *str)
00110 {
00111     if (str)
00112     {
00113 //      if (str->data)
00114 //          free(str->data);
00115         str->len = 0;
00116 //      str->size = 1;
00117 //      str->data = malloc(str->size * sizeof(char));
00118         str->data[0] = '\0';
00119     }
00120 }
00121 
00122     
00123 cp_string *cp_string_cstrcpy(cp_string *str, char *cstr)
00124 {
00125     if (str)
00126     {
00127         str->len = strlen(cstr);
00128         if (str->size < str->len + 1)
00129         {
00130             str->size = str->len + 1;
00131             str->data = malloc(str->size * sizeof(char));
00132         }
00133         if (str->data)
00134             memcpy(str->data, cstr, str->size * sizeof(char));
00135         else
00136         {
00137             free(str);
00138             str = NULL;
00139         }
00140     }
00141 
00142     return str;
00143 }
00144 
00145 cp_string *cp_string_cpy(cp_string *dst, cp_string *src)
00146 {
00147     dst->len = src->len;
00148     if (dst->size < src->len + 1)
00149     {
00150         dst->size = src->len + 1;
00151         dst->data = malloc(dst->size * sizeof(char));
00152     }
00153     if (dst->data)
00154         memcpy(dst->data, src->data, src->len);
00155     else 
00156         return NULL;
00157 
00158     return dst;
00159 }
00160 
00161 cp_string *cp_string_dup(cp_string *src)
00162 {
00163     cp_string *str = calloc(1, sizeof(cp_string));
00164 
00165     if (str)
00166     {
00167         *str = *src; /* bitwise copy */
00168         str->data = malloc((str->len + 1) * sizeof(char));
00169         if (str->data)
00170             memcpy(str->data, src->data, (str->len  + 1) * sizeof(char));
00171         else
00172         {
00173             free(str);
00174             str = NULL;
00175         }
00176     }
00177 
00178     return str;
00179 }
00180 
00181 cp_string *cp_string_cstrdup(char *src)
00182 {
00183     cp_string *str = calloc(1, sizeof(cp_string));
00184 
00185     if (str)
00186     {
00187         str->len = strlen(src);
00188         str->size = str->len + 1;
00189         str->data = malloc(str->size * sizeof(char));
00190         if (str->data == NULL)
00191         {
00192             free(str);
00193             return NULL;
00194         }
00195         memcpy(str->data, src, str->size);
00196     }
00197 
00198     return str;
00199 }
00200     
00201 cp_string *cp_string_cat(cp_string *str, cp_string *appendum)
00202 {
00203     int len = str->len;
00204     str->len += appendum->len;
00205     if (str->len + 1 > str->size)
00206     {
00207         str->size = str->len + 1;
00208         str->data = realloc(str->data, str->size * sizeof(char));
00209     }
00210     if (str->data)
00211         memcpy(str->data + len * sizeof(char), appendum->data, 
00212             appendum->len * sizeof(char));
00213 
00214     return str;
00215 }
00216 
00217 cp_string *cp_string_cstrcat(cp_string *str, char *cstr)
00218 {
00219     int len = str->len;
00220     int clen = strlen(cstr);
00221 
00222     str->len += clen * sizeof(char);
00223     if (str->len + 1 > str->size)
00224     {
00225 //      str->size = str->len + 0x400 - (str->len % 0x400); /* align to 1kb block */
00226         str->size = str->len + 1;
00227         str->data = realloc(str->data, str->size * sizeof(char));
00228     }
00229     if (str->data)
00230         memcpy(str->data + len * sizeof(char), cstr, clen);
00231 
00232     return str;
00233 }
00234 
00235 cp_string *cp_string_append_char(cp_string *str, char ch)
00236 {
00237     if (str->len + 1 > str->size)
00238     {
00239         str->size = str->len + 0x100;
00240         str->data = realloc(str->data, str->size * sizeof(char));
00241         if (str->data == NULL) return NULL;
00242     }
00243     str->data[str->len++] = ch;
00244 
00245     return str;
00246 }
00247 
00248 cp_string *cp_string_cat_bin(cp_string *str, void *bin, int len)
00249 {
00250     int olen = str->len;
00251     str->len += len;
00252 
00253     if (str->len > str->size)
00254     {
00255         str->size = str->len + 0x400 - (str->len % 0x400); /* align to 1kb block */
00256         str->data = realloc(str->data, str->size * sizeof(char));
00257     }
00258     memcpy(&str->data[olen], bin, len);
00259 
00260     return str;
00261 }
00262 
00263 int cp_string_cmp(cp_string *s1, cp_string *s2)
00264 {
00265     if (s1 == s2) return 0; //~~ implies cp_string_cmp(NULL, NULL) == 0
00266 
00267     if (s1 == NULL) return -1;
00268     if (s2 == NULL) return 1;
00269 
00270     if (s1->len == s2->len)
00271         return memcmp(s1->data, s2->data, s1->len);
00272     else
00273     {
00274         int p = (s1->len > s2->len) ? s2->len : s1->len;
00275         int rc = memcmp(s1->data, s2->data, p);
00276         if (rc == 0) 
00277             return s1->len - s2->len;
00278         return rc;
00279     }
00280 }
00281 
00282 char *cp_string_tocstr(cp_string *str)
00283 {
00284     char *cstr = NULL;
00285     
00286     if (str)
00287     {
00288         str->data[str->len * sizeof(char)] = '\0';
00289 //      str->data[str->len * sizeof(char) + 1] = '\0';
00290         cstr = str->data;
00291     }
00292 
00293     return cstr;
00294 }
00295 
00296 int cp_string_len(cp_string *s)
00297 {
00298     return s->len;
00299 }
00300 
00301 char *cp_string_data(cp_string *s)
00302 {
00303     return s->data;
00304 }
00305 
00306 #define CHUNK 0x1000
00307 cp_string *cp_string_read(int fd, int len)
00308 {
00309     char buf[CHUNK];
00310     int read_len;
00311     cp_string *res = NULL;
00312     
00313     if (len == 0)
00314         read_len = CHUNK;
00315     else
00316         read_len = len < CHUNK ? len : CHUNK;
00317 
00318     while (len == 0 || res == NULL || res->len < len)
00319     {
00320         int rc = 
00321 #ifdef CP_HAS_READ
00322             read(fd, buf, read_len);
00323 #else
00324             _read(fd, buf, read_len);
00325 #endif /* CP_HAS_READ */
00326         if (rc <= 0) break;
00327         if (res == NULL)
00328         {
00329             res = cp_string_create(buf, rc);
00330             if (res == NULL) return NULL;
00331         }
00332         else
00333             cp_string_cat_bin(res, buf, rc);
00334     }
00335 
00336     return res;
00337 }
00338 
00339 int cp_string_write(cp_string *str, int fd)
00340 {
00341     int rc;
00342     int total = 0;
00343 
00344     while (total < str->len)
00345     {
00346         rc =
00347 #ifdef CP_HAS_WRITE
00348             write(fd, &str->data[total], str->len - total);
00349 #else
00350             _write(fd, &str->data[total], str->len - total);
00351 #endif
00352         /* write sets EAGAIN when a socket is marked non-blocking and the
00353          * write would block. trying to write again could result in spinning
00354          * on the write call.
00355          */
00356         if (rc == -1) 
00357         {
00358             if (errno == EINTR /* || errno == EAGAIN */) /* try again */ 
00359                 continue;
00360             else 
00361                 break; 
00362         }
00363         total += rc;
00364     }
00365 
00366     return total;
00367 }
00368 
00369 cp_string *cp_string_read_file(char *filename)
00370 {
00371     cp_string *res;
00372     FILE *fp = fopen(filename, "rb");
00373     if (fp == NULL) return NULL;
00374 
00375     res = cp_string_read(fileno(fp), 0);
00376     fclose(fp);
00377 
00378     return res;
00379 }
00380 
00381 int cp_string_write_file(cp_string *str, char *filename)
00382 {
00383     int rc;
00384     FILE *fp = fopen(filename, "wb");
00385     if (fp == NULL) return 0;
00386 
00387     rc = cp_string_write(str, fileno(fp));
00388     fclose(fp);
00389 
00390     return rc;
00391 }
00392 
00393 #define LINELEN 81
00394 #define CHARS_PER_LINE 16
00395 
00396 static char *print_char = 
00397     "                "
00398     "                "
00399     " !\"#$%&'()*+,-./"
00400     "0123456789:;<=>?"
00401     "@ABCDEFGHIJKLMNO"
00402     "PQRSTUVWXYZ[\\]^_"
00403     "`abcdefghijklmno"
00404     "pqrstuvwxyz{|}~ "
00405     "                "
00406     "                "
00407     " "
00408     ""
00409     ""
00410     ""
00411     ""
00412     "";
00413 
00414 void cp_string_dump(cp_string *str)
00415 {
00416     int rc;
00417     int idx;
00418     char prn[LINELEN];
00419     char lit[CHARS_PER_LINE + 1];
00420     char hc[4];
00421     short line_done = 1;
00422 
00423     rc = str->len;
00424     idx = 0;
00425     lit[CHARS_PER_LINE] = '\0';
00426     while (rc > 0)
00427     {
00428         if (line_done) 
00429 #ifdef CP_HAS_SNPRINTF
00430             snprintf(prn, LINELEN, "%08X: ", idx);
00431 #else
00432             sprintf(prn, "%08X: ", idx);
00433 #endif /* CP_HAS_SNPRINTF */
00434         do
00435         {
00436             unsigned char c = str->data[idx];
00437 #ifdef CP_HAS_SNPRINTF
00438             snprintf(hc, 4, "%02X ", c);
00439 #else
00440             sprintf(hc, "%02X ", c);
00441 #endif /* CP_HAS_SNPRINTF */
00442 #ifdef CP_HAS_STRLCAT
00443             strlcat(prn, hc, 4);
00444 #else
00445             strcat(prn, hc);
00446 #endif /* CP_HAS_STRLCAT */
00447             lit[idx % CHARS_PER_LINE] = print_char[c];
00448             ++idx;
00449         } while (--rc > 0 && (idx % CHARS_PER_LINE != 0));
00450         line_done = (idx % CHARS_PER_LINE) == 0;
00451         if (line_done) 
00452             printf("%s  %s\n", prn, lit);
00453         else if (rc == 0)
00454 #ifdef CP_HAS_STRLCAT
00455             strlcat(prn, "   ", LINELEN);
00456 #else
00457             strcat(prn, "   ");
00458 #endif /* CP_HAS_STRLCAT */
00459     }
00460     if (!line_done)
00461     {
00462         lit[(idx % CHARS_PER_LINE)] = '\0';
00463         while ((++idx % CHARS_PER_LINE) != 0) 
00464 #ifdef CP_HAS_STRLCAT
00465             strlcat(prn, "   ", LINELEN);
00466 #else
00467             strcat(prn, "   ");
00468 #endif /* CP_HAS_STRLCAT */
00469         printf("%s  %s\n", prn, lit);
00470 
00471     }
00472 }
00473 
00475 void cp_string_flip(cp_string *str)
00476 {
00477     if (str->len)
00478     {
00479         char *i, *f, ch;
00480         f = &str->data[str->len - 1];
00481         i = str->data;
00482         while (i < f)
00483         {
00484             ch = *i;
00485             *i = *f;
00486             *f = ch;
00487             i++;
00488             f--;
00489         }
00490     }
00491 }
00492 
00493 /* remove all occurrences of letters from str */
00494 cp_string *cp_string_filter(cp_string *str, char *letters)
00495 {
00496     char *i;
00497     char *f;
00498 
00499     str->data[str->len] = '\0';
00500     i = str->data;
00501     while ((f = strpbrk(i, letters)))
00502     {
00503         i = f;
00504         while (*f && strchr(letters, *f)) f++;
00505         if (*f)
00506         {
00507             memmove(i, f, str->len - (f - str->data));
00508             str->len -= f - i;
00509             str->data[str->len] = '\0';
00510         }
00511         else
00512         {
00513             *i = '\0';
00514             str->len -= str->len - (i - str->data);
00515             break;
00516         }
00517     }
00518 
00519     return str;
00520 }
00521 

Generated on Mon Dec 5 23:00:22 2011 for cprops by  doxygen 1.4.7