From: Mathieu Desnoyers Date: Thu, 30 Sep 2010 01:46:03 +0000 (-0400) Subject: Add ctf type loading, add integer and bitfield "copy" X-Git-Tag: v0.1~233 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=698f0fe44073e0bfdc6c26222c3bdc1a0dc2d423 Add ctf type loading, add integer and bitfield "copy" Signed-off-by: Mathieu Desnoyers --- diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index d128b9ac..de760a83 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -50,3 +50,5 @@ void ctf_init(void) ret = bt_register_format(&ctf_format); assert(!ret); } + +/* TODO: finalize */ diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index f8c3c8aa..ed3e7aca 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -44,11 +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; @@ -66,4 +72,7 @@ struct type_class_struct { /* TODO */ }; +struct type_class *ctf_lookup_type(GQuark qname); +int ctf_register_type(struct type_class *type_class); + #endif /* _BABELTRACE_TYPES_H */ diff --git a/types/bitfield.c b/types/bitfield.c new file mode 100644 index 00000000..dc0e4743 --- /dev/null +++ b/types/bitfield.c @@ -0,0 +1,95 @@ +/* + * BabelTrace - Bitfield 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 + +/* + * 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, + 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)) + 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); + } 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); + } +} + +int bitfield_type_new(const char *name, size_t start_offset, + size_t len, int byte_order, int signedness) +{ + struct type_class_bitfield bitfield_class; + struct type_class_integer *int_class; + int ret; + + /* + * Freed when type is unregistered. + */ + 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->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; +} + +/* TODO: bitfield_type_free */ diff --git a/types/integer.c b/types/integer.c index 9b92ce35..8a540af1 100644 --- a/types/integer.c +++ b/types/integer.c @@ -19,26 +19,54 @@ */ #include +#include #include -size_t copy_integer(unsigned char *dest, const struct format *fdest, +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) { 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->byte_order, int_class->len); - return fdest->uint_write(dest, int_class->byte_order, - int_class->len, 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); } else { int64_t v; - v = fsrc->int_read(src, int_class->byte_order, int_class->len); - return fdest->int_write(dest, int_class->byte_order, - int_class->len, 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); } } + +int integer_type_new(const char *name, size_t alignment, size_t len, + int byte_order, int signedness) +{ + struct type_class_integer int_class; + int ret; + + /* + * Freed when type is unregistered. + */ + int_class = g_new(struct type_class_integer, 1); + int_class->p.name = g_quark_from_string(name); + int_class->p.alignment = alignment; + int_class->p.copy = integer_copy; + 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; +} + +/* TODO: integer_type_free */ diff --git a/types/types.c b/types/types.c index 7aeb74aa..5c890551 100644 --- a/types/types.c +++ b/types/types.c @@ -25,31 +25,26 @@ #include /* - * Type class hash table contains the registered type classes. Type class - * registration is typically performed by a plugin. - * TODO: support plugin unload (unregistration of type classes). + * Type hash table contains the registered types. Type registration is typically + * performed by a type plugin. + * TODO: support plugin unload (unregistration of types). */ -GHashTable *type_classes; +GHashTable *types; -struct type_class *ctf_lookup_type_class(GQuark qname) +struct type_class *ctf_lookup_type(GQuark qname) { return g_hash_table_lookup(type_classes, (gconstpointer) (unsigned long) qname) } -int ctf_register_type_class(const char *name, - void (*read)(), - void (*write)()) +int ctf_register_type(struct type_class *type_class) { - struct type_class tc = g_new(struct type_class, 1); - GQuark qname = g_quark_from_string(name); - - if (ctf_lookup_type_class(qname)) + if (ctf_lookup_type_class(type_class->name)) return -EEXIST; g_hash_table_insert(type_classes, - (gconstpointer) (unsigned long) qname, - tc); + (gconstpointer) (unsigned long) type_class->name, + type_class); return 0; }