make h_cast a family of macros, add H_ASSERT family, make h_assert_type a macro

This commit is contained in:
Sven M. Hallberg 2013-01-25 21:52:11 +01:00
parent 18fbf6fd69
commit 7149260a13
4 changed files with 40 additions and 63 deletions

View file

@ -52,7 +52,7 @@ bool validate_message(HParseResult *p) {
void set_rdata(struct dns_rr rr, HCountedArray *rdata) {
uint8_t *data = h_arena_malloc(rdata->arena, sizeof(uint8_t)*rdata->used);
for (size_t i=0; i<rdata->used; ++i)
data[i] = h_cast_uint(rdata->elements[i]);
data[i] = H_CAST_UINT(rdata->elements[i]);
// Parse RDATA if possible.
const HParseResult *p = NULL;
@ -66,7 +66,7 @@ void set_rdata(struct dns_rr rr, HCountedArray *rdata) {
// Pack the parsed rdata into rr.
switch(rr.type) {
case 1: rr.a = h_cast_uint(p->ast); break;
case 1: rr.a = H_CAST_UINT(p->ast); break;
case 2: rr.ns = *H_CAST(dns_domain_t, p->ast); break;
case 3: rr.md = *H_CAST(dns_domain_t, p->ast); break;
case 4: rr.md = *H_CAST(dns_domain_t, p->ast); break;
@ -89,18 +89,18 @@ void set_rdata(struct dns_rr rr, HCountedArray *rdata) {
const HParsedToken* act_header(const HParseResult *p) {
HParsedToken **fields = h_seq_elements(p->ast);
dns_header_t header_ = {
.id = h_cast_uint(fields[0]),
.qr = h_cast_uint(fields[1]),
.opcode = h_cast_uint(fields[2]),
.aa = h_cast_uint(fields[3]),
.tc = h_cast_uint(fields[4]),
.rd = h_cast_uint(fields[5]),
.ra = h_cast_uint(fields[6]),
.rcode = h_cast_uint(fields[7]),
.question_count = h_cast_uint(fields[8]),
.answer_count = h_cast_uint(fields[9]),
.authority_count = h_cast_uint(fields[10]),
.additional_count = h_cast_uint(fields[11])
.id = H_CAST_UINT(fields[0]),
.qr = H_CAST_UINT(fields[1]),
.opcode = H_CAST_UINT(fields[2]),
.aa = H_CAST_UINT(fields[3]),
.tc = H_CAST_UINT(fields[4]),
.rd = H_CAST_UINT(fields[5]),
.ra = H_CAST_UINT(fields[6]),
.rcode = H_CAST_UINT(fields[7]),
.question_count = H_CAST_UINT(fields[8]),
.answer_count = H_CAST_UINT(fields[9]),
.authority_count = H_CAST_UINT(fields[10]),
.additional_count = H_CAST_UINT(fields[11])
};
dns_header_t *header = H_ALLOC(dns_header_t);
@ -147,8 +147,8 @@ const HParsedToken* act_question(const HParseResult *p) {
q->qname.labels[i] = *H_INDEX(dns_label_t, fields[0], i);
}
q->qtype = h_cast_uint(fields[1]);
q->qclass = h_cast_uint(fields[2]);
q->qtype = H_CAST_UINT(fields[1]);
q->qclass = H_CAST_UINT(fields[2]);
return H_MAKE(dns_question_t, q);
}

View file

@ -77,36 +77,6 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val)
return ret;
}
void * h_cast(HTokenType type, const HParsedToken *p)
{
assert(p->token_type == type);
return p->user;
}
HCountedArray *h_cast_seq(const HParsedToken *p)
{
assert(p->token_type == TT_SEQUENCE);
return p->seq;
}
HBytes h_cast_bytes(const HParsedToken *p)
{
assert(p->token_type == TT_BYTES);
return p->bytes;
}
int64_t h_cast_sint(const HParsedToken *p)
{
assert(p->token_type == TT_SINT);
return p->sint;
}
uint64_t h_cast_uint(const HParsedToken *p)
{
assert(p->token_type == TT_UINT);
return p->uint;
}
// XXX -> internal
HParsedToken *h_carray_index(const HCountedArray *a, size_t i)
{

View file

@ -61,16 +61,24 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val);
#define H_MAKE_SINT(VAL) h_make_sint(p->arena, VAL)
#define H_MAKE_UINT(VAL) h_make_uint(p->arena, VAL)
// Extract type-specific value back from HParsedTokens...
// Extract (cast) type-specific value back from HParsedTokens...
void * h_cast (HTokenType type, const HParsedToken *p);
HCountedArray *h_cast_seq (const HParsedToken *p);
HBytes h_cast_bytes(const HParsedToken *p);
int64_t h_cast_sint (const HParsedToken *p);
uint64_t h_cast_uint (const HParsedToken *p);
// Pass-through assertion that a given token has the expected type.
#define h_assert_type(T,P) (assert(P->token_type == (HTokenType)T), P)
// Standard short-hand to cast to a user type.
#define H_CAST(TYP, TOK) ((TYP *) h_cast(TT_ ## TYP, TOK))
// Convenience short-hand forms of h_assert_type.
#define H_ASSERT(TYP, TOK) h_assert_type(TT_ ## TYP, TOK)
#define H_ASSERT_SEQ(TOK) h_assert_type(TT_SEQUENCE, TOK)
#define H_ASSERT_BYTES(TOK) h_assert_type(TT_BYTES, TOK)
#define H_ASSERT_SINT(TOK) h_assert_type(TT_SINT, TOK)
#define H_ASSERT_UINT(TOK) h_assert_type(TT_UINT, TOK)
// Assert expected type and return contained value.
#define H_CAST(TYP, TOK) ((TYP *) H_ASSERT(TYP, TOK)->user)
#define H_CAST_SEQ(TOK) (H_ASSERT_SEQ(TOK)->seq)
#define H_CAST_BYTES(TOK) (H_ASSERT_BYTES(TOK)->bytes)
#define H_CAST_SINT(TOK) (H_ASSERT_SINT(TOK)->sint)
#define H_CAST_UINT(TOK) (H_ASSERT_UINT(TOK)->uint)
// Sequence access...
@ -88,12 +96,11 @@ HParsedToken *h_seq_index_path(const HParsedToken *p, size_t i, ...);
HParsedToken *h_seq_index_vpath(const HParsedToken *p, size_t i, va_list va);
// Convenience macros combining (nested) index access and h_cast.
#define H_INDEX(TYP, SEQ, ...) \
((TYP *) h_cast(TT_ ## TYP, H_INDEX_TOKEN(SEQ, __VA_ARGS__)))
#define H_INDEX_SEQ(SEQ, ...) h_cast_seq(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_BYTES(SEQ, ...) h_cast_bytes(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_SINT(SEQ, ...) h_cast_sint(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_UINT(SEQ, ...) h_cast_uint(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX(TYP, SEQ, ...) H_CAST(TYP, H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_SEQ(SEQ, ...) H_CAST_SEQ(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_BYTES(SEQ, ...) H_CAST_BYTES(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_SINT(SEQ, ...) H_CAST_SINT(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_UINT(SEQ, ...) H_CAST_UINT(H_INDEX_TOKEN(SEQ, __VA_ARGS__))
#define H_INDEX_TOKEN(SEQ, ...) h_seq_index_path(SEQ, __VA_ARGS__, -1)
// Standard short-hand to access and cast elements on a sequence token.

View file

@ -31,7 +31,7 @@ const HParsedToken *act_null(const HParseResult *p) {
const HParsedToken *act_txt(const HParseResult *p) {
dns_rr_txt_t *txt = H_ALLOC(dns_rr_txt_t);
const HCountedArray *arr = h_cast_seq(p->ast);
const HCountedArray *arr = H_CAST_SEQ(p->ast);
uint8_t **ret = h_arena_malloc(arr->arena, sizeof(uint8_t*)*arr->used);
for (size_t i=0; i<arr->used; ++i) {
size_t len = h_seq_len(arr->elements[i]);
@ -50,10 +50,10 @@ const HParsedToken *act_txt(const HParseResult *p) {
const HParsedToken* act_cstr(const HParseResult *p) {
dns_cstr_t *cs = H_ALLOC(dns_cstr_t);
const HCountedArray *arr = h_cast_seq(p->ast);
const HCountedArray *arr = H_CAST_SEQ(p->ast);
uint8_t *ret = h_arena_malloc(arr->arena, sizeof(uint8_t)*arr->used);
for (size_t i=0; i<arr->used; ++i)
ret[i] = h_cast_uint(arr->elements[i]);
ret[i] = H_CAST_UINT(arr->elements[i]);
assert(ret[arr->used-1] == '\0'); // XXX Is this right?! If so, shouldn't it be a validation?
*cs = ret;