static void test_base16_decode(void) { const char expstr[] = "Test \x01\x09\x0a\x0f Hello"; const char *instrs[] = { "546573742001090a0f2048656c6c6f", "546573742001090A0F2048656C6C6F" }; char outstr[sizeof(expstr)]; struct sol_str_slice slice; ssize_t r, i; enum sol_decode_case decode_case; for (i = 0; i < 4; i++) { slice = sol_str_slice_from_str(instrs[i % 2]); if (i == 0) decode_case = SOL_DECODE_LOWERCASE; else if (i == 1) decode_case = SOL_DECODE_UPERCASE; else decode_case = SOL_DECODE_BOTH; memset(outstr, 0xff, sizeof(outstr)); r = sol_util_base16_decode(outstr, sizeof(outstr), slice, decode_case); ASSERT_INT_EQ(r, strlen(expstr)); ASSERT_INT_EQ(outstr[r], (char)0xff); outstr[r] = '\0'; ASSERT_STR_EQ(outstr, expstr); } /* negative test (case swap) */ for (i = 0; i < 2; i++) { slice = sol_str_slice_from_str(instrs[i]); memset(outstr, 0xff, sizeof(outstr)); r = sol_util_base16_decode(outstr, sizeof(outstr), slice, !i ? SOL_DECODE_UPERCASE : SOL_DECODE_LOWERCASE); } /* short sequence (not multiple of 2) */ slice = sol_str_slice_from_str("1"); memset(outstr, 0xff, sizeof(outstr)); r = sol_util_base16_decode(outstr, sizeof(outstr), slice, SOL_DECODE_UPERCASE); ASSERT_INT_EQ(r, -EINVAL); }
SOL_API int sol_buffer_insert_from_base16(struct sol_buffer *buf, size_t pos, const struct sol_str_slice slice, enum sol_decode_case decode_case) { char *p; size_t new_size; ssize_t decoded_size, r; const size_t nul_size = nul_byte_size(buf); int err; SOL_NULL_CHECK(buf, -EINVAL); SOL_INT_CHECK(pos, > buf->used, -EINVAL); if (slice.len == 0) return 0; if (pos == buf->used) return sol_buffer_append_from_base16(buf, slice, decode_case); decoded_size = sol_util_base16_calculate_decoded_len(slice); if (decoded_size < 0) return decoded_size; err = sol_util_size_add(buf->used, decoded_size, &new_size); if (err < 0) return err; if (nul_size) { err = sol_util_size_add(new_size, nul_size, &new_size); if (err < 0) return err; } err = sol_buffer_ensure(buf, new_size); if (err < 0) return err; p = sol_buffer_at(buf, pos); memmove(p + decoded_size, p, buf->used - pos); r = sol_util_base16_decode(p, decoded_size, slice, decode_case); if (r != decoded_size) { memmove(p, p + decoded_size, buf->used - pos); if (nul_size) sol_buffer_ensure_nul_byte(buf); if (r < 0) return r; else return -EINVAL; } buf->used += decoded_size; if (nul_size) return sol_buffer_ensure_nul_byte(buf); return 0; }