octstr.c
来自「The Kannel Open Source WAP and SMS gatew」· C语言 代码 · 共 2,586 行 · 第 1/5 页
C
2,586 行
if (pos < octstr_len(os)) list_append(list, octstr_copy(os, pos, octstr_len(os))); return list;}int octstr_item_match(void *item, void *pattern){ return octstr_compare(item, pattern) == 0;}int octstr_item_case_match(void *item, void *pattern){ return octstr_case_compare(item, pattern) == 0;}void octstr_dump(const Octstr *ostr, int level){ unsigned char *p, *d, buf[1024], charbuf[256]; long pos; const int octets_per_line = 16; int c, this_line_begins_at; if (ostr == NULL) return; seems_valid(ostr); debug("gwlib.octstr", 0, "%*sOctet string at %p:", level, "", (void *) ostr); debug("gwlib.octstr", 0, "%*s len: %lu", level, "", (unsigned long) ostr->len); debug("gwlib.octstr", 0, "%*s size: %lu", level, "", (unsigned long) ostr->size); debug("gwlib.octstr", 0, "%*s immutable: %d", level, "", ostr->immutable); buf[0] = '\0'; p = buf; d = charbuf; this_line_begins_at = 0; for (pos = 0; pos < octstr_len(ostr); ) { c = octstr_get_char(ostr, pos); sprintf(p, "%02x ", c); p = strchr(p, '\0'); if (isprint(c)) *d++ = c; else *d++ = '.'; ++pos; if (pos - this_line_begins_at == octets_per_line) { *d = '\0'; debug("gwlib.octstr", 0, "%*s data: %s %s", level, "", buf, charbuf); buf[0] = '\0'; charbuf[0] = '\0'; p = buf; d = charbuf; this_line_begins_at = pos; } } if (pos - this_line_begins_at > 0) { *d = '\0'; debug("gwlib.octstr", 0, "%*s data: %-*.*s %s", level, "", octets_per_line*3, octets_per_line*3, buf, charbuf); } debug("gwlib.octstr", 0, "%*sOctet string dump ends.", level, "");}void octstr_dump_short(Octstr *ostr, int level, const char *name){ char buf[100]; char *p; long i; int c; if (ostr == NULL) { debug("gwlib.octstr", 0, "%*s%s: NULL", level, "", name); return; } seems_valid(ostr); if (ostr->len < 20) { p = buf; for (i = 0; i < ostr->len; i++) { c = ostr->data[i]; if (c == '\n') { *p++ = '\\'; *p++ = 'n'; } else if (!isprint(c)) { break; } else if (c == '"') { *p++ = '\\'; *p++ = '"'; } else if (c == '\\') { *p++ = '\\'; *p++ = '\\'; } else { *p++ = c; } } if (i == ostr->len) { *p++ = 0; /* We got through the loop without hitting nonprintable * characters. */ debug("gwlib.octstr", 0, "%*s%s: \"%s\"", level, "", name, buf); return; } } debug("gwlib.octstr", 0, "%*s%s:", level, "", name); octstr_dump(ostr, level + 1);}void octstr_url_encode(Octstr *ostr){ long i, n, len = 0; int all_safe; unsigned char c, *str, *str2, *res, *hexits; if (ostr == NULL) return; seems_valid(ostr); gw_assert(!ostr->immutable); if (ostr->len == 0) return; /* calculate new length */ for (i = n = 0, str = ostr->data, all_safe = 1; i < ostr->len; i++) { c = *str++; if (c == ' ') { all_safe = 0; continue; } if (!is_safe[c]) { n++; all_safe = 0; } } if (all_safe) /* we are done, all chars are safe */ return; hexits = "0123456789ABCDEF"; /* * no need to reallocate if n == 0, so we make replace in place. * NOTE: we don't do if (xxx) ... else ... because conditional jump * is not so fast as just compare (alex). */ res = str2 = (n ? gw_malloc((len = ostr->len + 2 * n + 1)) : ostr->data); for (i = 0, str = ostr->data; i < ostr->len; i++) { c = *str++; if (c == ' ') { *str2++ = '+'; continue; } if (!is_safe[c]) { *str2++ = '%'; *str2++ = hexits[c >> 4 & 0xf]; *str2++ = hexits[c & 0xf]; continue; } *str2++ = c; } *str2 = 0; /* we made replace in place */ if (n) { gw_free(ostr->data); ostr->data = res; ostr->size = len; ostr->len = len - 1; } seems_valid(ostr);}int octstr_url_decode(Octstr *ostr){ unsigned char *string = ostr->data; unsigned char *dptr = ostr->data; int code, code2, ret = 0; if (ostr == NULL) return 0; seems_valid(ostr); gw_assert(!ostr->immutable); if (ostr->len == 0) return 0; do { if (*string == '%') { if (*(string + 1) == '\0' || *(string + 2) == '\0') { warning(0, "octstr_url_decode: corrupted end-of-string <%s>", string); ret = -1; break; } code = H2B(*(string + 1)); code2 = H2B(*(string + 2)); if (code == -1 || code2 == -1) { warning(0, "octstr_url_decode: garbage detected (%c%c%c) skipping.", *string, *(string + 1), *(string + 2)); *dptr++ = *string++; *dptr++ = *string++; *dptr++ = *string++; ret = -1; continue; } *dptr++ = code << 4 | code2; string += 3; } else if (*string == '+') { *dptr++ = ' '; string++; } else *dptr++ = *string++; } while (*string); /* we stop here because it terimates encoded string */ *dptr = '\0'; ostr->len = (dptr - ostr->data); seems_valid(ostr); return ret;}long octstr_get_bits(Octstr *ostr, long bitpos, int numbits){ long pos; long result; int mask; int shiftwidth; seems_valid(ostr); gw_assert(bitpos >= 0); gw_assert(numbits <= 32); gw_assert(numbits >= 0); pos = bitpos / 8; bitpos = bitpos % 8; /* This also takes care of the len == 0 case */ if (pos >= ostr->len) return 0; mask = (1 << numbits) - 1; /* It's easy if the range fits in one octet */ if (bitpos + numbits <= 8) { /* shiftwidth is the number of bits to ignore on the right. * bitpos 0 is the leftmost bit. */ shiftwidth = 8 - (bitpos + numbits); return (ostr->data[pos] >> shiftwidth) & mask; } /* Otherwise... */ result = 0; while (bitpos + numbits > 8) { result = (result << 8) | ostr->data[pos]; numbits -= (8 - bitpos); bitpos = 0; pos++; if (pos >= ostr->len) return (result << numbits) & mask; } gw_assert(bitpos == 0); result <<= numbits; result |= ostr->data[pos] >> (8 - numbits); return result & mask;}void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value){ long pos; unsigned long mask; int shiftwidth; int bits; int maxlen; int c; seems_valid(ostr); gw_assert(!ostr->immutable); gw_assert(bitpos >= 0); gw_assert(numbits <= 32); gw_assert(numbits >= 0); maxlen = (bitpos + numbits + 7) / 8; if (maxlen > ostr->len) { octstr_grow(ostr, maxlen); /* Make sure the new octets start out with value 0 */ for (pos = ostr->len; pos < maxlen; pos++) { ostr->data[pos] = 0; } ostr->len = maxlen; ostr->data[maxlen] = 0; } mask = (1 << numbits) - 1; /* mask is also the largest value that fits */ gw_assert(value <= mask); pos = bitpos / 8; bitpos = bitpos % 8; /* Does the range fit in one octet? */ if (bitpos + numbits <= 8) { /* shiftwidth is the number of bits to ignore on the right. * bitpos 0 is the leftmost bit. */ shiftwidth = 8 - (bitpos + numbits); /* Extract the bits we don't want to affect */ c = ostr->data[pos] & ~(mask << shiftwidth); c |= value << shiftwidth; gw_assert(pos < ostr->len); ostr->data[pos] = c; return; } /* Otherwise... */ /* If speed is a problem here, we could have separate cases for * the first octet (which may have bitpos > 0), and the rest, * which don't. */ while (bitpos + numbits > 8) { /* We want this many bits from the value */ bits = 8 - bitpos; /* There are this many bits to their right in the value */ shiftwidth = numbits - bits; /* Construct a mask for "bits" bits on the far right */ mask = (1 << bits) - 1; /* Get the bits we want */ c = (value >> shiftwidth) & mask; /* Merge them with the bits that are already there */ gw_assert(pos < ostr->len); ostr->data[pos] = (ostr->data[pos] & ~mask) | c; numbits -= (8 - bitpos); bitpos = 0; pos++; } gw_assert(bitpos == 0); gw_assert(pos < ostr->len); /* Set remaining bits. This is just like the single-octet case * before the loop, except that we know bitpos is 0. */ mask = (1 << numbits) - 1; shiftwidth = 8 - numbits; c = ostr->data[pos] & ~(mask << shiftwidth); c |= value << shiftwidth; ostr->data[pos] = c; seems_valid(ostr);}void octstr_append_uintvar(Octstr *ostr, unsigned long value){ /* A uintvar is defined to be up to 32 bits large, so it will * fit in 5 octets. */ unsigned char octets[5]; int i; int start; /* Handle last byte separately; it has no continuation bit, * and must be encoded even if value is 0. */ octets[4] = value & 0x7f; value >>= 7; for (i = 3; value > 0 && i >= 0; i--) { octets[i] = 0x80 | (value & 0x7f); value >>= 7; } start = i + 1; octstr_append_data(ostr, octets + start, 5 - start);}long octstr_extract_uintvar(Octstr *ostr, unsigned long *value, long pos){ int c; int count; unsigned long ui; ui = 0; for (count = 0; count < 5; count++) { c = octstr_get_char(ostr, pos + count); if (c < 0) return -1; ui = (ui << 7) | (c & 0x7f); if (!(c & 0x80)) { *value = ui; return pos + count + 1; } } return -1;}void octstr_append_decimal(Octstr *ostr, long value){ char tmp[128]; sprintf(tmp, "%ld", value); octstr_append_cstr(ostr, tmp);}/********************************************************************** * octstr_format and related private functions *//* * A parsed form of the format string. This struct has been carefully * defined so that it can be initialized with {0} and it will have * the correct defaults. */struct format{ int minus; int zero; long min_width; int has_prec; long prec; long type;};static void format_flags(struct format *format, const char **fmt){ int done; done = 0; do { switch (**fmt) { case '-': format->minus = 1; break; case '0': format->zero = 1; break; default: done = 1; } if (!done) ++(*fmt); } while (!done);}static void format_width(struct format *format, const char **fmt, VALPARM(args)){ char *end; if (**fmt == '*') { format->min_width = va_arg(VALST(args), int); ++(*fmt); } else if (isdigit(**(const unsigned char **) fmt)) { format->min_width = strtol(*fmt, &end, 10); *fmt = end; /* XXX error checking is missing from here */ }}static void format_prec(struct format *format, const char **fmt, VALPARM(args)){ char *end; if (**fmt != '.') return; ++(*fmt); if (**fmt == '*') { format->has_prec = 1; format->prec = va_arg(VALST(args), int); ++(*fmt); } else if (isdigit(**(const unsigned char **) fmt)) { format->has_prec = 1; format->prec = strtol(*fmt, &end, 10); *fmt = end; /* XXX error checking is missing from here */ }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?