Guest User

str.h

a guest
Jan 18th, 2011
195
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.03 KB | None | 0 0
  1. #ifndef __STR_H__
  2. #define __STR_H__
  3.  
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <stdio.h>
  8.  
  9. typedef struct _str_t {
  10.     size_t capacity;
  11.     size_t length;
  12.     char data[1];
  13. } str_t;
  14.  
  15. typedef struct _str_vector_t {
  16.     size_t length;
  17.     str_t **vector;
  18. } str_vector_t;
  19.  
  20. typedef int bool;
  21.  
  22. static inline size_t allign(size_t ln) {
  23.     ln += 16 - ((ln + sizeof(str_t)) & 15);
  24.     return ln;
  25. }
  26.  
  27. static const size_t str_npos = (size_t)(-1);
  28. static const str_t str_empty = { 1u, 0u, {0} };
  29.  
  30. static inline str_t * str_new_ln(size_t ln) {
  31.     str_t *ret;
  32.     size_t cap = allign(ln);
  33.     ret = (str_t *)malloc(sizeof(str_t) + cap);
  34.     ret->length = ln;
  35.     ret->capacity = cap;
  36.     return ret;
  37. }
  38.  
  39. static inline str_t * str_new_pc(const char *pc) {
  40.     size_t sln = strlen(pc);
  41.     str_t * ret = str_new_ln(sln);
  42.     memcpy(ret->data, pc, sln);
  43.     return ret;
  44. }
  45.  
  46. static inline str_t * str_new_pcln(const char *pc, size_t ln) {
  47.     str_t * ret = str_new_ln(ln);
  48.     memcpy(ret->data, pc, ln);
  49.     return ret;
  50. }
  51.  
  52. static inline str_t * str_new_str(const str_t *str) {
  53.     return str_new_pcln(str->data, str->length);
  54. }
  55.  
  56. static inline void str_destroy(str_t **dst) {
  57.     free(*dst);
  58.     *dst = NULL;
  59. }
  60.  
  61. static inline void str_clear(str_t *str) {
  62.     str->length = 0;
  63. }
  64.  
  65. static inline char * str_c(str_t *str) {
  66.     str->data[str->length] = 0;
  67.     return str->data;
  68. }
  69.  
  70. static inline size_t str_length(const str_t *str) {
  71.     if( str != NULL ) {
  72.         return str->length;
  73.     }
  74.     else {
  75.         return 0;
  76.     }
  77. }
  78.  
  79. static inline bool str_is_empty(const str_t *str) {
  80.     size_t r;
  81.     if( str_length(str) == 0 ) {
  82.         return 1;
  83.     }
  84.     for( r = 0; r < str_length(str) && isspace(str->data[r]); ++r )
  85.         ;
  86.     if( r == str->length ) {
  87.         return 1; // true
  88.     }
  89.     return 0; // false
  90. }
  91.  
  92. static inline bool str_xeq_pc(const str_t *str, const char *pc) {
  93.     size_t sln = strlen(pc);
  94.     if( str->length < sln ) {
  95.         return 0; // false
  96.     }
  97.     return memcmp(str->data + (str->length - sln), pc, sln) == 0;
  98. }
  99.  
  100.  
  101. static inline str_t * str_substr(const str_t *str, size_t pos, size_t len) {
  102.     if( pos >= str->length || len == 0 ) {
  103.         return str_new_ln(0);
  104.     }
  105.     if( len == str_npos || pos + len > str->length ) {
  106.         len = str->length - pos;
  107.     }
  108.     return str_new_pcln(str->data + pos, len);
  109. }
  110.  
  111. static inline void str_alltrim(str_t **dst_str) {
  112.     size_t p1, p2;
  113.     str_t *tmp;
  114.     for(p1 = 0; p1 < (*dst_str)->length && isspace((*dst_str)->data[p1]); ++p1)
  115.         ;
  116.     if( p1 == (*dst_str)->length ) {
  117.         (*dst_str)->length = 0;
  118.         return;
  119.     }
  120.     for(p2 = (*dst_str)->length - 1; p2 + 1 > p1 && isspace((*dst_str)->data[p2]); --p2)
  121.         ;
  122.     tmp = str_substr(*dst_str, p1, p2 - p1 + 1);
  123.     str_destroy(dst_str);
  124.     *dst_str = tmp;
  125. }
  126.  
  127. static inline void str_chomp(str_t *str) {
  128.     char c;
  129.     if( str != NULL )
  130.         while( str->length != 0 && ((c = str->data[str->length-1]) == '\r' || c == '\n') )
  131.             --str->length;
  132. }
  133.  
  134. static inline void str_tolower(str_t *str) {
  135.     size_t i;
  136.     for(i = 0; i < str->length; ++i)
  137.         str->data[i] = tolower(str->data[i]);
  138. }
  139.  
  140. static inline void str_toupper(str_t *str) {
  141.     size_t i;
  142.     for(i = 0; i < str->length; ++i)
  143.         str->data[i] = toupper(str->data[i]);
  144. }
  145.  
  146. static inline void str_append_str(str_t **dest_str, const str_t *str) {
  147.     if( str == NULL || str->length == 0 ) {
  148.         return;
  149.     }
  150.     if( *dest_str == NULL )
  151.         *dest_str = str_new_str(str);
  152.     else {
  153.         if( (*dest_str)->capacity < (*dest_str)->length + str->length + 1 ) {
  154.             str_t *tmp = str_new_ln((*dest_str)->capacity + (str->capacity * 2));
  155.             memcpy(tmp->data, (*dest_str)->data, (*dest_str)->length);
  156.             tmp->length = (*dest_str)->length;
  157.             free(*dest_str);
  158.             *dest_str = tmp;
  159.         }
  160.         memcpy((*dest_str)->data + (*dest_str)->length, str->data, str->length);
  161.         (*dest_str)->length += str->length;
  162.     }
  163. }
  164.  
  165. static inline void str_append_pc(str_t **dest_str, const char *pc) {
  166.     size_t sln;
  167.     if( pc == NULL || (sln = strlen(pc)) == 0 ) {
  168.         return;
  169.     }
  170.     if( *dest_str == NULL )
  171.         *dest_str = str_new_pc(pc);
  172.     else {
  173.         if( (*dest_str)->capacity < (*dest_str)->length + sln + 1 ) {
  174.             str_t *tmp = str_new_ln((*dest_str)->capacity + (sln * 2));
  175.             memcpy(tmp->data, (*dest_str)->data, (*dest_str)->length);
  176.             tmp->length = (*dest_str)->length;
  177.             free(*dest_str);
  178.             *dest_str = tmp;
  179.         }
  180.         memcpy((*dest_str)->data + (*dest_str)->length, pc, sln);
  181.         (*dest_str)->length += sln;
  182.     }
  183. }
  184.  
  185. static inline void str_append_pcln(str_t **dest_str, const char *pc, size_t sln) {
  186.     if( pc == NULL || sln == 0 ) {
  187.         return;
  188.     }
  189.     if( *dest_str == NULL )
  190.         *dest_str = str_new_pcln(pc, sln);
  191.     else {
  192.         if( (*dest_str)->capacity < (*dest_str)->length + sln + 1 ) {
  193.             str_t *tmp = str_new_ln((*dest_str)->capacity + (sln * 2));
  194.             memcpy(tmp->data, (*dest_str)->data, (*dest_str)->length);
  195.             tmp->length = (*dest_str)->length;
  196.             free(*dest_str);
  197.             *dest_str = tmp;
  198.         }
  199.         memcpy((*dest_str)->data + (*dest_str)->length, pc, sln);
  200.         (*dest_str)->length += sln;
  201.     }
  202. }
  203.  
  204. static inline void str_append_c(str_t **dest_str, char c) {
  205.     if( *dest_str == NULL )
  206.         *dest_str = str_new_pcln(&c, 1);
  207.     else {
  208.         if( (*dest_str)->capacity < (*dest_str)->length + 2 ) {
  209.             str_t *tmp = str_new_ln((*dest_str)->capacity + 16);
  210.             memcpy(tmp->data, (*dest_str)->data, (*dest_str)->length);
  211.             tmp->length = (*dest_str)->length;
  212.             free(*dest_str);
  213.             *dest_str = tmp;
  214.         }
  215.         (*dest_str)->data[(*dest_str)->length] = c;
  216.         (*dest_str)->length += 1;
  217.     }
  218. }
  219.  
  220. static inline void str_replace_str(str_t **dest_str, size_t pos, size_t n, const str_t *str) {
  221.     size_t nl;
  222.     str_t *tmp;
  223.     if( pos == (*dest_str)->length ) {
  224.         str_append_str(dest_str, str);
  225.         return;
  226.     }
  227.     if( pos > (*dest_str)->length ) {
  228.         return;
  229.     }
  230.     if( str == NULL )
  231.         str = &str_empty;
  232.     if( n == str_npos || pos + n > (*dest_str)->length)
  233.         n = (*dest_str)->length - pos;
  234.     nl = (*dest_str)->length + str->length - n;
  235.     tmp = str_new_ln(nl);
  236.     if( pos )
  237.         memcpy(tmp->data, (*dest_str)->data, pos);
  238.     if( str->length )
  239.         memcpy(tmp->data + pos, str->data, str->length);
  240.     if( pos + n < (*dest_str)->length )
  241.         memcpy(tmp->data + pos + str->length, (*dest_str)->data + pos + n, (*dest_str)->length - n - pos);
  242.     str_destroy(dest_str);
  243.     *dest_str = tmp;
  244. }
  245.  
  246. static inline size_t str_find_str(const str_t *str, const str_t *substr, size_t pos) {
  247.     if( str == NULL )
  248.         return str_npos;
  249.     if( substr->length > str->length || str->length == 0 || substr->length == 0 ) {
  250.         return str_npos;
  251.     }
  252.     while( pos + substr->length <= str->length )
  253.         if( memcmp(str->data + pos, substr->data, substr->length) == 0 ) {
  254.             return pos;
  255.         }
  256.         else
  257.             ++pos;
  258.     return str_npos;
  259. }
  260.  
  261. static inline size_t str_find_pc(const str_t *str, const char *pc, size_t pos) {
  262.     size_t sln = strlen(pc);
  263.     if( str == NULL )
  264.         return str_npos;
  265.     if( sln > str->length || str->length == 0 || sln == 0 ) {
  266.         return str_npos;
  267.     }
  268.     while( pos + sln <= str->length )
  269.         if( memcmp(str->data + pos, pc, sln) == 0 ) {
  270.             return pos;
  271.         }
  272.         else
  273.             ++pos;
  274.     return str_npos;
  275. }
  276.  
  277. static inline size_t str_find_c(const str_t *str, char c, size_t pos) {
  278.     char *cptr;
  279.     if( str == NULL )
  280.         return str_npos;
  281.     if( pos >= str->length || str->length == 0 ) {
  282.         return str_npos;
  283.     }
  284.     cptr = (char*)memchr(str->data + pos, c, str->length - pos);
  285.     if( cptr != NULL ) {
  286.         return cptr - str->data;
  287.     }
  288.     return str_npos;
  289. }
  290.  
  291. static inline size_t str_rfind_c(const str_t *str, char c, size_t pos) {
  292.     if( str == NULL )
  293.         return str_npos;
  294.     if( str->length == 0 ) {
  295.         return str_npos;
  296.     }
  297.     if( pos >= str->length )
  298.         pos = str->length - 1;
  299.     while( pos + 1 > 0 ) {
  300.         if( str->data[pos] == c ) {
  301.             return pos;
  302.         }
  303.         --pos;
  304.     }
  305.     return str_npos;
  306. }
  307.  
  308. static inline size_t str_rfind_str(const str_t *str, const str_t *substr, size_t pos) {
  309.     if( str == NULL )
  310.         return str_npos;
  311.     if( substr->length > str->length || str->length == 0 || substr->length == 0 ) {
  312.         return str_npos;
  313.     }
  314.     if( pos == str_npos || pos + substr->length > str->length )
  315.         pos = str->length - substr->length;
  316.     while( pos + 1 > 0 )
  317.         if( memcmp(str->data + pos, substr->data, substr->length) == 0 ) {
  318.             return pos;
  319.         }
  320.         else
  321.             --pos;
  322.     return str_npos;
  323. }
  324.  
  325. static inline size_t str_rfind_pc(const str_t *str, const char *pc, size_t pos) {
  326.     size_t sln = strlen(pc);
  327.     if( str == NULL )
  328.         return str_npos;
  329.     if( sln > str->length || str->length == 0 || sln == 0 ) {
  330.         return str_npos;
  331.     }
  332.     if( pos == str_npos || pos + sln > str->length )
  333.         pos = str->length - sln;
  334.     while( pos + 1 > 0 )
  335.         if( memcmp(str->data + pos, pc, sln) == 0 ) {
  336.             return pos;
  337.         }
  338.         else
  339.             --pos;
  340.     return str_npos;
  341. }
  342.  
  343. static inline str_vector_t * str_vector_new(size_t ln) {
  344.     str_vector_t *ret = (str_vector_t *)malloc(sizeof(*ret));
  345.     ret->vector = (str_t**)calloc(ln,sizeof(str_t*));
  346.     ret->length = ln;
  347.     return ret;
  348. }
  349.  
  350. static inline void str_vector_add_str(str_vector_t *strv, str_t *str) {
  351.     strv->vector = (str_t**)realloc(strv->vector, (strv->length + 1) * sizeof(str_t*));
  352.     strv->vector[strv->length] = str;
  353.     ++strv->length;
  354. }
  355.  
  356. static inline void str_vector_del_str(str_vector_t *strv) {
  357.     str_destroy(strv->vector + strv->length - 1);
  358.     --strv->length;
  359. }
  360.  
  361. static inline void str_vector_destroy(str_vector_t **pstrv) {
  362.     if( *pstrv != NULL ) {
  363.         size_t n;
  364.         for(n = 0; n < (*pstrv)->length; ++n)
  365.             str_destroy((*pstrv)->vector + n);
  366.         free((*pstrv)->vector);
  367.         free(*pstrv);
  368.         *pstrv = NULL;
  369.     }
  370. }
  371.  
  372. static inline str_vector_t * str_split_pc(const str_t *str, const char *pc) {
  373.     size_t sln;
  374.     str_vector_t *ret = str_vector_new(0);
  375.     if( str_length(str) == 0 ) {
  376.         str_vector_add_str(ret, str_new_ln(0));
  377.         return ret;
  378.     }
  379.     if( pc == NULL || (sln = strlen(pc)) == 0 ) {
  380.         size_t i;
  381.         str_vector_destroy(&ret);
  382.         ret = str_vector_new(str->length);
  383.         for(i = 0; i < str->length; ++i)
  384.             ret->vector[i] = str_new_pcln(str->data + i, 1);
  385.         return ret;
  386.     }
  387.     else {
  388.         size_t npos = 0, fpos;
  389.         do {
  390.             fpos = str_find_pc(str, pc, npos);
  391.             if( fpos != str_npos ) {
  392.                 str_vector_add_str(ret, str_substr(str, npos, fpos - npos));
  393.             }
  394.             else {
  395.                 str_vector_add_str(ret, str_substr(str, npos, str->length - npos));
  396.                 break;
  397.             }
  398.             npos = fpos + sln;
  399.         } while(1);
  400.         return ret;
  401.     }
  402. }
  403.  
  404. #endif /* __STR_H__ */
Advertisement
Add Comment
Please, Sign In to add comment