Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* nonzstring.h */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Port                                                                   */
  6. /*                                                                           */
  7. /* Handling of non-NUL terminated stringd                                    */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13. #include "strutil.h"
  14.  
  15. #include "nonzstring.h"
  16.  
  17. /*!------------------------------------------------------------------------
  18.  * \fn     as_nonz_dynstr_ini(as_nonz_dynstr_t *p_str, size_t ini_capacity)
  19.  * \brief  create/initialize string
  20.  * \param  p_str string to set up
  21.  * \param  ini_capacity initial capacity
  22.  * ------------------------------------------------------------------------ */
  23.  
  24. void as_nonz_dynstr_ini(as_nonz_dynstr_t *p_str, size_t ini_capacity)
  25. {
  26.   p_str->p_str = (char*)calloc(1, ini_capacity);
  27.   p_str->capacity = p_str->p_str ? ini_capacity : 0;
  28.   p_str->len = 0;
  29. }
  30.  
  31. /*!------------------------------------------------------------------------
  32.  * \fn     as_nonz_dynstr_ini_c_str(as_nonz_dynstr_t *p_str, const char *p_src)
  33.  * \brief  create/initialize string from C string
  34.  * \param  p_str string to set up
  35.  * \param  p_src data source
  36.  * ------------------------------------------------------------------------ */
  37.  
  38. void as_nonz_dynstr_ini_c_str(as_nonz_dynstr_t *p_str, const char *p_src)
  39. {
  40.   size_t len = strlen(p_src);
  41.  
  42.   as_nonz_dynstr_ini(p_str, as_nonz_dynstr_roundup_len(len));
  43.   p_str->len = (p_str->capacity < len) ? p_str->capacity : len;
  44.   memcpy(p_str->p_str, p_src, p_str->len);
  45. }
  46.  
  47. /*!------------------------------------------------------------------------
  48.  * \fn     as_nonz_dynstr_realloc(as_nonz_dynstr_t *p_str, size_t new_capacity)
  49.  * \brief  resize buffer of string
  50.  * \param  p_str string to resize
  51.  * \param  new_capacity new capacity
  52.  * ------------------------------------------------------------------------ */
  53.  
  54. void as_nonz_dynstr_realloc(as_nonz_dynstr_t *p_str, size_t new_capacity)
  55. {
  56.   size_t old_capacity = p_str->capacity;
  57.   char *p_new_str = p_str->p_str
  58.                   ? (char*)realloc(p_str->p_str, new_capacity)
  59.                   : (char*)malloc(new_capacity);
  60.  
  61.   if (p_new_str)
  62.   {
  63.     p_str->p_str = p_new_str;
  64.     p_str->capacity = new_capacity;
  65.     if (new_capacity > old_capacity)
  66.       memset(p_str->p_str + old_capacity, 0, new_capacity - old_capacity);
  67.     else if (p_str->len > new_capacity)
  68.       p_str->len = new_capacity;
  69.   }
  70. }
  71.  
  72. /*!------------------------------------------------------------------------
  73.  * \fn     as_nonz_dynstr_free(as_nonz_dynstr_t *p_str)
  74.  * \brief  free_destroy string
  75.  * \param  p_str string to free
  76.  * ------------------------------------------------------------------------ */
  77.  
  78. void as_nonz_dynstr_free(as_nonz_dynstr_t *p_str)
  79. {
  80.   if (p_str->p_str)
  81.     free(p_str->p_str);
  82.   p_str->p_str = NULL;
  83.   p_str->len = p_str->capacity = 0;
  84. }
  85.  
  86. /*!------------------------------------------------------------------------
  87.  * \fn     as_nonz_dynstr_to_c_str(char *p_dest, const as_nonz_dynstr_t *p_src, size_t dest_len)
  88.  * \brief  convert string to C-style string
  89.  * \param  p_dest destination
  90.  * \param  p_src source
  91.  * \param  dest_len dest capacity
  92.  * \return result length
  93.  * ------------------------------------------------------------------------ */
  94.  
  95. size_t as_nonz_dynstr_to_c_str(char *p_dest, const as_nonz_dynstr_t *p_src, size_t dest_len)
  96. {
  97.   if (dest_len > 0)
  98.   {
  99.     unsigned TransLen = dest_len - 1;
  100.  
  101.     if (TransLen > p_src->len)
  102.       TransLen = p_src->len;
  103.     memcpy(p_dest, p_src->p_str, TransLen);
  104.     p_dest[TransLen] = '\0';
  105.     return TransLen;
  106.   }
  107.   else
  108.     return 0;
  109. }
  110.  
  111. /*!------------------------------------------------------------------------
  112.  * \fn     as_nonz_dynstr_copy(as_nonz_dynstr_t *p_dest, const as_nonz_dynstr_t *p_src)
  113.  * \brief  copy string
  114.  * \param  p_dest destination
  115.  * \param  p_src source
  116.  * \return actual dest length after copy
  117.  * ------------------------------------------------------------------------ */
  118.  
  119. size_t as_nonz_dynstr_copy(as_nonz_dynstr_t *p_dest, const as_nonz_dynstr_t *p_src)
  120. {
  121.   size_t trans_len;
  122.  
  123.   if (p_dest->capacity < p_src->capacity)
  124.     as_nonz_dynstr_realloc(p_dest, p_src->capacity);
  125.   trans_len = p_src->len;
  126.   if (trans_len > p_dest->capacity)
  127.     trans_len = p_dest->capacity;
  128.   memcpy(p_dest->p_str, p_src->p_str, p_dest->len = trans_len);
  129.   return p_dest->len;
  130. }
  131.  
  132. /*!------------------------------------------------------------------------
  133.  * \fn     as_nonz_dynstr_append_raw(as_nonz_dynstr_t *p_dest, const char *p_src, int src_len)
  134.  * \brief  extend string
  135.  * \param  p_dest string to extend
  136.  * \param  p_src what to append
  137.  * \param  src_len source length (-1 for NUL-terminated source)
  138.  * \return actual # of bytes transferred
  139.  * ------------------------------------------------------------------------ */
  140.  
  141. size_t as_nonz_dynstr_append_raw(as_nonz_dynstr_t *p_dest, const char *p_src, int src_len)
  142. {
  143.   size_t trans_len;
  144.  
  145.   if (src_len < 0)
  146.     src_len = strlen(p_src);
  147.  
  148.   if (p_dest->len + src_len > p_dest->capacity)
  149.     as_nonz_dynstr_realloc(p_dest, as_nonz_dynstr_roundup_len(p_dest->len + src_len));
  150.   trans_len = p_dest->capacity - p_dest->len;
  151.   if ((size_t)src_len < trans_len)
  152.     trans_len = src_len;
  153.   memcpy(p_dest->p_str + p_dest->len, p_src, trans_len);
  154.   p_dest->len += trans_len;
  155.   return trans_len;
  156. }
  157.  
  158. /*!------------------------------------------------------------------------
  159.  * \fn     as_nonz_dynstr_copy_c_str(as_nonz_dynstr_t *p_dest, const char *p_src)
  160.  * \brief  convert C-style string to non-NUL terminated string
  161.  * \param  p_dest string to fill
  162.  * \param  p_src string to fill from
  163.  * \return actual # of characters appended
  164.  * ------------------------------------------------------------------------ */
  165.  
  166. size_t as_nonz_dynstr_copy_c_str(as_nonz_dynstr_t *p_dest, const char *p_src)
  167. {
  168.   p_dest->len = 0;
  169.   return as_nonz_dynstr_append_raw(p_dest, p_src, -1);
  170. }
  171.  
  172. /*!------------------------------------------------------------------------
  173.  * \fn     as_nonz_dynstr_append(as_nonz_dynstr_t *p_dest, const as_nonz_dynstr_t *p_src)
  174.  * \brief  extend string by non-NUL terminated string
  175.  * \param  p_dest string to extend
  176.  * \param  p_src string to append
  177.  * \return actual # of characters appended
  178.  * ------------------------------------------------------------------------ */
  179.  
  180. size_t as_nonz_dynstr_append(as_nonz_dynstr_t *p_dest, const as_nonz_dynstr_t *p_src)
  181. {
  182.   return as_nonz_dynstr_append_raw(p_dest, p_src->p_str, p_src->len);
  183. }
  184.  
  185. /*!------------------------------------------------------------------------
  186.  * \fn     as_nonz_dynstr_cmp(const as_nonz_dynstr_t *p_str1, const as_nonz_dynstr_t *p_str2)
  187.  * \brief  compare two strings
  188.  * \param  p_str1, p_str2 strings to compare
  189.  * \return -1/0/+1 if Str1 </==/> Str2
  190.  * ------------------------------------------------------------------------ */
  191.  
  192. int as_nonz_dynstr_cmp(const as_nonz_dynstr_t *p_str1, const as_nonz_dynstr_t *p_str2)
  193. {
  194.   return strlencmp(p_str1->p_str, p_str1->len, p_str2->p_str, p_str2->len);
  195. }
  196.  
  197. /*!------------------------------------------------------------------------
  198.  * \fn     as_nonz_dynstr_find(const as_nonz_dynstr_t *p_haystack, const as_nonz_dynstr_t *p_needle)
  199.  * \brief  find first occurence of substring
  200.  * \param  p_haystack where to search
  201.  * \param  p_needle what to search
  202.  * \return first position or -1 if not found
  203.  * ------------------------------------------------------------------------ */
  204.  
  205. int as_nonz_dynstr_find(const as_nonz_dynstr_t *p_haystack, const as_nonz_dynstr_t *p_needle)
  206. {
  207.   int pos, maxpos = ((int)p_haystack->len) - ((int)p_needle->len);
  208.  
  209.   for (pos = 0; pos <= maxpos; pos++)
  210.     if (!memcmp(p_haystack->p_str + pos, p_needle->p_str, p_needle->len))
  211.       return pos;
  212.  
  213.   return -1;
  214. }
  215.  
  216. /*!------------------------------------------------------------------------
  217.  * \fn     as_nonz_dynstr_dump_hex(FILE *p_file, const as_dynstr_t *p_str)
  218.  * \brief  debug helper
  219.  * \param  p_file where to dump
  220.  * \param  p_str string to dump
  221.  * ------------------------------------------------------------------------ */
  222.  
  223. void as_nonz_dynstr_dump_hex(FILE *p_file, const as_nonz_dynstr_t *p_str)
  224. {
  225.   const char *p_run;
  226.  
  227.   fprintf(p_file, "[%u/%u]", (unsigned)p_str->len, (unsigned)p_str->capacity);
  228.   for (p_run = p_str->p_str; *p_run; p_run++) fprintf(p_file, " %02x", *p_run & 0xff);
  229.   fprintf(p_file, "\n");
  230. }
  231.