From 0a46062b3916eda6f871b5d80c4b97dcb3804d37 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 30 Sep 2010 13:20:18 -0400 Subject: [PATCH] Add float type class to babeltrace types Signed-off-by: Mathieu Desnoyers --- formats/ctf/ctf.c | 2 + include/babeltrace/ctf/types.h | 4 +- include/babeltrace/format.h | 4 ++ include/babeltrace/types.h | 27 ++++++++++--- types/bitfield.c | 28 +++++++++---- types/float.c | 72 ++++++++++++++++++++++++++++++++++ types/integer.c | 27 +++++++++---- 7 files changed, 140 insertions(+), 24 deletions(-) create mode 100644 types/float.c diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index de760a83..0f0d6921 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -34,6 +34,8 @@ static const struct format ctf_format = { .bitfield_signed_read = ctf_bitfield_signed_read, .bitfield_unsigned_write = ctf_bitfield_unsigned_write, .bitfield_signed_write = ctf_bitfield_signed_write, + .double_read = ctf_double_read, + .double_write = ctf_double_write, .float_copy = ctf_float_copy, .string_copy = ctf_string_copy, .enum_uint_to_quark = ctf_enum_uint_to_quark, diff --git a/include/babeltrace/ctf/types.h b/include/babeltrace/ctf/types.h index 894dda24..2d06d6a5 100644 --- a/include/babeltrace/ctf/types.h +++ b/include/babeltrace/ctf/types.h @@ -53,11 +53,11 @@ size_t ctf_bitfield_signed_write(unsigned char *ptr, unsigned long start, unsigned long len, int byte_order, int64_t v); -double ctf_double_read(const unsigned char *ptr, const struct type_class_float *src) +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, - const struct type_class_float *src) + 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, diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h index 4981f122..d31ee831 100644 --- a/include/babeltrace/format.h +++ b/include/babeltrace/format.h @@ -50,6 +50,10 @@ struct format { void (*float_copy)(unsigned char *destp, const struct type_class_float *dest, const unsigned char *srcp, const struct type_class_float *src); + double (*double_read)(const unsigned char *ptr, const struct type_class_float *src); + size_t (*double_write)(unsigned char *ptr, const struct type_class_float *dest, + double v); + size_t (*string_copy)(unsigned char *dest, const unsigned char *src); diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index ed3e7aca..b77ac400 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -44,22 +44,17 @@ struct type_class_integer { int signedness; }; -int integer_type_new(const char *name, size_t len, int byte_order, - int signedness); - struct type_class_bitfield { struct type_class_integer p; size_t start_offset; /* offset from base address, in bits */ }; -int bitfield_type_new(const char *name, size_t start_offset, - size_t len, int byte_order, int signedness); - struct type_class_float { struct type_class p; size_t mantissa_len; size_t exp_len; int byte_order; + /* TODO: we might want to express more info about NaN, +inf and -inf */ }; struct type_class_enum { @@ -75,4 +70,24 @@ struct type_class_struct { struct type_class *ctf_lookup_type(GQuark qname); int ctf_register_type(struct type_class *type_class); +/* Nameless types can be created by passing a NULL name */ + +struct type_class_integer *integer_type_new(const char *name, + size_t start_offset, + size_t len, int byte_order, + int signedness); +void integer_type_free(struct type_class_integer *int_class); + +struct type_class_bitfield *bitfield_type_new(const char *name, + size_t start_offset, + size_t len, int byte_order, + int signedness); +void bitfield_type_free(struct type_class_bitfield *bitfield_class); + +struct type_class_float *float_type_new(const char *name, + size_t mantissa_len, + size_t exp_len, int byte_order, + size_t alignment); +void float_type_free(struct type_class_float *float_class); + #endif /* _BABELTRACE_TYPES_H */ diff --git a/types/bitfield.c b/types/bitfield.c index e9a9f696..b21fdc91 100644 --- a/types/bitfield.c +++ b/types/bitfield.c @@ -73,10 +73,13 @@ size_t bitfield_copy(unsigned char *dest, const struct format *fdest, } } -int bitfield_type_new(const char *name, size_t start_offset, - size_t len, int byte_order, int signedness) +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) { - struct type_class_bitfield bitfield_class; + struct type_class_bitfield *bitfield_class; struct type_class_integer *int_class; int ret; @@ -86,14 +89,23 @@ int bitfield_type_new(const char *name, size_t start_offset, bitfield_class = g_new(struct type_class_bitfield, 1); int_class = &bitfield_class->p; int_class->p.name = g_quark_from_string(name); + int_class->p.alignment = alignment; int_class->len = len; int_class->byte_order = byte_order; int_class->signedness = signedness; bitfield_class->start_offset = start_offset; - ret = ctf_register_type(&int_class->p); - if (ret) - g_free(bitfield_class); - return ret; + if (int_class->p.name) { + ret = ctf_register_type(&int_class->p); + if (ret) { + g_free(bitfield_class); + return NULL; + } + } + return bitfield_class; } -/* TODO: bitfield_type_free */ +void bitfield_type_free(struct type_class_bitfield *bitfield_class) +{ + if (!bitfield_class->name) + g_free(bitfield_class); +} diff --git a/types/float.c b/types/float.c new file mode 100644 index 00000000..ac152559 --- /dev/null +++ b/types/float.c @@ -0,0 +1,72 @@ +/* + * BabelTrace - Float 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 + +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) +{ + 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); + } +} + +struct type_class_float *float_type_new(const char *name, + size_t mantissa_len, + size_t exp_len, int byte_order, + size_t alignment) +{ + struct type_class_float *float_class; + int ret; + + /* + * Freed when type is unregistered. + */ + 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->mantissa_len = mantissa_len; + float_class->exp_len = exp_len; + float_class->byte_order = byte_order; + if (float_class->p.name) { + ret = ctf_register_type(&float_class->p); + if (ret) { + g_free(float_class); + return NULL; + } + } + return float_class; +} + +void float_type_free(struct type_class_float *float_class) +{ + if (!float_class->name) + g_free(float_class); +} diff --git a/types/integer.c b/types/integer.c index 8a540af1..b338a591 100644 --- a/types/integer.c +++ b/types/integer.c @@ -47,10 +47,13 @@ size_t integer_copy(unsigned char *dest, const struct format *fdest, } } -int integer_type_new(const char *name, size_t alignment, size_t len, - int byte_order, int signedness) +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) { - struct type_class_integer int_class; + struct type_class_integer *int_class; int ret; /* @@ -63,10 +66,18 @@ int integer_type_new(const char *name, size_t alignment, size_t len, int_class->len = len; int_class->byte_order = byte_order; int_class->signedness = signedness; - ret = ctf_register_type(&int_class.p); - if (ret) - g_free(int_class); - return ret; + if (int_class->p.name) { + ret = ctf_register_type(&int_class.p); + if (ret) { + g_free(int_class); + return NULL; + } + } + return int_class; } -/* TODO: integer_type_free */ +void integer_type_free(struct type_class_integer *int_class) +{ + if (!int_class->name) + g_free(int_class); +} -- 2.34.1