octstr.c
来自「The Kannel Open Source WAP and SMS gatew」· C语言 代码 · 共 2,586 行 · 第 1/5 页
C
2,586 行
static void format_type(struct format *format, const char **fmt){ switch (**fmt) { case 'h': case 'l': format->type = **fmt; ++(*fmt); break; }}static void convert(Octstr *os, struct format *format, const char **fmt, VALPARM(args)){ Octstr *new; char *s, *pad; long n; unsigned long u; char tmpfmt[1024]; char tmpbuf[1024]; char c; void *p; new = NULL; switch (**fmt) { case 'c': c = va_arg(VALST(args), int); new = octstr_create_from_data(&c, 1); break; case 'd': case 'i': switch (format->type) { case 'l': n = va_arg(VALST(args), long); break; case 'h': n = (short) va_arg(VALST(args), int); break; default: n = va_arg(VALST(args), int); break; } new = octstr_create(""); octstr_append_decimal(new, n); break; case 'o': case 'u': case 'x': case 'X': switch (format->type) { case 'l': u = va_arg(VALST(args), unsigned long); break; case 'h': u = (unsigned short) va_arg(VALST(args), unsigned int); break; default: u = va_arg(VALST(args), unsigned int); break; } tmpfmt[0] = '%'; tmpfmt[1] = 'l'; tmpfmt[2] = **fmt; tmpfmt[3] = '\0'; sprintf(tmpbuf, tmpfmt, u); new = octstr_create(tmpbuf); break; case 'e': case 'f': case 'g': sprintf(tmpfmt, "%%"); if (format->minus) strcat(tmpfmt, "-"); if (format->zero) strcat(tmpfmt, "0"); if (format->min_width > 0) sprintf(strchr(tmpfmt, '\0'), "%ld", format->min_width); if (format->has_prec) sprintf(strchr(tmpfmt, '\0'), ".%ld", format->prec); if (format->type != '\0') sprintf(strchr(tmpfmt, '\0'), "%c", (int) format->type); sprintf(strchr(tmpfmt, '\0'), "%c", **fmt); snprintf(tmpbuf, sizeof(tmpbuf), tmpfmt, va_arg(VALST(args), double)); new = octstr_create(tmpbuf); break; case 's': s = va_arg(VALST(args), char *); if (format->has_prec && format->prec < (long) strlen(s)) n = format->prec; else n = (long) strlen(s); new = octstr_create_from_data(s, n); break; case 'p': p = va_arg(VALST(args), void *); sprintf(tmpfmt, "%p", p); new = octstr_create(tmpfmt); break; case 'S': new = octstr_duplicate(va_arg(VALST(args), Octstr *)); if (!new) new = octstr_imm("(null)"); if (format->has_prec) octstr_truncate(new, format->prec); break; case 'E': new = octstr_duplicate(va_arg(VALST(args), Octstr *)); if (!new) new = octstr_imm("(null)"); octstr_url_encode(new); /* * note: we use blind truncate - encoded character can get cut half-way. */ if (format->has_prec) octstr_truncate(new, format->prec); break; case 'H': new = octstr_duplicate(va_arg(VALST(args), Octstr *)); if (!new) new = octstr_imm("(null)"); /* upper case */ octstr_binary_to_hex(new, 1); if (format->has_prec) octstr_truncate(new, (format->prec % 2 ? format->prec - 1 : format->prec)); break; case '%': new = octstr_imm("%"); break; default: panic(0, "octstr_format format string syntax error."); } if (format->zero) pad = "0"; else pad = " "; if (format->minus) { while (format->min_width > octstr_len(new)) octstr_append_data(new, pad, 1); } else { while (format->min_width > octstr_len(new)) octstr_insert_data(new, 0, pad, 1); } octstr_append(os, new); octstr_destroy(new); if (**fmt != '\0') ++(*fmt);}Octstr *octstr_format(const char *fmt, ...){ Octstr *os; va_list args; va_start(args, fmt); os = octstr_format_valist(fmt, args); va_end(args); return os;}Octstr *octstr_format_valist_real(const char *fmt, va_list args){ Octstr *os; size_t n; os = octstr_create(""); while (*fmt != '\0') { struct format format = { 0, }; n = strcspn(fmt, "%"); octstr_append_data(os, fmt, n); fmt += n; gw_assert(*fmt == '%' || *fmt == '\0'); if (*fmt == '\0') continue; ++fmt; format_flags(&format, &fmt); format_width(&format, &fmt, VARGS(args)); format_prec(&format, &fmt, VARGS(args)); format_type(&format, &fmt); convert(os, &format, &fmt, VARGS(args)); } seems_valid(os); return os;}void octstr_format_append(Octstr *os, const char *fmt, ...){ Octstr *temp; va_list args; va_start(args, fmt); temp = octstr_format_valist(fmt, args); va_end(args); octstr_append(os, temp); octstr_destroy(temp);}unsigned long octstr_hash_key(Octstr *ostr){ unsigned long key = 0; long i; if (ostr == NULL) return 0; for (i = 0; i < octstr_len(ostr); i++) key = key + octstr_get_char(ostr, i); return key;}/********************************************************************** * Local functions. */static void seems_valid_real(const Octstr *ostr, const char *filename, long lineno, const char *function){ gw_assert(immutables_init); gw_assert_place(ostr != NULL, filename, lineno, function); gw_assert_allocated(ostr, filename, lineno, function); gw_assert_place(ostr->len >= 0, filename, lineno, function); gw_assert_place(ostr->size >= 0, filename, lineno, function); if (ostr->size == 0) { gw_assert_place(ostr->len == 0, filename, lineno, function); gw_assert_place(ostr->data == NULL, filename, lineno, function); } else { gw_assert_place(ostr->len + 1 <= ostr->size, filename, lineno, function); gw_assert_place(ostr->data != NULL, filename, lineno, function); if (!ostr->immutable) gw_assert_allocated(ostr->data, filename, lineno, function); gw_assert_place(ostr->data[ostr->len] == '\0', filename, lineno, function); }}intoctstr_recode (Octstr *tocode, Octstr *fromcode, Octstr *orig){ Octstr *octstr_utf8 = NULL; Octstr *octstr_final = NULL; int resultcode = 0; if (octstr_case_compare(tocode, fromcode) == 0) { goto cleanup_and_exit; } if ((octstr_case_compare(fromcode, octstr_imm ("utf-8")) != 0) && (octstr_case_compare(fromcode, octstr_imm ("utf8")) != 0)) { if (charset_to_utf8(orig, &octstr_utf8, fromcode) < 0) { resultcode = -1; goto cleanup_and_exit; } } else { octstr_utf8 = octstr_duplicate(orig); } if ((octstr_case_compare(tocode, octstr_imm ("utf-8")) != 0) && (octstr_case_compare(tocode, octstr_imm ("utf8")) != 0)) { if (charset_from_utf8(octstr_utf8, &octstr_final, tocode) < 0) { resultcode = -1; goto cleanup_and_exit; } } else { octstr_final = octstr_duplicate(octstr_utf8); } octstr_truncate(orig, 0); octstr_append(orig, octstr_final); cleanup_and_exit: octstr_destroy (octstr_utf8); octstr_destroy (octstr_final); return resultcode;}void octstr_strip_char(Octstr *text, char ch){ int start = 0; seems_valid(text); gw_assert(!text->immutable); /* Remove char from the beginning of the text */ while ((ch == octstr_get_char(text, start)) && start <= octstr_len(text)) start ++; if (start > 0) octstr_delete(text, 0, start); seems_valid(text);}int octstr_isnum(Octstr *ostr1){ int start = 0; char c; seems_valid(ostr1); while (start < octstr_len(ostr1)) { c = octstr_get_char(ostr1, start); if (!isdigit(c) && (c!='+')) return 0; start++; } return 1;}void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl){ int p = 0; long len, repl_len; len = octstr_len(needle); repl_len = octstr_len(repl); while ((p = octstr_search(haystack, needle, p)) != -1) { octstr_delete(haystack, p, len); octstr_insert(haystack, repl, p); p += repl_len; }}int octstr_symbolize(Octstr *ostr){ long len, i; seems_valid(ostr); gw_assert(!ostr->immutable); if (ostr->len == 0) return 0; /* Check if it's in the right format */ if (!octstr_check_range(ostr, 0, ostr->len, gw_isxdigit)) return -1; len = ostr->len + (ostr->len/2); octstr_grow(ostr, ostr->len * 2); for (i = 0; i < len; i += 3) octstr_insert_data(ostr, i, "%", 1); return 1;}void octstr_delete_matching(Octstr *haystack, Octstr *needle){ int p = -1; long len; seems_valid(haystack); seems_valid(needle); gw_assert(!haystack->immutable); len = octstr_len(needle); while ((p = octstr_search(haystack, needle, p + 1)) != -1) { octstr_delete(haystack, p, len); p -= len; }} int octstr_is_all_hex(Octstr *os) { long len, i; int ch; seems_valid(os); len = octstr_len(os); for (i = 0; i < len; ++i) { ch = octstr_get_char(os, i); if (!gw_isxdigit(ch)) return 0; } return 1;}/* * function octstr_convert_to_html_entities() * make data HTML safe by converting appropriate characters to HTML entities * Input: data to be inserted in HTML **/void octstr_convert_to_html_entities(Octstr* input){ int i; for (i = 0; i < octstr_len(input); ++i) { switch (octstr_get_char(input, i)) {#define ENTITY(a,b) \ case a: \ octstr_delete(input, i, 1); \ octstr_insert(input, octstr_imm("&" b ";"), i); \ i += sizeof(b); break;#include "gwlib/html-entities.def"#undef ENTITY } }}/* * This function is meant to find html entities in an octstr. * The html-entities.def file must be sorted alphabetically for * this function to work (according to current Locale in use).*/static int octstr_find_entity(Octstr* input, int startfind, int endfind){#define ENTITY(a,b) { a, b }, struct entity_struct { int entity; char *entity_str; }; const struct entity_struct entities[] = {#include "html-entities.def" { -1, "" } /* pivot */ };#undef ENTITY int center; /* position in table that we are about to compare */ int matchresult; /* result of match agains found entity name. indicates less, equal or greater */ if (endfind == 0) { /* when calling this function we do not (nor even want to) know the * sizeof(entities). Hence this check. */ endfind = (sizeof(entities) / sizeof(struct entity_struct)) - 1; } center = startfind + ((endfind - startfind) / 2); matchresult = octstr_str_compare(input, entities[center].entity_str); if (matchresult == 0) { return entities[center].entity; } if (endfind - startfind <= 1) { /* we are at the end of our results */ return -1; } if (matchresult < 0) { /* keep searching in first part of the table */ return octstr_find_entity(input, startfind, center); } else { /* keep searching in last part of the table */ return octstr_find_entity(input, center, endfind); }}/* * function octstr_convert_from_html_entities() * convert HTML safe data back to binary data by replacing HTML entities with their * respective character values * Input: data to be inserted in HTML **/void octstr_convert_from_html_entities(Octstr* input){ int startpos = 0, endpos; int entity; Octstr *match; while ((startpos = octstr_search_char(input, '&', startpos)) != -1) { endpos = octstr_search_char(input, ';', startpos + 1); if (endpos >= 0) { match = octstr_copy(input, startpos + 1, endpos - startpos - 1); entity = octstr_find_entity(match, 0, 0); if (entity >= 0) { octstr_delete(input, startpos, endpos - startpos + 1); octstr_insert_char(input, startpos, entity); } octstr_destroy(match); } startpos++; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?