/* char_langle_tag • '<' when tags or autolinks are allowed */ static size_t char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size) { enum mkd_autolink altype = MKDA_NOT_AUTOLINK; size_t end = tag_length(data, size, &altype); struct buf work = { data, end, 0, 0, 0 }; int ret = 0; if (end) { if (rndr->make.autolink && altype != MKDA_NOT_AUTOLINK) { work.data = data + 1; work.size = end - 2; ret = rndr->make.autolink(ob, &work, altype, rndr->make.opaque); } else if (rndr->make.raw_html_tag) ret = rndr->make.raw_html_tag(ob, &work, rndr->make.opaque); } if (!ret) return 0; else return end; }
bool tag_read( uint8_t* buf, uint32_t buf_len, bool one_byte_name_is_id, TAG** tag_out, uint8_t** after_tag_out, uint32_t* bytes_read_out ) { bool result = false; uint32_t tag_len = 0; TAG* tag = NULL; uint8_t* p = NULL; uint8_t* pout = NULL; uint8_t type = 0; uint32_t i = 0; uint32_t io_bytes = 0; do { if (!buf || !buf_len || !tag_out) break; if (!tag_length(buf, buf_len, &tag_len)){ LOG_ERROR("Failed to calculate tag size."); break; } tag = (TAG*)mem_alloc(tag_len); if (!tag){ LOG_ERROR("Failed to allocate memory for tag."); break; } p = buf; type = *p++; if (type & TAG_NAME_ID_FLAG){ // Name id is used. type &= ~TAG_NAME_ID_FLAG; tag->name_id = *p++; } else { tag->name_len = *(uint16_t*)p; p += sizeof(uint16_t); if (one_byte_name_is_id && tag->name_len == 1){ tag->name_id = *p++; } else { for (uint32_t i = 0; i < tag->name_len; i++){ tag->name[i] = *(p + i); } p += tag->name_len; } } tag->type = type; tag->data_offset = tag->name_len?(10 + (tag->name_len - 1) * 2):10; pout = (uint8_t*)tag + tag->data_offset; switch (type){ case TAGTYPE_HASH16: memcpy(pout, p, 16); p += 16; break; case TAGTYPE_STRING: // Bytes count in utf-8 encoded string *(uint16_t*)pout = *(uint16_t*)p; str_utf8_to_unicode( (char*)(p + 2), *(uint16_t*)p, (wchar_t*)(pout + 2), *((uint16_t*)pout) * 2, &io_bytes ); p += sizeof(uint16_t) + *(uint16_t*)p; break; case TAGTYPE_UINT32: *(uint32_t*)pout = *(uint32_t*)p; p += sizeof(uint32_t); break; case TAGTYPE_FLOAT32: memcpy(pout, p, sizeof(float)); p += sizeof(float); break; case TAGTYPE_BOOL: *pout = *p; p++; break; case TAGTYPE_BOOLARRAY: // [IMPLEMENT] break; case TAGTYPE_BLOB: *(uint32_t*)pout = *(uint32_t*)p; memcpy(pout + 4, p + 4, *(uint32_t*)p); p += sizeof(uint32_t) + *(uint32_t*)p; break; case TAGTYPE_UINT16: *(uint16_t*)pout = *(uint16_t*)p; p += sizeof(uint16_t); break; case TAGTYPE_UINT8: *pout = *p; p++; break; case TAGTYPE_BSOB: *pout = *p; memcpy(pout + 1, p + 1, *p); p += sizeof(uint8_t) + *p; break; case TAGTYPE_UINT64: *(uint64_t*)pout = *(uint64_t*)p; p += sizeof(uint64_t); break; } *tag_out = tag; if (after_tag_out) *after_tag_out = p; if (bytes_read_out) *bytes_read_out = p - buf; result = true; } while (false); if (!result && tag) tag_destroy(tag); return result; }