From bed864a75d2315c344a6e625db66ae9bfbc51e27 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 2 Oct 2010 22:40:35 -0400 Subject: [PATCH] API cleanups, offset by bit. Signed-off-by: Mathieu Desnoyers --- formats/ctf/types/bitfield.c | 69 +++++++++++++++---------- formats/ctf/types/enum.c | 25 +++------ formats/ctf/types/float.c | 2 + formats/ctf/types/integer.c | 93 ++++++++++++++++++++++------------ formats/ctf/types/string.c | 14 +++-- include/babeltrace/ctf/types.h | 67 +++++++++++++----------- include/babeltrace/format.h | 66 ++++++++++++------------ include/babeltrace/types.h | 73 ++++++++++++++++++++++++-- types/bitfield.c | 45 +++------------- types/float.c | 48 ++++++++++++------ types/integer.c | 16 ++---- types/string.c | 69 +++++++++++++++++++++++++ 12 files changed, 374 insertions(+), 213 deletions(-) create mode 100644 types/string.c diff --git a/formats/ctf/types/bitfield.c b/formats/ctf/types/bitfield.c index 38c8b884..2d7a2ae0 100644 --- a/formats/ctf/types/bitfield.c +++ b/formats/ctf/types/bitfield.c @@ -23,56 +23,69 @@ #include #include -uint64_t ctf_bitfield_unsigned_read(const unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order) +uint64_t ctf_bitfield_unsigned_read(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class) { uint64_t v; - if (byte_order == LITTLE_ENDIAN) - ctf_bitfield_read_le(ptr, start, len, &v); + align_pos(pos, bitfield_class->p.p.alignment); + if (bitfield_class->p.byte_order == LITTLE_ENDIAN) + ctf_bitfield_read_le(pos->base, pos->offset, + bitfield_class->p.len, &v); else - ctf_bitfield_read_be(ptr, start, len, &v); + ctf_bitfield_read_be(pos->base, pos->offset, + bitfield_class->p.len, &v); + move_pos(pos, bitfield_class->p.len); return v; } -int64_t ctf_bitfield_signed_read(const unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order) +int64_t ctf_bitfield_signed_read(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class) { int64_t v; - if (byte_order == LITTLE_ENDIAN) - ctf_bitfield_read_le(ptr, start, len, &v); + align_pos(pos, bitfield_class->p.p.alignment); + + if (bitfield_class->p.byte_order == LITTLE_ENDIAN) + ctf_bitfield_read_le(pos->base, pos->offset, + bitfield_class->p.len, &v); else - ctf_bitfield_read_be(ptr, start, len, &v); + ctf_bitfield_read_be(pos->base, pos->offset, + bitfield_class->p.len, &v); + move_pos(pos, bitfield_class->p.len); return v; } -size_t ctf_bitfield_unsigned_write(unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order, uint64_t v) +void ctf_bitfield_unsigned_write(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class, + uint64_t v) { - if (!ptr) + align_pos(pos, bitfield_class->p.p.alignment); + if (pos->dummy) goto end; - if (byte_order == LITTLE_ENDIAN) - ctf_bitfield_write_le(ptr, start, len, v); + if (bitfield_class->p.byte_order == LITTLE_ENDIAN) + ctf_bitfield_write_le(pos->base, pos->offset, + bitfield_class->p.len, v); else - ctf_bitfield_write_be(ptr, start, len, v); + ctf_bitfield_write_be(pos->base, pos->offset, + bitfield_class->p.len,, v); end: - return len; + move_pos(pos, bitfield_class->p.len); } -size_t ctf_bitfield_signed_write(unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order, int64_t v) +void ctf_bitfield_signed_write(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class, + int64_t v) { - if (!ptr) + align_pos(pos, bitfield_class->p.p.alignment); + if (pos->dummy) goto end; - if (byte_order == LITTLE_ENDIAN) - ctf_bitfield_write_le(ptr, start, len, v); + if (bitfield_class->p.byte_order == LITTLE_ENDIAN) + ctf_bitfield_write_le(pos->base, pos->offset, + bitfield_class->p.len, v); else - ctf_bitfield_write_be(ptr, start, len, v); + ctf_bitfield_write_be(pos->base, pos->offset, + bitfield_class->p.len, v); end: - return len; + move_pos(pos, bitfield_class->p.len); } diff --git a/formats/ctf/types/enum.c b/formats/ctf/types/enum.c index 256807a7..a209b47d 100644 --- a/formats/ctf/types/enum.c +++ b/formats/ctf/types/enum.c @@ -24,7 +24,7 @@ #include #include -GQuark ctf_enum_read(const unsigned char *ptr, +GQuark ctf_enum_read(struct stream_pos *pos, const struct type_class_enum *src) { struct type_class_bitfield *bitfield_class = &src->p; @@ -33,23 +33,18 @@ GQuark ctf_enum_read(const unsigned char *ptr, if (!int_class->signedness) { uint64_t v; - v = ctf_bitfield_unsigned_read(src, - bitfield_class->start_offset, - int_class->len, - int_class->byte_order); + v = ctf_bitfield_unsigned_read(pos, bitfield_class); return enum_uint_to_quark(src, v); } else { int64_t v; - v = fsrc->bitfield_signed_read(src, - bitfield_class->start_offset, - int_class->len, - int_class->byte_order); + v = fsrc->bitfield_signed_read(pos, bitfield_class); return enum_int_to_quark(src, v); } } -size_t ctf_enum_write(unsigned char *ptr, const struct type_class_enum *dest, +size_t ctf_enum_write(struct stream_pos *pos, + const struct type_class_enum *dest, GQuark q) { struct type_class_bitfield *bitfield_class = &dest->p; @@ -59,17 +54,11 @@ size_t ctf_enum_write(unsigned char *ptr, const struct type_class_enum *dest, uint64_t v; v = enum_quark_to_uint(dest, q); - return ctf_bitfield_unsigned_write(src, - bitfield_class->start_offset, - int_class->len, - int_class->byte_order, v); + return ctf_bitfield_unsigned_write(pos, bitfield_class, v); } else { int64_t v; v = enum_quark_to_int(dest, q); - return ctf_bitfield_signed_write(src, - bitfield_class->start_offset, - int_class->len, - int_class->byte_order, v); + return ctf_bitfield_signed_write(pos, bitfield_class, v); } } diff --git a/formats/ctf/types/float.c b/formats/ctf/types/float.c index db753dfb..09a20e3a 100644 --- a/formats/ctf/types/float.c +++ b/formats/ctf/types/float.c @@ -72,6 +72,8 @@ struct pos_len { size_t sign_start, exp_start, mantissa_start, len; }; +/* TODO */ + void ctf_float_copy(unsigned char *destp, const struct type_class_float *dest, const unsigned char *src, const struct type_class_float *src) { diff --git a/formats/ctf/types/integer.c b/formats/ctf/types/integer.c index 316a0888..b2c429f5 100644 --- a/formats/ctf/types/integer.c +++ b/formats/ctf/types/integer.c @@ -25,37 +25,44 @@ #include #include -uint64_t ctf_uint_read(const uint8_t *ptr, size_t len, int byte_order) +uint64_t ctf_uint_read(struct stream_pos *pos, + const struct type_class_integer *int_class) { - int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ + int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ - switch (len) { + align_pos(pos, int_class->p.alignment); + assert(!(pos->offset % CHAR_BIT)); + switch (int_class->len) { case 8: { uint8_t v; - v = *(const uint8_t *)ptr; + v = *(const uint8_t *)pos->base; + move_pos(pos, int_class->len); return v; } case 16: { uint16_t v; - v = *(const uint16_t *)ptr; + v = *(const uint16_t *)pos->base; + move_pos(pos, int_class->len); return rbo ? GUINT16_SWAP_LE_BE(v) : v; } case 32: { uint32_t v; - v = *(const uint32_t *)ptr; + v = *(const uint32_t *)pos->base; + move_pos(pos, int_class->len); return rbo ? GUINT32_SWAP_LE_BE(v) : v; } case 64: { uint64_t v; - v = *(const uint64_t *)ptr; + v = *(const uint64_t *)pos->base; + move_pos(pos, int_class->len); return rbo ? GUINT64_SWAP_LE_BE(v) : v; } default: @@ -63,37 +70,44 @@ uint64_t ctf_uint_read(const uint8_t *ptr, size_t len, int byte_order) } } -int64_t ctf_int_read(const uint8_t *ptr, size_t len, int byte_order) +int64_t ctf_int_read(struct stream_pos *pos, + const struct type_class_integer *int_class) { - int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ + int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ - switch (len) { + align_pos(pos, int_class->p.alignment); + assert(!(pos->offset % CHAR_BIT)); + switch (int_class->len) { case 8: { int8_t v; - v = *(const int8_t *)ptr; + v = *(const int8_t *)pos->base; + move_pos(pos, int_class->len); return v; } case 16: { int16_t v; - v = *(const int16_t *)ptr; + v = *(const int16_t *)pos->base; + move_pos(pos, int_class->len); return rbo ? GUINT16_SWAP_LE_BE(v) : v; } case 32: { int32_t v; - v = *(const int32_t *)ptr; + v = *(const int32_t *)pos->base; + move_pos(pos, int_class->len); return rbo ? GUINT32_SWAP_LE_BE(v) : v; } case 64: { int64_t v; - v = *(const int64_t *)ptr; + v = *(const int64_t *)pos->base; + move_pos(pos, int_class->len); return rbo ? GUINT64_SWAP_LE_BE(v) : v; } default: @@ -101,58 +115,73 @@ int64_t ctf_int_read(const uint8_t *ptr, size_t len, int byte_order) } } -size_t ctf_uint_write(uint8_t *ptr, size_t len, int byte_order, uint64_t v) +void ctf_uint_write(struct stream_pos *pos, + const struct type_class_integer *int_class, + uint64_t v) { - int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ + int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ - if (!ptr) + align_pos(pos, int_class->p.alignment); + assert(!(pos->offset % CHAR_BIT)); + if (pos->dummy) goto end; - switch (len) { - case 8: *(uint8_t *)ptr = (uint8_t) v; + switch (int_class->len) { + case 8: *(uint8_t *) get_pos_addr(pos) = (uint8_t) v; break; case 16: - *(uint16_t *)ptr = rbo ? GUINT16_SWAP_LE_BE((uint16_t) v) : + *(uint16_t *) get_pos_addr(pos) = rbo ? + GUINT16_SWAP_LE_BE((uint16_t) v) : (uint16_t) v; break; case 32: - *(uint32_t *)ptr = rbo ? GUINT32_SWAP_LE_BE((uint32_t) v) : + *(uint32_t *) get_pos_addr(pos) = rbo ? + GUINT32_SWAP_LE_BE((uint32_t) v) : (uint32_t) v; break; case 64: - *(uint64_t *)ptr = rbo ? GUINT64_SWAP_LE_BE(v) : v; + *(uint64_t *) get_pos_addr(pos) = rbo ? + GUINT64_SWAP_LE_BE(v) : v; break; default: assert(0); } end: - return len; + move_pos(pos, int_class->len); } -size_t ctf_int_write(uint8_t *ptr, size_t len, int byte_order, int64_t v) +void ctf_int_write(struct stream_pos *pos, + const struct type_class_integer *int_class, + int64_t v) { - int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */ + int rbo = (int_class->byte_order != BYTE_ORDER); /* reverse byte order */ - if (!ptr) + align_pos(pos, int_class->p.alignment); + assert(!(pos->offset % CHAR_BIT)); + if (pos->dummy) goto end; - switch (len) { - case 8: *(int8_t *)ptr = (int8_t) v; + switch (int_class->len) { + case 8: *(int8_t *) get_pos_addr(pos) = (int8_t) v; break; case 16: - *(int16_t *)ptr = rbo ? GUINT16_SWAP_LE_BE((int16_t) v) : + *(int16_t *) get_pos_addr(pos) = rbo ? + GUINT16_SWAP_LE_BE((int16_t) v) : (int16_t) v; break; case 32: - *(int32_t *)ptr = rbo ? GUINT32_SWAP_LE_BE((int32_t) v) : + *(int32_t *) get_pos_addr(pos) = rbo ? + GUINT32_SWAP_LE_BE((int32_t) v) : (int32_t) v; break; case 64: - *(int64_t *)ptr = rbo ? GUINT64_SWAP_LE_BE(v) : v; + *(int64_t *) get_pos_addr(pos) = rbo ? + GUINT64_SWAP_LE_BE(v) : v; break; default: assert(0); } end: - return len; + move_pos(pos, int_class->len); + return; } diff --git a/formats/ctf/types/string.c b/formats/ctf/types/string.c index 9cfd0a09..5cd09d95 100644 --- a/formats/ctf/types/string.c +++ b/formats/ctf/types/string.c @@ -24,13 +24,21 @@ #include /* C99 limits */ #include -size_t string_copy(char *dest, const char *src) +void ctf_string_copy(struct stream_pos *dest, struct stream_pos *src, + const struct type_class_string *string_class) { - size_t len = strlen(src) + 1; + size_t len; + unsigned char *destaddr, *srcaddr; + align_pos(src, string_class->p.alignment); + srcaddr = get_pos_addr(src); + len = strlen(srcaddr) + 1; if (!dest) goto end; + align_pos(dest, string_class->p.alignment); + destaddr = get_pos_addr(dest); strcpy(dest, src); + move_pos(dest, len); end: - return len * CHAR_BIT; + move_pos(src, len); } diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h index 0f0615f4..473bbff9 100644 --- a/include/babeltrace/ctf/types.h +++ b/include/babeltrace/ctf/types.h @@ -35,39 +35,48 @@ * the size is returned. */ -uint64_t ctf_uint_read(const unsigned char *ptr, int byte_order, size_t len); -int64_t ctf_int_read(const unsigned char *ptr, int byte_order, size_t len); -size_t ctf_uint_write(unsigned char *ptr, int byte_order, size_t len, uint64_t v); -size_t ctf_int_write(unsigned char *ptr, int byte_order, size_t len, int64_t v); +uint64_t ctf_uint_read(struct stream_pos *pos, + const struct type_class_integer *int_class); +int64_t ctf_int_read(struct stream_pos *pos, + const struct type_class_integer *int_class); +void ctf_uint_write(struct stream_pos *pos, + const struct type_class_integer *int_class, + uint64_t v); +void ctf_int_write(struct stream_pos *pos, + const struct type_class_integer *int_class, + int64_t v); -uint64_t ctf_bitfield_unsigned_read(const unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order); -int64_t ctf_bitfield_signed_read(const unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order); -size_t ctf_bitfield_unsigned_write(unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order, uint64_t v); -size_t ctf_bitfield_signed_write(unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order, int64_t v); +uint64_t ctf_bitfield_unsigned_read(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class); +int64_t ctf_bitfield_signed_read(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class); +void ctf_bitfield_unsigned_write(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class, + uint64_t v); +void ctf_bitfield_signed_write(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class, + int64_t v); -double ctf_double_read(const unsigned char *ptr, const struct type_class_float *src); -size_t ctf_double_write(unsigned char *ptr, const struct type_class_float *dest, - double v); -long double ctf_ldouble_read(const unsigned char *ptr, +double ctf_double_read(struct stream_pos *pos, + const struct type_class_float *src); +void ctf_double_write(struct stream_pos *pos, + const struct type_class_float *dest, + double v); +long double ctf_ldouble_read(struct stream_pos *pos, const struct type_class_float *src); -size_t ctf_ldouble_write(unsigned char *ptr, const struct type_class_float *dest, - long double v); -void ctf_float_copy(unsigned char *destp, const struct type_class_float *dest, - const unsigned char *srcp, const struct type_class_float *src); +void ctf_ldouble_write(struct stream_pos *pos, + const struct type_class_float *dest, + long double v); +void ctf_float_copy(struct stream_pos *destp, const struct type_class_float *dest, + struct stream_pos *srcp, const struct type_class_float *src); -size_t ctf_string_copy(unsigned char *dest, const unsigned char *src); +void ctf_string_copy(struct stream_pos *dest, struct stream_pos *src, + const struct type_class_string *string_class); -GQuark ctf_enum_read(const unsigned char *ptr, - const struct type_class_enum *src); -size_t ctf_enum_write(unsigned char *ptr, const struct type_class_enum *dest, - GQuark q); +GQuark ctf_enum_read(struct stream_pos *pos, + const struct type_class_enum *src); +void ctf_enum_write(struct stream_pos *pos, + const struct type_class_enum *dest, + GQuark q); #endif /* _BABELTRACE_CTF_TYPES_H */ diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h index ac03dba7..1a847846 100644 --- a/include/babeltrace/format.h +++ b/include/babeltrace/format.h @@ -29,46 +29,46 @@ struct format { GQuark name; - uint64_t (*uint_read)(const uint8_t *ptr, size_t len, int byte_order); - int64_t (*int_read)(const uint8_t *ptr, size_t len, int byte_order); - size_t (*uint_write)(uint8_t *ptr, size_t len, int byte_order, - uint64_t v); - size_t (*int_write)(uint8_t *ptr, size_t len, int byte_order, - int64_t v); + uint64_t (*uint_read)(struct stream_pos *pos, + const struct type_class_integer *int_class); + int64_t (*int_read)(struct stream_pos *pos, + const struct type_class_integer *int_class); + void (*uint_write)(struct stream_pos *pos, + const struct type_class_integer *int_class, + uint64_t v); + void (*int_write)(struct stream_pos *pos, + const struct type_class_integer *int_class, + int64_t v); - uint64_t (*bitfield_unsigned_read)(const unsigned char *ptr, - unsigned long start, - unsigned long len, - int byte_order); - int64_t (*bitfield_signed_read)(const unsigned char *ptr, - unsigned long start, unsigned long len, - int byte_order); - size_t (*bitfield_unsigned_write)(unsigned char *ptr, - unsigned long start, - unsigned long len, - int byte_order, uint64_t v); - size_t (*bitfield_signed_write)(unsigned char *ptr, - unsigned long start, - unsigned long len, - int byte_order, int64_t v); + uint64_t (*bitfield_unsigned_read)(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class); + int64_t (*bitfield_signed_read)(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class); + void (*bitfield_unsigned_write)(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class, + uint64_t v); + void (*bitfield_signed_write)(struct stream_pos *pos, + const struct type_class_bitfield *bitfield_class, + int64_t v); - void (*float_copy)(unsigned char *destp, + void (*float_copy)(struct stream_pos *destp, const struct type_class_float *dest, - const unsigned char *srcp, - const struct type_class_float *src); - double (*double_read)(const unsigned char *ptr, + struct stream_pos *srcp, + const struct type_class_float *src); + double (*double_read)(struct stream_pos *pos, const struct type_class_float *src); - size_t (*double_write)(unsigned char *ptr, - const struct type_class_float *dest, - double v); + void (*double_write)(struct stream_pos *pos, + const struct type_class_float *dest, + double v); - size_t (*string_copy)(unsigned char *dest, const unsigned char *src); + void (*string_copy)(struct stream_pos *dest, struct stream_pos *src, + const struct type_class_string *string_class); - GQuark (*enum_read)(const unsigned char *ptr, + GQuark (*enum_read)(struct stream_pos *pos, const struct type_class_enum *src); - size_t (*enum_write)(unsigned char *ptr, - const struct type_class_enum *dest, - GQuark q); + void (*enum_write)(struct stream_pos *pos, + const struct type_class_enum *dest, + GQuark q); }; diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index 417bb691..86262408 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -24,6 +24,61 @@ */ #include +#include +#include + +/* + * Always update stream_pos with move_pos and init_pos. + */ +struct stream_pos { + unsigned char *base; /* Base address */ + size_t offset; /* Offset from base, in bits */ + int dummy; /* Dummy position, for length calculation */ +}; + +static inline +void init_pos(struct stream_pos *pos, unsigned char *base) +{ + pos->base = base; /* initial base, page-aligned */ + pos->offset = 0; + pos->dummy = false; +} + +/* + * move_pos - move position of a relative bit offset + * + * TODO: allow larger files by updating base too. + */ +static inline +void move_pos(struct stream_pos *pos, size_t offset) +{ + pos->offset = pos->offset + offset; +} + +/* + * align_pos - align position on a bit offset (> 0) + * + * TODO: allow larger files by updating base too. + */ +static inline +void align_pos(struct stream_pos *pos, size_t offset) +{ + pos->offset += offset_align(pos->offset, offset); +} + +static inline +void copy_pos(struct stream_pos *dest, struct stream_pos *src) +{ + memcpy(dest, src, sizeof(struct stream_pos)); +} + +static inline +unsigned char *get_pos_addr(struct stream_pos *pos) +{ + /* Only makes sense to get the address after aligning on CHAR_BIT */ + assert(!(pos->alignment % CHAR_BIT)); + return pos->base + (pos->offset / CHAR_BIT); +} struct type_class { GQuark name; /* type name */ @@ -32,8 +87,8 @@ struct type_class { * Type copy function. Knows how to find the child type_class from the * parent type_class. */ - size_t (*copy)(unsigned char *dest, const struct format *fdest, - const unsigned char *src, const struct format *fsrc, + size_t (*copy)(struct stream_pos *dest, const struct format *fdest, + struct stream_pos *src, const struct format *fsrc, const struct type_class *type_class); void (*free)(struct type_class *type_class); }; @@ -45,15 +100,19 @@ struct type_class_integer { int signedness; }; +/* + * Because we address in bits, bitfields end up being exactly the same as + * integers, except that their read/write functions must be able to deal with + * read/write non aligned on CHAR_BIT. + */ struct type_class_bitfield { struct type_class_integer p; - size_t start_offset; /* offset from base address, in bits */ }; struct type_class_float { struct type_class p; - size_t mantissa_len; - size_t exp_len; + struct bitfield_class *mantissa; + struct bitfield_class *exp; int byte_order; /* TODO: we might want to express more info about NaN, +inf and -inf */ }; @@ -68,6 +127,10 @@ struct type_class_enum { struct enum_table table; }; +struct type_class_string { + struct type_class p; +}; + struct type_class_struct { struct type_class p; /* TODO */ diff --git a/types/bitfield.c b/types/bitfield.c index a7111b1c..69774877 100644 --- a/types/bitfield.c +++ b/types/bitfield.c @@ -22,55 +22,24 @@ #include #include -/* - * Shortcut to integer copy if we copy bit-aligned data with 0 start_offset. - * This skips the bitfield overhead when dealing with enumerations (which use - * the bitfield copy functions). - */ -extern -size_t integer_copy(unsigned char *dest, const struct format *fdest, - const unsigned char *src, const struct format *fsrc, - const struct type_class *type_class); - -size_t bitfield_copy(unsigned char *dest, const struct format *fdest, - const unsigned char *src, const struct format *fsrc, +size_t bitfield_copy(struct stream_pos *dest, const struct format *fdest, + struct stream_pos *src, const struct format *fsrc, const struct type_class *type_class) { struct type_class_bitfield *bitfield_class = container_of(type_class, struct type_class_bitfield, p); struct type_class_integer *int_class = &bitfield_class->p; - if (!(int_class->p.alignment % CHAR_BIT) - && !(int_class->len % CHAR_BIT) - && !(bitfield_class->start_offset % CHAR_BIT)) { - size_t offset = bitfield_class->start_offset / CHAR_BIT; - dest += offset; - src += offset; - return integer_copy(dest, fdest, src, fsrc, type_class); - } - if (!int_class->signedness) { uint64_t v; - v = fsrc->bitfield_unsigned_read(src, - bitfield_class->start_offset, - int_class->len, - int_class->byte_order); - return fdest->bitfield_unsigned_write(dest, - bitfield_class->start_offset, - int_class->len, int_class->byte_order, - v); + v = fsrc->bitfield_unsigned_read(src, bitfield_class); + return fdest->bitfield_unsigned_write(dest, bitfield_class, v); } else { int64_t v; - v = fsrc->bitfield_signed_read(src, - bitfield_class->start_offset, - int_class->len, - int_class->byte_order); - return fdest->bitfield_signed_write(dest, - bitfield_class->start_offset, - int_class->len, int_class->byte_order, - v); + v = fsrc->bitfield_signed_read(src, bitfield_class); + return fdest->bitfield_signed_write(dest, bitfield_class, v); } } @@ -87,7 +56,6 @@ static void _bitfield_type_free(struct type_class *type_class) } struct type_class_bitfield *bitfield_type_new(const char *name, - size_t start_offset, size_t len, int byte_order, int signedness, size_t alignment) @@ -105,7 +73,6 @@ struct type_class_bitfield *bitfield_type_new(const char *name, int_class->len = len; int_class->byte_order = byte_order; int_class->signedness = signedness; - bitfield_class->start_offset = start_offset; if (int_class->p.name) { ret = ctf_register_type(&int_class->p); if (ret) { diff --git a/types/float.c b/types/float.c index e42daa16..2f40d930 100644 --- a/types/float.c +++ b/types/float.c @@ -21,21 +21,20 @@ #include #include -size_t float_copy(unsigned char *dest, const struct format *fdest, - const unsigned char *src, const struct format *fsrc, - const struct type_class *type_class) +void float_copy(struct stream_pos *dest, const struct format *fdest, + struct stream_pos *src, const struct format *fsrc, + const struct type_class *type_class) { struct type_class_float *float_class = container_of(type_class, struct type_class_float, p); if (fsrc->float_copy == fdest->float_copy) { fsrc->float_copy(dest, float_class, src, float_class); - return float_class->mantissa_len + float_class->exp_len; } else { double v; v = fsrc->double_read(src, fsrc); - return fdest->double_write(dest, fdest, v); + fdest->double_write(dest, fdest, v); } } @@ -57,22 +56,41 @@ struct type_class_float *float_type_new(const char *name, size_t alignment) { struct type_class_float *float_class; + struct type_class_bitfield *bitfield_class; + struct type_class_integer *int_class; + struct type_class *type_class; int ret; float_class = g_new(struct type_class_float, 1); - float_class->p.name = g_quark_from_string(name); - float_class->p.alignment = alignment; - float_class->p.copy = float_copy; - float_class->p.free = _float_type_free; - float_class->mantissa_len = mantissa_len; - float_class->exp_len = exp_len; + type_class = &float_class->p; + + type_class->name = g_quark_from_string(name); + type_class->alignment = alignment; + type_class->copy = float_copy; + type_class->free = _float_type_free; float_class->byte_order = byte_order; + + float_class->mantissa = bitfield_type_new(NULL, mantissa_len, + byte_order, false, 1); + if (!float_class->mantissa) + goto error_mantissa; + float_class->exp = bitfield_type_new(NULL, exp_len, + byte_order, true, 1); + if (!float_class->exp) + goto error_exp; + if (float_class->p.name) { ret = ctf_register_type(&float_class->p); - if (ret) { - g_free(float_class); - return NULL; - } + if (ret) + goto error_register; } return float_class; + +error_register: + bitfield_type_free(float_class->exp); +error_exp: + bitfield_type_free(float_class->mantissa); +error_mantissa: + g_free(float_class); + return NULL; } diff --git a/types/integer.c b/types/integer.c index bafb6cb7..7b2a3a97 100644 --- a/types/integer.c +++ b/types/integer.c @@ -30,21 +30,16 @@ size_t integer_copy(unsigned char *dest, const struct format *fdest, struct type_class_integer *int_class = container_of(type_class, struct type_class_integer, p); - if (fsrc->p.alignment) - src = PTR_ALIGN(src, fsrc->p.alignment / CHAR_BIT); - if (fdest->p.alignment) - dest = PTR_ALIGN(dest, fdest->p.alignment / CHAR_BIT); - if (!int_class->signedness) { uint64_t v; - v = fsrc->uint_read(src, int_class->len, int_class->byte_order); - return fdest->uint_write(dest, int_class->len, int_class->byte_order, v); + v = fsrc->uint_read(src, int_class); + return fdest->uint_write(dest, int_class, v); } else { int64_t v; - v = fsrc->int_read(src, int_class->len, int_class->byte_order); - return fdest->int_write(dest, int_class->len, int_class->byte_order, v); + v = fsrc->int_read(src, int_class); + return fdest->int_write(dest, int_class, v); } } @@ -61,7 +56,6 @@ static void _integer_type_free(struct type_class *type_class) } struct type_class_integer *integer_type_new(const char *name, - size_t start_offset, size_t len, int byte_order, int signedness, size_t alignment) @@ -78,7 +72,7 @@ struct type_class_integer *integer_type_new(const char *name, int_class->byte_order = byte_order; int_class->signedness = signedness; if (int_class->p.name) { - ret = ctf_register_type(&int_class.p); + ret = ctf_register_type(&int_class->p); if (ret) { g_free(int_class); return NULL; diff --git a/types/string.c b/types/string.c new file mode 100644 index 00000000..df9bacac --- /dev/null +++ b/types/string.c @@ -0,0 +1,69 @@ +/* + * BabelTrace - String Type Converter + * + * Copyright (c) 2010 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +void string_copy(struct stream_pos *dest, const struct format *fdest, + struct stream_pos *src, const struct format *fsrc, + const struct type_class *type_class) +{ + struct type_class_string *string_class = + container_of(type_class, struct type_class_string, p); + + if (fsrc->string_copy == fdest->string_copy) { + fsrc->string_copy(dest, src, string_class); + } else { + /* TODO */ + } +} + +void string_type_free(struct type_class_string *string_class) +{ + g_free(string_class); +} + +static void _string_type_free(struct type_class *type_class) +{ + struct type_class_string *string_class = + container_of(type_class, struct type_class_string, p); + string_type_free(string_class); +} + +struct type_class_string *string_type_new(const char *name) +{ + struct type_class_string *string_class; + int ret; + + string_class = g_new(struct type_class_string, 1); + string_class->p.name = g_quark_from_string(name); + string_class->p.alignment = CHAR_BIT; + string_class->p.copy = string_copy; + string_class->p.free = _string_type_free; + if (string_class->p.name) { + ret = ctf_register_type(&string_class->p); + if (ret) { + g_free(string_class); + return NULL; + } + } + return string_class; +} -- 2.34.1