⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 str.c

📁 文件传输协议linux 下vsftpd2.1.0.tar.gz
💻 C
字号:
/* * Part of Very Secure FTPd * Licence: GPL v2 * Author: Chris Evans * str.c * * Generic string handling functions. The fact that a string is implemented * internally using a buffer is not exposed in the API. If you can't see * the buffers, you can't handle them in a screwed way. Or so goes the * theory, anyway... *//* Anti-lamer measures deployed, sir! */#define PRIVATE_HANDS_OFF_p_buf p_buf#define PRIVATE_HANDS_OFF_len len#define PRIVATE_HANDS_OFF_alloc_bytes alloc_bytes#include "str.h"/* Ick. Its for die() */#include "utility.h"#include "sysutil.h"/* File local functions */static void str_split_text_common(struct mystr* p_src, struct mystr* p_rhs,                                  const char* p_text, int is_reverse);static int str_equal_internal(const char* p_buf1, unsigned int buf1_len,                              const char* p_buf2, unsigned int buf2_len);/* Private functions */static voids_setbuf(struct mystr* p_str, char* p_newbuf){  if (p_str->p_buf != 0)  {    bug("p_buf not NULL when setting it");  }  p_str->p_buf = p_newbuf;}voidprivate_str_alloc_memchunk(struct mystr* p_str, const char* p_src,                           unsigned int len){  /* Make sure this will fit in the buffer */  unsigned int buf_needed = len + 1;  if (buf_needed > p_str->alloc_bytes)  {    str_free(p_str);    s_setbuf(p_str, vsf_sysutil_malloc(buf_needed));    p_str->alloc_bytes = buf_needed;  }  vsf_sysutil_memcpy(p_str->p_buf, p_src, len);  p_str->p_buf[len] = '\0';  p_str->len = len;}voidprivate_str_append_memchunk(struct mystr* p_str, const char* p_src,                            unsigned int len){  unsigned int buf_needed = p_str->len + len + 1;  if (buf_needed > p_str->alloc_bytes)  {    p_str->p_buf = vsf_sysutil_realloc(p_str->p_buf, buf_needed);    p_str->alloc_bytes = buf_needed;  }  vsf_sysutil_memcpy(p_str->p_buf + p_str->len, p_src, len);  p_str->p_buf[p_str->len + len] = '\0';  p_str->len += len;}/* Public functions */voidstr_alloc_text(struct mystr* p_str, const char* p_src){  unsigned int len = vsf_sysutil_strlen(p_src);  private_str_alloc_memchunk(p_str, p_src, len);}voidstr_copy(struct mystr* p_dest, const struct mystr* p_src){  private_str_alloc_memchunk(p_dest, p_src->p_buf, p_src->len);}const char*str_strdup(const struct mystr* p_str){  return vsf_sysutil_strdup(str_getbuf(p_str));}voidstr_alloc_alt_term(struct mystr* p_str, const char* p_src, char term){  const char* p_search = p_src;  unsigned int len = 0;  while (*p_search != term)  {    p_search++;    len++;  }  private_str_alloc_memchunk(p_str, p_src, len);}voidstr_alloc_ulong(struct mystr* p_str, unsigned long the_long){  str_alloc_text(p_str, vsf_sysutil_ulong_to_str(the_long));}voidstr_alloc_filesize_t(struct mystr* p_str, filesize_t the_filesize){  str_alloc_text(p_str, vsf_sysutil_filesize_t_to_str(the_filesize));}voidstr_free(struct mystr* p_str){  if (p_str->p_buf != 0)  {    vsf_sysutil_free(p_str->p_buf);  }  p_str->p_buf = 0;  p_str->len = 0;  p_str->alloc_bytes = 0;}voidstr_empty(struct mystr* p_str){  /* Ensure a buffer is allocated. */  (void) str_getbuf(p_str);  str_trunc(p_str, 0);}voidstr_trunc(struct mystr* p_str, unsigned int trunc_len){  if (trunc_len >= p_str->alloc_bytes)  {    bug("trunc_len not smaller than alloc_bytes in str_trunc");  }  p_str->len = trunc_len;  p_str->p_buf[p_str->len] = '\0';}voidstr_reserve(struct mystr* p_str, unsigned int res_len){  /* Reserve space for the trailing zero as well. */  res_len++;  if (res_len > p_str->alloc_bytes)  {    p_str->p_buf = vsf_sysutil_realloc(p_str->p_buf, res_len);    p_str->alloc_bytes = res_len;  }  p_str->p_buf[res_len - 1] = '\0';}intstr_isempty(const struct mystr* p_str){  return (p_str->len == 0);}unsigned intstr_getlen(const struct mystr* p_str){  return p_str->len;}const char*str_getbuf(const struct mystr* p_str){  if (p_str->p_buf == 0)  {    if (p_str->len != 0 || p_str->alloc_bytes != 0)    {      bug("p_buf NULL and len or alloc_bytes != 0 in str_getbuf");    }    private_str_alloc_memchunk((struct mystr*)p_str, 0, 0);  }  return p_str->p_buf;}intstr_strcmp(const struct mystr* p_str1, const struct mystr* p_str2){  return str_equal_internal(p_str1->p_buf, p_str1->len,                            p_str2->p_buf, p_str2->len);}static intstr_equal_internal(const char* p_buf1, unsigned int buf1_len,                   const char* p_buf2, unsigned int buf2_len){  int retval;  unsigned int minlen = buf1_len;  if (buf2_len < minlen)  {    minlen = buf2_len;  }  retval = vsf_sysutil_memcmp(p_buf1, p_buf2, minlen);  if (retval != 0 || buf1_len == buf2_len)  {    return retval;  }  /* Strings equal but lengths differ. The greater one, then, is the longer */  return (int) (buf1_len - buf2_len);}intstr_equal(const struct mystr* p_str1, const struct mystr* p_str2){  return (str_strcmp(p_str1, p_str2) == 0);}intstr_equal_text(const struct mystr* p_str, const char* p_text){  unsigned int cmplen = vsf_sysutil_strlen(p_text);  return (str_equal_internal(p_str->p_buf, p_str->len, p_text, cmplen) == 0);}voidstr_append_str(struct mystr* p_str, const struct mystr* p_other){  private_str_append_memchunk(p_str, p_other->p_buf, p_other->len);}voidstr_append_text(struct mystr* p_str, const char* p_src){  unsigned int len = vsf_sysutil_strlen(p_src);  private_str_append_memchunk(p_str, p_src, len);}voidstr_append_char(struct mystr* p_str, char the_char){  private_str_append_memchunk(p_str, &the_char, sizeof(the_char));}voidstr_append_ulong(struct mystr* p_str, unsigned long the_ulong){  str_append_text(p_str, vsf_sysutil_ulong_to_str(the_ulong));}voidstr_append_filesize_t(struct mystr* p_str, filesize_t the_filesize){  str_append_text(p_str, vsf_sysutil_filesize_t_to_str(the_filesize));}voidstr_append_double(struct mystr* p_str, double the_double){  str_append_text(p_str, vsf_sysutil_double_to_str(the_double));}voidstr_upper(struct mystr* p_str){  unsigned int i;  for (i=0; i < p_str->len; i++)  {    p_str->p_buf[i] = vsf_sysutil_toupper(p_str->p_buf[i]);  }}voidstr_rpad(struct mystr* p_str, const unsigned int min_width){  unsigned int to_pad;  if (p_str->len >= min_width)  {    return;  }  to_pad = min_width - p_str->len;  while (to_pad--)  {    str_append_char(p_str, ' ');  }}voidstr_lpad(struct mystr* p_str, const unsigned int min_width){  static struct mystr s_tmp_str;  unsigned int to_pad;  if (p_str->len >= min_width)  {    return;  }  to_pad = min_width - p_str->len;  str_empty(&s_tmp_str);  while (to_pad--)  {    str_append_char(&s_tmp_str, ' ');  }  str_append_str(&s_tmp_str, p_str);  str_copy(p_str, &s_tmp_str);}voidstr_replace_char(struct mystr* p_str, char from, char to){  unsigned int i;  for (i=0; i < p_str->len; i++)  {    if (p_str->p_buf[i] == from)    {      p_str->p_buf[i] = to;    }  }}voidstr_replace_text(struct mystr* p_str, const char* p_from, const char* p_to){  static struct mystr s_lhs_chunk_str;  static struct mystr s_rhs_chunk_str;  unsigned int lhs_len;  str_copy(&s_lhs_chunk_str, p_str);  str_free(p_str);  do  {    lhs_len = str_getlen(&s_lhs_chunk_str);    str_split_text(&s_lhs_chunk_str, &s_rhs_chunk_str, p_from);    /* Copy lhs to destination */    str_append_str(p_str, &s_lhs_chunk_str);    /* If this was a 'hit', append the 'to' text */    if (str_getlen(&s_lhs_chunk_str) < lhs_len)    {      str_append_text(p_str, p_to);    }    /* Current rhs becomes new lhs */    str_copy(&s_lhs_chunk_str, &s_rhs_chunk_str);  } while (!str_isempty(&s_lhs_chunk_str));}voidstr_split_char(struct mystr* p_src, struct mystr* p_rhs, char c){  /* Just use str_split_text */  char ministr[2];  ministr[0] = c;  ministr[1] = '\0';  str_split_text(p_src, p_rhs, ministr);}voidstr_split_char_reverse(struct mystr* p_src, struct mystr* p_rhs, char c){  /* Just use str_split_text_reverse */  char ministr[2];  ministr[0] = c;  ministr[1] = '\0';  str_split_text_reverse(p_src, p_rhs, ministr);}voidstr_split_text(struct mystr* p_src, struct mystr* p_rhs, const char* p_text){  str_split_text_common(p_src, p_rhs, p_text, 0);}voidstr_split_text_reverse(struct mystr* p_src, struct mystr* p_rhs,                       const char* p_text){  str_split_text_common(p_src, p_rhs, p_text, 1);}static voidstr_split_text_common(struct mystr* p_src, struct mystr* p_rhs,                      const char* p_text, int is_reverse){  struct str_locate_result locate_result;  unsigned int indexx;  unsigned int search_len = vsf_sysutil_strlen(p_text);  if (is_reverse)  {    locate_result = str_locate_text_reverse(p_src, p_text);  }  else  {    locate_result = str_locate_text(p_src, p_text);  }  /* Not found? */  if (!locate_result.found)  {    str_empty(p_rhs);    return;  }  indexx = locate_result.index;  if (indexx + search_len > p_src->len)  {    bug("indexx invalid in str_split_text");  }   /* Build rhs */  private_str_alloc_memchunk(p_rhs, p_src->p_buf + indexx + search_len,                             p_src->len - indexx - search_len);  /* Build lhs */  str_trunc(p_src, indexx);}struct str_locate_resultstr_locate_str(const struct mystr* p_str, const struct mystr* p_look_str){  return str_locate_text(p_str, str_getbuf(p_look_str));}struct str_locate_resultstr_locate_str_reverse(const struct mystr* p_str,                       const struct mystr* p_look_str){  return str_locate_text_reverse(p_str, str_getbuf(p_look_str));}struct str_locate_resultstr_locate_char(const struct mystr* p_str, char look_char){  char look_str[2];  look_str[0] = look_char;  look_str[1] = '\0';  return str_locate_text(p_str, look_str);}struct str_locate_resultstr_locate_chars(const struct mystr* p_str, const char* p_chars){  struct str_locate_result retval;  unsigned int num_chars = vsf_sysutil_strlen(p_chars);  unsigned int i = 0;  retval.found = 0;  retval.char_found = 0;  retval.index = 0;  for (; i < p_str->len; ++i)  {    unsigned int j = 0;    char this_char = p_str->p_buf[i];    for (; j < num_chars; ++j)    {      if (p_chars[j] == this_char)      {        retval.found = 1;        retval.index = i;        retval.char_found = p_chars[j];        return retval;      }    }  }  return retval;}struct str_locate_resultstr_locate_text(const struct mystr* p_str, const char* p_text){  struct str_locate_result retval;  unsigned int i;  unsigned int text_len = vsf_sysutil_strlen(p_text);  retval.found = 0;  retval.char_found = 0;  retval.index = 0;  if (text_len == 0 || text_len > p_str->len)  {    /* Not found */    return retval;  }  for (i=0; i <= (p_str->len - text_len); i++)  {    if (vsf_sysutil_memcmp(p_str->p_buf + i, p_text, text_len) == 0)    {      retval.found = 1;      retval.index = i;      return retval;    }  }  /* Not found */  return retval;}struct str_locate_resultstr_locate_text_reverse(const struct mystr* p_str, const char* p_text){  struct str_locate_result retval;  unsigned int i;  unsigned int text_len = vsf_sysutil_strlen(p_text);  retval.found = 0;  retval.char_found = 0;  retval.index = 0;  if (text_len == 0 || text_len > p_str->len)  {    return retval;  }  i = p_str->len - text_len;  /* Want to go through loop once even if i==0 */  while (1)  {    if (vsf_sysutil_memcmp(p_str->p_buf + i, p_text, text_len) == 0)    {      retval.found = 1;      retval.index = i;      return retval;    }    if (i == 0)    {      break;    }    i--;  }  /* Not found */  return retval;}voidstr_left(const struct mystr* p_str, struct mystr* p_out, unsigned int chars){  if (chars > p_str->len)  {    bug("chars invalid in str_left");  }  private_str_alloc_memchunk(p_out, p_str->p_buf, chars);}voidstr_right(const struct mystr* p_str, struct mystr* p_out, unsigned int chars){  unsigned int indexx = p_str->len - chars;  if (chars > p_str->len)  {    bug("chars invalid in str_right");  }  private_str_alloc_memchunk(p_out, p_str->p_buf + indexx, chars);}voidstr_mid_to_end(const struct mystr* p_str, struct mystr* p_out,               unsigned int indexx){  if (indexx > p_str->len)  {    bug("invalid indexx in str_mid_to_end");  }  private_str_alloc_memchunk(p_out, p_str->p_buf + indexx,                             p_str->len - indexx);}charstr_get_char_at(const struct mystr* p_str, const unsigned int indexx){  if (indexx >= p_str->len)  {    bug("bad indexx in str_get_char_at");  }  return p_str->p_buf[indexx];}intstr_contains_space(const struct mystr* p_str){  unsigned int i;  for (i=0; i < p_str->len; i++)  {    if (vsf_sysutil_isspace(p_str->p_buf[i]))    {      return 1;    }  }  return 0;}intstr_all_space(const struct mystr* p_str){  unsigned int i;  for (i=0; i < p_str->len; i++)  {    if (!vsf_sysutil_isspace(p_str->p_buf[i]))    {      return 0;    }  }  return 1;}intstr_contains_unprintable(const struct mystr* p_str){  unsigned int i;  for (i=0; i < p_str->len; i++)  {    if (!vsf_sysutil_isprint(p_str->p_buf[i]))    {      return 1;    }  }  return 0;}intstr_atoi(const struct mystr* p_str){  return vsf_sysutil_atoi(str_getbuf(p_str));}filesize_tstr_a_to_filesize_t(const struct mystr* p_str){  return vsf_sysutil_a_to_filesize_t(str_getbuf(p_str));}unsigned intstr_octal_to_uint(const struct mystr* p_str){  return vsf_sysutil_octal_to_uint(str_getbuf(p_str));}intstr_getline(const struct mystr* p_str, struct mystr* p_line_str,            unsigned int* p_pos){  unsigned int start_pos = *p_pos;  unsigned int curr_pos = start_pos;  unsigned int buf_len = str_getlen(p_str);  const char* p_buf = str_getbuf(p_str);  unsigned int out_len;  if (start_pos > buf_len)  {    bug("p_pos out of range in str_getline");  }  str_empty(p_line_str);  if (start_pos == buf_len)  {    return 0;  }  while (curr_pos < buf_len && p_buf[curr_pos] != '\n')  {    curr_pos++;  }  out_len = curr_pos - start_pos;  /* If we ended on a \n - skip it */  if (curr_pos < buf_len && p_buf[curr_pos] == '\n')  {    curr_pos++;  }  private_str_alloc_memchunk(p_line_str, p_buf + start_pos, out_len);  *p_pos = curr_pos;  return 1;}intstr_contains_line(const struct mystr* p_str, const struct mystr* p_line_str){  static struct mystr s_curr_line_str;  unsigned int pos = 0;  while (str_getline(p_str, &s_curr_line_str, &pos))  {    if (str_equal(&s_curr_line_str, p_line_str))    {      return 1;    }  }  return 0;}voidstr_replace_unprintable(struct mystr* p_str, char new_char){  unsigned int i;  for (i=0; i < p_str->len; i++)  {    if (!vsf_sysutil_isprint(p_str->p_buf[i]))    {      p_str->p_buf[i] = new_char;    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -