📄 octstr.c.debug
字号:
void octstr_base64_to_binary(Octstr *ostr){ long triplet; long pos, len; long to; int quadpos = 0; int warned = 0; unsigned char *data; seems_valid(ostr); gw_assert(!ostr->immutable); len = ostr->len; data = ostr->data; if (len == 0) return; to = 0; triplet = 0; quadpos = 0; for (pos = 0; pos < len; pos++) { int c = data[pos]; int sixbits; if (c >= 'A' && c <= 'Z') { sixbits = c - 'A'; } else if (c >= 'a' && c <= 'z') { sixbits = 26 + c - 'a'; } else if (c >= '0' && c <= '9') { sixbits = 52 + c - '0'; } else if (c == '+') { sixbits = 62; } else if (c == '/') { sixbits = 63; } else if (c == '=') { /* These can only occur at the end of encoded * text. RFC 2045 says we can assume it really * is the end. */ break; } else if (isspace(c)) { /* skip whitespace */ continue; } else { if (!warned) { warning(0, "Unusual characters in base64 " "encoded text."); warned = 1; } continue; } triplet = (triplet << 6) | sixbits; quadpos++; if (quadpos == 4) { data[to++] = (triplet >> 16) & 0xff; data[to++] = (triplet >> 8) & 0xff; data[to++] = triplet & 0xff; quadpos = 0; } } /* Deal with leftover octets */ switch (quadpos) { case 0: break; case 3: /* triplet has 18 bits, we want the first 16 */ data[to++] = (triplet >> 10) & 0xff; data[to++] = (triplet >> 2) & 0xff; break; case 2: /* triplet has 12 bits, we want the first 8 */ data[to++] = (triplet >> 4) & 0xff; break; case 1: warning(0, "Bad padding in base64 encoded text."); break; } ostr->len = to; data[to] = '\0'; seems_valid(ostr);}long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base){ /* strtol wants a char *, and we have to compare the result to * an unsigned char *. The easiest way to avoid warnings without * introducing typecasts is to use two variables. */ char *endptr; unsigned char *endpos; long number; seems_valid(ostr); gw_assert(nump != NULL); gw_assert(base == 0 || (base >= 2 && base <= 36)); if (pos >= ostr->len) { errno = EINVAL; return -1; } errno = 0; number = strtol(ostr->data + pos, &endptr, base); endpos = endptr; if (errno == ERANGE) return -1; if (endpos == ostr->data + pos) { errno = EINVAL; return -1; } *nump = number; return endpos - ostr->data;}int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter){ long end = pos + len; seems_valid(ostr); gw_assert(len >= 0); if (pos >= ostr->len) return 1; if (end > ostr->len) end = ostr->len; for ( ; pos < end; pos++) { if (!filter(ostr->data[pos])) return 0; } return 1;}void octstr_convert_range(Octstr *ostr, long pos, long len, octstr_func_t map){ long end = pos + len; seems_valid(ostr); gw_assert(!ostr->immutable); gw_assert(len >= 0); if (pos >= ostr->len) return; if (end > ostr->len) end = ostr->len; for ( ; pos < end; pos++) { ostr->data[pos] = map(ostr->data[pos]); } seems_valid(ostr);}int octstr_compare(Octstr *ostr1, Octstr *ostr2){ int ret; long len; seems_valid(ostr1); seems_valid(ostr2); if (ostr1->len < ostr2->len) len = ostr1->len; else len = ostr2->len; if (len == 0) { if (ostr1->len == 0 && ostr2->len > 0) return -1; if (ostr1->len > 0 && ostr2->len == 0) return 1; return 0; } ret = memcmp(ostr1->data, ostr2->data, len); if (ret == 0) { if (ostr1->len < ostr2->len) ret = -1; else if (ostr1->len > ostr2->len) ret = 1; } return ret;}int octstr_case_compare(Octstr *os1, Octstr *os2){ int c1, c2; long i, len; seems_valid(os1); seems_valid(os2); if (os1->len < os2->len) len = os1->len; else len = os2->len; if (len == 0) { if (os1->len == 0 && os2->len > 0) return -1; if (os1->len > 0 && os2->len == 0) return 1; return 0; } for (i = 0; i < len; ++i) { c1 = toupper(os1->data[i]); c2 = toupper(os2->data[i]); if (c1 != c2) break; } if (i == len) { if (i == os1->len && i == os2->len) return 0; if (i == os1->len) return -1; return 1; } else { c1 = toupper(os1->data[i]); c2 = toupper(os2->data[i]); if (c1 < c2) return -1; if (c1 == c2) return 0; return 1; }}int octstr_ncompare(Octstr *ostr1, Octstr *ostr2, long n){ long len; seems_valid(ostr1); seems_valid(ostr2); if ((ostr1->len < ostr2->len) && (ostr1->len < n)) len = ostr1->len; else if ((ostr2->len < ostr1->len) && (ostr2->len < n)) len = ostr2->len; else len = n; if (len == 0) return 0; return memcmp(ostr1->data, ostr2->data, len);}int octstr_str_compare(Octstr *ostr, const char *str){ seems_valid(ostr); if (str == NULL) return -1; if (ostr->data == NULL) return strcmp("", str); return strcmp(ostr->data, str);}int octstr_search_char(Octstr *ostr, int ch, long pos){ unsigned char *p; seems_valid(ostr); gw_assert(ch >= 0); gw_assert(ch <= UCHAR_MAX); gw_assert(pos >= 0); if (pos >= ostr->len) return -1; p = memchr(ostr->data + pos, ch, ostr->len - pos); if (!p) return -1; return p - ostr->data;}int octstr_search(Octstr *haystack, Octstr *needle, long pos){ int first; seems_valid(haystack); seems_valid(needle); gw_assert(pos >= 0); /* Always "find" an empty string */ if (needle->len == 0) return 0; if (needle->len == 1) return octstr_search_char(haystack, needle->data[0], pos); /* For each occurrence of needle's first character in ostr, * check if the rest of needle follows. Stop if there are no * more occurrences, or if the rest of needle can't possibly * fit in the haystack. */ first = needle->data[0]; pos = octstr_search_char(haystack, first, pos); while (pos >= 0 && haystack->len - pos >= needle->len) { if (memcmp(haystack->data + pos, needle->data, needle->len) == 0) return pos; pos = octstr_search_char(haystack, first, pos + 1); } return -1;}int octstr_case_search(Octstr *haystack, Octstr *needle, long pos){ long i, j; int c1, c2; seems_valid(haystack); seems_valid(needle); gw_assert(pos >= 0); /* Always "find" an empty string */ if (needle->len == 0) return 0; for (i = pos; i <= haystack->len - needle->len; ++i) { for (j = 0; j < needle->len; ++j) { c1 = toupper(haystack->data[i + j]); c2 = toupper(needle->data[j]); if (c1 != c2) break; } if (j == needle->len) return i; } return -1; }int octstr_print(FILE *f, Octstr *ostr){ gw_assert(f != NULL); seems_valid(ostr); if (ostr->len == 0) return 0; if (fwrite(ostr->data, ostr->len, 1, f) != 1) { error(errno, "Couldn't write all of octet string to file."); return -1; } return 0;}int octstr_pretty_print(FILE *f, Octstr *ostr){ unsigned char *p; long i; gw_assert(f != NULL); seems_valid(ostr); p = ostr->data; for (i = 0; i < ostr->len; ++i, ++p) { if (isprint(*p)) fprintf(f, "%c", *p); else fprintf(f, "\\x%02x", *p); } if (ferror(f)) return -1; return 0;}int octstr_write_to_socket(int socket, Octstr *ostr){ long len; unsigned char *data; int ret; gw_assert(socket >= 0); seems_valid(ostr); data = ostr->data; len = ostr->len; while (len > 0) { ret = write(socket, data, len); if (ret == -1) { if (errno != EINTR) { error(errno, "Writing to socket failed"); return -1; } } else { /* ret may be less than len */ len -= ret; data += ret; } } return 0;}long octstr_write_data(Octstr *ostr, int fd, long from){ long ret; gw_assert(fd >= 0); gw_assert(from >= 0); seems_valid(ostr); if (from >= ostr->len) return 0; ret = write(fd, ostr->data + from, ostr->len - from); if (ret < 0) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) return 0; error(errno, "Error writing %ld octets to fd %d:", ostr->len - from, fd); return -1; } return ret;}int octstr_append_from_socket(Octstr *ostr, int socket){ unsigned char buf[4096]; int len; seems_valid(ostr); gw_assert(!ostr->immutable);again: len = recv(socket, buf, sizeof(buf), 0); if (len < 0 && errno == EINTR) goto again; if (len < 0) { error(errno, "Could not read from socket %d", socket); return -1; } octstr_append_data(ostr, buf, len); return len;}void octstr_insert_impl (Octstr *ostr1, Octstr *ostr2, long pos, const char *file, long line, const char *func){ seems_valid_real(ostr1, file, line, func); seems_valid_real(ostr2, file, line, func); gw_assert(pos <= ostr1->len); gw_assert(!ostr1->immutable); if (ostr2->len == 0) return; octstr_grow(ostr1, ostr1->len + ostr2->len); memmove(ostr1->data + pos + ostr2->len, ostr1->data + pos, ostr1->len - pos); memcpy(ostr1->data + pos, ostr2->data, ostr2->len); ostr1->len += ostr2->len; ostr1->data[ostr1->len] = '\0'; seems_valid(ostr1);}void octstr_truncate(Octstr *ostr, int new_len){ seems_valid(ostr); gw_assert(!ostr->immutable); gw_assert(new_len >= 0); if (new_len >= ostr->len) return; ostr->len = new_len; ostr->data[new_len] = '\0'; seems_valid(ostr);}void octstr_strip_blanks(Octstr *text){ int start = 0, end, len = 0; seems_valid(text); gw_assert(!text->immutable); /* Remove white space from the beginning of the text */ while (isspace(octstr_get_char(text, start)) && start <= octstr_len(text)) start ++; if (start > 0) octstr_delete(text, 0, start); /* and from the end. */ if ((len = octstr_len(text)) > 0) { end = len = len - 1; while (isspace(octstr_get_char(text, end)) && end >= 0) end--; octstr_delete(text, end + 1, len - end); } seems_valid(text);}void octstr_strip_nonalphanums(Octstr *text){ int start = 0, end, len = 0; seems_valid(text); gw_assert(!text->immutable); /* Remove white space from the beginning of the text */ while (!isalnum(octstr_get_char(text, start)) && start <= octstr_len(text)) start ++; if (start > 0) octstr_delete(text, 0, start); /* and from the end. */ if ((len = octstr_len(text)) > 0) { end = len = len - 1; while (!isalnum(octstr_get_char(text, end)) && end >= 0) end--; octstr_delete(text, end + 1, len - end); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -