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 + -
显示快捷键?