📄 octet_string.c
字号:
*buf |= (ch&1) << bits_unused; break; default: st->bits_unused = bits_unused; return -1; } } if(bits_unused == 8) { st->size = buf - st->buf; st->bits_unused = 0; } else { st->size = buf - st->buf + 1; st->bits_unused = bits_unused; } assert(st->size <= _ns); st->buf[st->size] = 0; /* Courtesy termination */ return chunk_size; /* Converted in full */}/* * Something like strtod(), but with stricter rules. */static intOS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { int32_t val = 0; const char *p; for(p = buf; p < end; p++) { int ch = *p; if((val * base + base) < 0) return -1; /* Strange huge value */ switch(ch) { case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/ val = val * base + (ch - 0x30); break; case 0x41: case 0x42: case 0x43: /* ABC */ case 0x44: case 0x45: case 0x46: /* DEF */ val = val * base + (ch - 0x41 + 10); break; case 0x61: case 0x62: case 0x63: /* abc */ case 0x64: case 0x65: case 0x66: /* def */ val = val * base + (ch - 0x61 + 10); break; case 0x3b: /* ';' */ *ret_value = val; return (p - buf) + 1; default: return -1; /* Character set error */ } } /* Do not return value. It's an error we're talking about here. */ return (p - buf);}/* * Convert from the plain UTF-8 format, expanding entity references: "2 < 3" */static ssize_t OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) { OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; const char *p = (const char *)chunk_buf; const char *pend = p + chunk_size; uint8_t *buf; /* Reallocate buffer */ ssize_t _ns = st->size + chunk_size; void *nptr = REALLOC(st->buf, _ns + 1); if(!nptr) return -1; st->buf = (uint8_t *)nptr; buf = st->buf + st->size; /* * Convert series of 0 and 1 into the octet string. */ for(; p < pend; p++) { int ch = *(const unsigned char *)p; int len; /* Length of the rest of the chunk */ if(ch != 0x26 /* '&' */) { *buf++ = ch; continue; /* That was easy... */ } /* * Process entity reference. */ len = chunk_size - (p - (const char *)chunk_buf); if(len == 1 /* "&" */) goto want_more; if(p[1] == 0x23 /* '#' */) { const char *pval; /* Pointer to start of digits */ int32_t val; /* Entity reference value */ int base; if(len == 2 /* "&#" */) goto want_more; if(p[2] == 0x78 /* 'x' */) pval = p + 3, base = 16; else pval = p + 2, base = 10; len = OS__strtoent(base, pval, p + len, &val); if(len == -1) { /* Invalid charset. Just copy verbatim. */ *buf++ = ch; continue; } if(!len || pval[len-1] != 0x3b) goto want_more; assert(val > 0); p += (pval - p) + len - 1; /* Advance past entref */ if(val < 0x80) { *buf++ = (char)val; } else if(val < 0x800) { *buf++ = 0xc0 | ((val >> 6)); *buf++ = 0x80 | ((val & 0x3f)); } else if(val < 0x10000) { *buf++ = 0xe0 | ((val >> 12)); *buf++ = 0x80 | ((val >> 6) & 0x3f); *buf++ = 0x80 | ((val & 0x3f)); } else if(val < 0x200000) { *buf++ = 0xf0 | ((val >> 18)); *buf++ = 0x80 | ((val >> 12) & 0x3f); *buf++ = 0x80 | ((val >> 6) & 0x3f); *buf++ = 0x80 | ((val & 0x3f)); } else if(val < 0x4000000) { *buf++ = 0xf8 | ((val >> 24)); *buf++ = 0x80 | ((val >> 18) & 0x3f); *buf++ = 0x80 | ((val >> 12) & 0x3f); *buf++ = 0x80 | ((val >> 6) & 0x3f); *buf++ = 0x80 | ((val & 0x3f)); } else { *buf++ = 0xfc | ((val >> 30) & 0x1); *buf++ = 0x80 | ((val >> 24) & 0x3f); *buf++ = 0x80 | ((val >> 18) & 0x3f); *buf++ = 0x80 | ((val >> 12) & 0x3f); *buf++ = 0x80 | ((val >> 6) & 0x3f); *buf++ = 0x80 | ((val & 0x3f)); } } else { /* * Ugly, limited parsing of & > < */ char *sc = (char *)memchr(p, 0x3b, len > 5 ? 5 : len); if(!sc) goto want_more; if((sc - p) == 4 && p[1] == 0x61 /* 'a' */ && p[2] == 0x6d /* 'm' */ && p[3] == 0x70 /* 'p' */) { *buf++ = 0x26; p = sc; continue; } if((sc - p) == 3) { if(p[1] == 0x6c) { *buf = 0x3c; /* '<' */ } else if(p[1] == 0x67) { *buf = 0x3e; /* '>' */ } else { /* Unsupported entity reference */ *buf++ = ch; continue; } if(p[2] != 0x74) { /* Unsupported entity reference */ *buf++ = ch; continue; } buf++; p = sc; continue; } /* Unsupported entity reference */ *buf++ = ch; } continue; want_more: if(have_more) { /* * We know that no more data (of the same type) * is coming. Copy the rest verbatim. */ *buf++ = ch; continue; } chunk_size = (p - (const char *)chunk_buf); /* Processing stalled: need more data */ break; } st->size = buf - st->buf; assert(st->size <= _ns); st->buf[st->size] = 0; /* Courtesy termination */ return chunk_size; /* Converted in full */}/* * Decode OCTET STRING from the XML element's body. */static asn_dec_rval_tOCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, void *buf_ptr, size_t size, int (*opt_unexpected_tag_decoder) (void *struct_ptr, const void *chunk_buf, size_t chunk_size), ssize_t (*body_receiver) (void *struct_ptr, const void *chunk_buf, size_t chunk_size, int have_more)) { OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr; asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; asn_struct_ctx_t *ctx; /* Per-structure parser context */ asn_dec_rval_t rval; /* Return value from the decoder */ int st_allocated; /* * Create the string if does not exist. */ if(!st) { st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size); *sptr = (void *)st; if(!st) goto sta_failed; st_allocated = 1; } else { st_allocated = 0; } if(!st->buf) { /* This is separate from above section */ st->buf = (uint8_t *)CALLOC(1, 1); if(!st->buf) { if(st_allocated) { *sptr = 0; goto stb_failed; } else { goto sta_failed; } } } /* Restore parsing context */ ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset); return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag, buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);stb_failed: FREEMEM(st);sta_failed: rval.code = RC_FAIL; rval.consumed = 0; return rval;}/* * Decode OCTET STRING from the hexadecimal data. */asn_dec_rval_tOCTET_STRING_decode_xer_hex(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, void *buf_ptr, size_t size) { return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, buf_ptr, size, 0, OCTET_STRING__convert_hexadecimal);}/* * Decode OCTET STRING from the binary (0/1) data. */asn_dec_rval_tOCTET_STRING_decode_xer_binary(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, void *buf_ptr, size_t size) { return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, buf_ptr, size, 0, OCTET_STRING__convert_binary);}/* * Decode OCTET STRING from the string (ASCII/UTF-8) data. */asn_dec_rval_tOCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, void *buf_ptr, size_t size) { return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname, buf_ptr, size, OCTET_STRING__handle_control_chars, OCTET_STRING__convert_entrefs);}intOCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { static const char *h2c = "0123456789ABCDEF"; const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; char scratch[16 * 3 + 4]; char *p = scratch; uint8_t *buf; uint8_t *end; size_t i; (void)td; /* Unused argument */ if(!st || !st->buf) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0; /* * Dump the contents of the buffer in hexadecimal. */ buf = st->buf; end = buf + st->size; for(i = 0; buf < end; buf++, i++) { if(!(i % 16) && (i || st->size > 16)) { if(cb(scratch, p - scratch, app_key) < 0) return -1; _i_INDENT(1); p = scratch; } *p++ = h2c[(*buf >> 4) & 0x0F]; *p++ = h2c[*buf & 0x0F]; *p++ = 0x20; } if(p > scratch) { p--; /* Remove the tail space */ if(cb(scratch, p - scratch, app_key) < 0) return -1; } return 0;}intOCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; (void)td; /* Unused argument */ (void)ilevel; /* Unused argument */ if(st && st->buf) { return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0; } else { return (cb("<absent>", 8, app_key) < 0) ? -1 : 0; }}voidOCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; asn_struct_ctx_t *ctx = (asn_struct_ctx_t *) ((char *)st + specs->ctx_offset); struct _stack *stck; if(!td || !st) return; ASN_DEBUG("Freeing %s as OCTET STRING", td->name); if(st->buf) { FREEMEM(st->buf); } /* * Remove decode-time stack. */ stck = (struct _stack *)ctx->ptr; if(stck) { while(stck->tail) { struct _stack_el *sel = stck->tail; stck->tail = sel->prev; FREEMEM(sel); } FREEMEM(stck); } if(!contents_only) { FREEMEM(st); }}/* * Conversion routines. */intOCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) { void *buf; if(st == 0 || (str == 0 && len)) { errno = EINVAL; return -1; } /* * Clear the OCTET STRING. */ if(str == NULL) { if(st->buf) FREEMEM(st->buf); st->size = 0; return 0; } /* Determine the original string size, if not explicitly given */ if(len < 0) len = strlen(str); /* Allocate and fill the memory */ buf = MALLOC(len + 1); if(buf == NULL) { return -1; } else { st->buf = (uint8_t *)buf; st->size = len; } memcpy(buf, str, len); st->buf[st->size] = '\0'; /* Couldn't use memcpy(len+1)! */ return 0;}OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) { asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; OCTET_STRING_t *st; st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size); if(st && str && OCTET_STRING_fromBuf(st, str, len)) { free(st); st = NULL; } return st;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -