--- /dev/null
+/*
+ * Common Trace Format - Converter
+ *
+ * Types registry.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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 <ctf/ctf-types.h>
+#include <glib.h>
+#include <errno.h>
+
+struct type_class {
+ GQuark qname;
+ void (*read)();
+ size_t (*write)();
+};
+
+struct type {
+ struct type_class *class;
+ size_t alignment; /* type alignment, in bits */
+ ssize_t len; /* type length, in bits. -1 for dynamic size. */
+};
+
+/*
+ * 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).
+ */
+GHashTable *type_classes;
+
+struct type_class *ctf_lookup_type_class(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)())
+{
+ struct type_class tc = g_new(struct type_class, 1);
+ GQuark qname = g_quark_from_string(name);
+
+ if (ctf_lookup_type_class(qname))
+ return -EEXIST;
+
+ g_hash_table_insert(type_classes,
+ (gconstpointer) (unsigned long) qname,
+ tc);
+ return 0;
+}
+
+int ctf_init_types(void)
+{
+ type_classes = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, g_free);
+ if (!type_classes)
+ return -ENOMEM;
+ return 0;
+}
+
+int ctf_finalize_types(void)
+{
+ g_hash_table_destroy(type_classes);
+}
--- /dev/null
+/*
+ * Common Trace Format
+ *
+ * Enumeration mapping strings (quarks) from/to integers.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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 <ctf/ctf-types.h>
+#include <stdint.h>
+#include <glib.h>
+
+struct enum_table {
+ GHashTable *value_to_quark; /* Tuples (value, GQuark) */
+ GHashTable *quark_to_value; /* Tuples (GQuark, value) */
+};
+
+#if (__WORDSIZE == 32)
+GQuark enum_uint_to_quark(const struct enum_table *table, uint64_t v)
+{
+ gconstpointer q = g_hash_table_lookup(table->value_to_quark, &v);
+ return (GQuark) (unsigned long) q;
+}
+
+GQuark enum_int_to_quark(const struct enum_table *table, uint64_t v)
+{
+ gconstpointer q = g_hash_table_lookup(table->value_to_quark, &v);
+ return (GQuark) (unsigned long) q;
+}
+
+uint64_t enum_quark_to_uint(size_t len, int byte_order, GQuark q)
+{
+ gconstpointer v = g_hash_table_lookup(table->quark_to_value,
+ (gconstpointer) q);
+ return *(const uint64_t *) v;
+}
+
+int64_t enum_quark_to_int(size_t len, int byte_order, GQuark q)
+{
+ gconstpointer v = g_hash_table_lookup(table->quark_to_value,
+ (gconstpointer) q);
+ return *(const int64_t *) v;
+}
+
+guint enum_val_hash(gconstpointer key)
+{
+ int64_t ukey = *(const int64_t *)key;
+
+ return (guint)ukey ^ (guint)(ukey >> 32);
+}
+
+gboolean enum_val_equal(gconstpointer a, gconstpointer b)
+{
+ int64_t ua = *(const int64_t *)a;
+ int64_t ub = *(const int64_t *)b;
+
+ return ua == ub;
+}
+
+void enum_val_free(void *ptr)
+{
+ g_free(ptr);
+}
+
+void enum_signed_insert(struct enum_table *table, int64_t v, GQuark q)
+{
+ int64_t *valuep = g_new(int64_t, 1);
+
+ g_hash_table_insert(table->value_to_quark, valuep,
+ (gpointer) (unsigned long) q);
+ g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
+ valuep);
+}
+
+void enum_unsigned_insert(struct enum_table *table, uint64_t v, GQuark q)
+{
+ uint64_t *valuep = g_new(uint64_t, 1);
+
+ g_hash_table_insert(table->value_to_quark, valuep,
+ (gpointer) (unsigned long) q);
+ g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
+ valuep);
+}
+#else /* __WORDSIZE != 32 */
+GQuark enum_uint_to_quark(const struct enum_table *table, uint64_t v)
+{
+ gconstpointer q = g_hash_table_lookup(table->value_to_quark,
+ (gconstpointer) v);
+ return (GQuark) (unsigned long) q;
+}
+
+GQuark enum_int_to_quark(const struct enum_table *table, uint64_t v)
+{
+ gconstpointer q = g_hash_table_lookup(table->value_to_quark,
+ (gconstpointer) v);
+ return (GQuark) (unsigned long) q;
+}
+
+uint64_t enum_quark_to_uint(size_t len, int byte_order, GQuark q)
+{
+ gconstpointer v = g_hash_table_lookup(table->quark_to_value,
+ (gconstpointer) (unsigned long) q);
+ return *(const uint64_t *) v;
+}
+
+int64_t enum_quark_to_int(size_t len, int byte_order, GQuark q)
+{
+ gconstpointer v = g_hash_table_lookup(table->quark_to_value,
+ (gconstpointer) (unsigned long) q);
+ return *(const int64_t *) v;
+}
+
+guint enum_val_hash(gconstpointer key)
+{
+ return g_direct_hash(key);
+}
+
+gboolean enum_val_equal(gconstpointer a, gconstpointer b)
+{
+ return g_direct_equal(a, b);
+}
+
+void enum_val_free(void *ptr)
+{
+}
+
+void enum_signed_insert(struct enum_table *table, int64_t v, GQuark q)
+{
+ g_hash_table_insert(table->value_to_quark, (gpointer) v,
+ (gpointer) (unsigned long) q);
+ g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
+ valuep);
+}
+
+void enum_unsigned_insert(struct enum_table *table, uint64_t v, GQuark q)
+{
+ g_hash_table_insert(table->value_to_quark, (gpointer) v,
+ (gpointer) (unsigned long) q);
+ g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
+ valuep);
+}
+#endif /* __WORDSIZE != 32 */
+
+struct enum_table *enum_new(void)
+{
+ struct enum_table *table;
+
+ table = g_new(struct enum_table, 1);
+ table->value_to_quark = g_hash_table(enum_val_hash, enum_val_equal);
+ table->quark_to_value = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal,
+ NULL, enum_val_free);
+}
+
+void enum_destroy(struct enum_table *table)
+{
+ g_hash_table_destroy(table->value_to_quark);
+ g_hash_table_destroy(table->quark_to_value);
+ g_free(table);
+}
--- /dev/null
+/*
+ * Common Trace Format
+ *
+ * Floating point read/write functions.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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
+ *
+ * Reference: ISO C99 standard 5.2.4
+ */
+
+#include <ctf/ctf-types.h>
+#include <glib.h>
+#include <float.h> /* C99 floating point definitions */
+#include <endian.h>
+
+/*
+ * This library is limited to binary representation of floating point values.
+ * Sign-extension of the exponents is assumed to keep the NaN, +inf, -inf
+ * values, but this should be double-checked (TODO).
+ */
+
+/*
+ * Aliasing float/double and unsigned long is not strictly permitted by strict
+ * aliasing, but in practice type prunning is well supported, and this permits
+ * us to use per-word read/writes rather than per-byte.
+ */
+
+#if defined(__GNUC__) || defined(__MINGW32__) || defined(_MSC_VER)
+#define HAS_TYPE_PRUNING
+#endif
+
+#if (FLT_RADIX != 2)
+
+#error "Unsupported floating point radix"
+
+#endif
+
+union doubleIEEE754 {
+ double v;
+#ifdef HAS_TYPE_PRUNING
+ unsigned long bits[(sizeof(double) + sizeof(unsigned long) - 1) / sizeof(unsigned long)];
+#else
+ unsigned char bits[sizeof(double)];
+#endif
+};
+
+union ldoubleIEEE754 {
+ long double v;
+#ifdef HAS_TYPE_PRUNING
+ unsigned long bits[(sizeof(long double) + sizeof(unsigned long) - 1) / sizeof(unsigned long)];
+#else
+ unsigned char bits[sizeof(long double)];
+#endif
+};
+
+struct pos_len {
+ size_t sign_start, exp_start, mantissa_start, len;
+};
+
+void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest,
+ const unsigned char *src, const struct ctf_float *src)
+{
+ struct pos_len destpos, srcpos;
+ union {
+ unsigned long long u;
+ long long s;
+ } tmp;
+
+ destpos.len = dest.exp_len + dest.mantissa_len;
+ if (dest.byte_order == LITTLE_ENDIAN) {
+ destpos.sign_start = destpos.len - 1;
+ destpos.exp_start = destpos.sign_start - dest->exp_len;
+ destpos.mantissa_start = 0;
+ } else {
+ destpos.sign_start = 0;
+ destpos.exp_start = 1;
+ destpos.mantissa_start = destpos.exp_start + dest->exp_len;
+ }
+
+ srcpos.len = src.exp_len + src.mantissa_len;
+ if (src.byte_order == LITTLE_ENDIAN) {
+ srcpos.sign_start = srcpos.len - 1;
+ srcpos.exp_start = srcpos.sign_start - src->exp_len;
+ srcpos.mantissa_start = 0;
+ } else {
+ srcpos.sign_start = 0;
+ srcpos.exp_start = 1;
+ srcpos.mantissa_start = srcpos.exp_start + src->exp_len;
+ }
+
+ /* sign */
+ tmp.u = bitfield_unsigned_read(ptr, srcpos.sign_start, 1,
+ src->byte_order);
+ bitfield_unsigned_write(&u.bits, destpos.sign_start, 1,
+ dest->byte_order, tmp.u);
+
+ /* mantissa (without leading 1). No sign extend. */
+ tmp.u = bitfield_unsigned_read(ptr, srcpos.mantissa_start,
+ src->mantissa_len - 1, src->byte_order);
+ bitfield_unsigned_write(&u.bits, destpos.mantissa_start,
+ dest->mantissa_len - 1, dest->byte_order, tmp.u);
+
+ /* exponent, with sign-extend. */
+ tmp.s = bitfield_signed_read(ptr, srcpos.exp_start, src->exp_len,
+ src->byte_order);
+ bitfield_signed_write(&u.bits, destpos.exp_start, dest->exp_len,
+ dest->byte_order, tmp.s);
+}
+
+double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src)
+{
+ union doubleIEEE754 u;
+ struct ctf_float dest = {
+ .exp_len = sizeof(double) * CHAR_BIT - DBL_MANT_DIG,
+ .mantissa_len = DBL_MANT_DIG,
+ .byte_order = BYTE_ORDER,
+ };
+
+ float_copy(&u.bits, &dest, ptr, src);
+ return u.v;
+}
+
+size_t ctf_double_write(unsigned char *ptr, const struct ctf_float *dest,
+ double v)
+{
+ union doubleIEEE754 u;
+ struct ctf_float src = {
+ .exp_len = sizeof(double) * CHAR_BIT - DBL_MANT_DIG,
+ .mantissa_len = DBL_MANT_DIG,
+ .byte_order = BYTE_ORDER,
+ };
+
+ if (!ptr)
+ goto end;
+ u.v = v;
+ float_copy(ptr, dest, &u.bits, &src);
+end:
+ return len;
+}
+
+long double ctf_ldouble_read(const unsigned char *ptr,
+ const struct ctf_float *src)
+{
+ union ldoubleIEEE754 u;
+ struct ctf_float dest = {
+ .exp_len = sizeof(double) * CHAR_BIT - LDBL_MANT_DIG,
+ .mantissa_len = LDBL_MANT_DIG,
+ .byte_order = BYTE_ORDER,
+ };
+
+ float_copy(&u.bits, &dest, ptr, src);
+ return u.v;
+}
+
+size_t ctf_ldouble_write(unsigned char *ptr, const struct ctf_float *dest,
+ long double v)
+{
+ union ldoubleIEEE754 u;
+ struct ctf_float src = {
+ .exp_len = sizeof(double) * CHAR_BIT - LDBL_MANT_DIG,
+ .mantissa_len = LDBL_MANT_DIG,
+ .byte_order = BYTE_ORDER,
+ };
+
+ if (!ptr)
+ goto end;
+ u.v = v;
+ float_copy(ptr, dest, &u.bits, &src);
+end:
+ return len;
+}
--- /dev/null
+/*
+ * Common Trace Format
+ *
+ * Integers read/write functions.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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 <ctf/ctf-types.h>
+#include <stdint.h>
+#include <glib.h>
+#include <endian.h>
+
+uint64_t uint_read(const uint8_t *ptr, size_t len, int byte_order)
+{
+ int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
+
+ switch (len) {
+ case 8:
+ {
+ uint8_t v;
+
+ v = *(const uint8_t *)ptr;
+ return v;
+ }
+ case 16:
+ {
+ uint16_t v;
+
+ v = *(const uint16_t *)ptr;
+ return rbo ? GUINT16_SWAP_LE_BE(v) : v;
+ }
+ case 32:
+ {
+ uint32_t v;
+
+ v = *(const uint32_t *)ptr;
+ return rbo ? GUINT32_SWAP_LE_BE(v) : v;
+ }
+ case 64:
+ {
+ uint64_t v;
+
+ v = *(const uint64_t *)ptr;
+ return rbo ? GUINT64_SWAP_LE_BE(v) : v;
+ }
+ default:
+ assert(0);
+ }
+}
+
+int64_t int_read(const uint8_t *ptr, size_t len, int byte_order)
+{
+ int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
+
+ switch (len) {
+ case 8:
+ {
+ int8_t v;
+
+ v = *(const int8_t *)ptr;
+ return v;
+ }
+ case 16:
+ {
+ int16_t v;
+
+ v = *(const int16_t *)ptr;
+ return rbo ? GUINT16_SWAP_LE_BE(v) : v;
+ }
+ case 32:
+ {
+ int32_t v;
+
+ v = *(const int32_t *)ptr;
+ return rbo ? GUINT32_SWAP_LE_BE(v) : v;
+ }
+ case 64:
+ {
+ int64_t v;
+
+ v = *(const int64_t *)ptr;
+ return rbo ? GUINT64_SWAP_LE_BE(v) : v;
+ }
+ default:
+ assert(0);
+ }
+}
+
+size_t uint_write(uint8_t *ptr, size_t len, int byte_order, uint64_t v)
+{
+ int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
+
+ if (!ptr)
+ goto end;
+
+ switch (len) {
+ case 8: *(uint8_t *)ptr = (uint8_t) v;
+ break;
+ case 16:
+ *(uint16_t *)ptr = 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) v;
+ break;
+ case 64:
+ *(uint64_t *)ptr = rbo ? GUINT64_SWAP_LE_BE(v) : v;
+ break;
+ default:
+ assert(0);
+ }
+end:
+ return len;
+}
+
+size_t int_write(uint8_t *ptr, size_t len, int byte_order, int64_t v)
+{
+ int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
+
+ if (!ptr)
+ goto end;
+
+ switch (len) {
+ case 8: *(int8_t *)ptr = (int8_t) v;
+ break;
+ case 16:
+ *(int16_t *)ptr = 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) v;
+ break;
+ case 64:
+ *(int64_t *)ptr = rbo ? GUINT64_SWAP_LE_BE(v) : v;
+ break;
+ default:
+ assert(0);
+ }
+end:
+ return len;
+}
--- /dev/null
+/*
+ * Common Trace Format
+ *
+ * Strings read/write functions.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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 <ctf/ctf-types.h>
+#include <string.h>
+
+size_t string_copy(char *dest, const char *src)
+{
+ size_t len = strlen(src) + 1;
+
+ if (!dest)
+ goto end;
+ strcpy(dest, src);
+end:
+ return len * 8;
+}
--- /dev/null
+/*
+ * Common Trace Format
+ *
+ * Structure write/access functions.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * 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 <ctf/ctf-types.h>
+#include <glib.h>
+
+
+++ /dev/null
-/*
- * Common Trace Format
- *
- * Enumeration mapping strings (quarks) from/to integers.
- *
- * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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 <ctf/ctf-types.h>
-#include <stdint.h>
-#include <glib.h>
-
-struct enum_table {
- GHashTable *value_to_quark; /* Tuples (value, GQuark) */
- GHashTable *quark_to_value; /* Tuples (GQuark, value) */
-};
-
-#if (__WORDSIZE == 32)
-GQuark enum_uint_to_quark(const struct enum_table *table, uint64_t v)
-{
- gconstpointer q = g_hash_table_lookup(table->value_to_quark, &v);
- return (GQuark) (unsigned long) q;
-}
-
-GQuark enum_int_to_quark(const struct enum_table *table, uint64_t v)
-{
- gconstpointer q = g_hash_table_lookup(table->value_to_quark, &v);
- return (GQuark) (unsigned long) q;
-}
-
-uint64_t enum_quark_to_uint(size_t len, int byte_order, GQuark q)
-{
- gconstpointer v = g_hash_table_lookup(table->quark_to_value,
- (gconstpointer) q);
- return *(const uint64_t *) v;
-}
-
-int64_t enum_quark_to_int(size_t len, int byte_order, GQuark q)
-{
- gconstpointer v = g_hash_table_lookup(table->quark_to_value,
- (gconstpointer) q);
- return *(const int64_t *) v;
-}
-
-guint enum_val_hash(gconstpointer key)
-{
- int64_t ukey = *(const int64_t *)key;
-
- return (guint)ukey ^ (guint)(ukey >> 32);
-}
-
-gboolean enum_val_equal(gconstpointer a, gconstpointer b)
-{
- int64_t ua = *(const int64_t *)a;
- int64_t ub = *(const int64_t *)b;
-
- return ua == ub;
-}
-
-void enum_val_free(void *ptr)
-{
- g_free(ptr);
-}
-
-void enum_signed_insert(struct enum_table *table, int64_t v, GQuark q)
-{
- int64_t *valuep = g_new(int64_t, 1);
-
- g_hash_table_insert(table->value_to_quark, valuep,
- (gpointer) (unsigned long) q);
- g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
- valuep);
-}
-
-void enum_unsigned_insert(struct enum_table *table, uint64_t v, GQuark q)
-{
- uint64_t *valuep = g_new(uint64_t, 1);
-
- g_hash_table_insert(table->value_to_quark, valuep,
- (gpointer) (unsigned long) q);
- g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
- valuep);
-}
-#else /* __WORDSIZE != 32 */
-GQuark enum_uint_to_quark(const struct enum_table *table, uint64_t v)
-{
- gconstpointer q = g_hash_table_lookup(table->value_to_quark,
- (gconstpointer) v);
- return (GQuark) (unsigned long) q;
-}
-
-GQuark enum_int_to_quark(const struct enum_table *table, uint64_t v)
-{
- gconstpointer q = g_hash_table_lookup(table->value_to_quark,
- (gconstpointer) v);
- return (GQuark) (unsigned long) q;
-}
-
-uint64_t enum_quark_to_uint(size_t len, int byte_order, GQuark q)
-{
- gconstpointer v = g_hash_table_lookup(table->quark_to_value,
- (gconstpointer) (unsigned long) q);
- return *(const uint64_t *) v;
-}
-
-int64_t enum_quark_to_int(size_t len, int byte_order, GQuark q)
-{
- gconstpointer v = g_hash_table_lookup(table->quark_to_value,
- (gconstpointer) (unsigned long) q);
- return *(const int64_t *) v;
-}
-
-guint enum_val_hash(gconstpointer key)
-{
- return g_direct_hash(key);
-}
-
-gboolean enum_val_equal(gconstpointer a, gconstpointer b)
-{
- return g_direct_equal(a, b);
-}
-
-void enum_val_free(void *ptr)
-{
-}
-
-void enum_signed_insert(struct enum_table *table, int64_t v, GQuark q)
-{
- g_hash_table_insert(table->value_to_quark, (gpointer) v,
- (gpointer) (unsigned long) q);
- g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
- valuep);
-}
-
-void enum_unsigned_insert(struct enum_table *table, uint64_t v, GQuark q)
-{
- g_hash_table_insert(table->value_to_quark, (gpointer) v,
- (gpointer) (unsigned long) q);
- g_hash_table_insert(table->quark_to_value, (gpointer) (unsigned long) q,
- valuep);
-}
-#endif /* __WORDSIZE != 32 */
-
-struct enum_table *enum_new(void)
-{
- struct enum_table *table;
-
- table = g_new(struct enum_table, 1);
- table->value_to_quark = g_hash_table(enum_val_hash, enum_val_equal);
- table->quark_to_value = g_hash_table_new_full(g_direct_hash,
- g_direct_equal,
- NULL, enum_val_free);
-}
-
-void enum_destroy(struct enum_table *table)
-{
- g_hash_table_destroy(table->value_to_quark);
- g_hash_table_destroy(table->quark_to_value);
- g_free(table);
-}
+++ /dev/null
-/*
- * Common Trace Format
- *
- * Floating point read/write functions.
- *
- * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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
- *
- * Reference: ISO C99 standard 5.2.4
- */
-
-#include <ctf/ctf-types.h>
-#include <glib.h>
-#include <float.h> /* C99 floating point definitions */
-#include <endian.h>
-
-/*
- * This library is limited to binary representation of floating point values.
- * Sign-extension of the exponents is assumed to keep the NaN, +inf, -inf
- * values, but this should be double-checked (TODO).
- */
-
-/*
- * Aliasing float/double and unsigned long is not strictly permitted by strict
- * aliasing, but in practice type prunning is well supported, and this permits
- * us to use per-word read/writes rather than per-byte.
- */
-
-#if defined(__GNUC__) || defined(__MINGW32__) || defined(_MSC_VER)
-#define HAS_TYPE_PRUNING
-#endif
-
-#if (FLT_RADIX != 2)
-
-#error "Unsupported floating point radix"
-
-#endif
-
-union doubleIEEE754 {
- double v;
-#ifdef HAS_TYPE_PRUNING
- unsigned long bits[(sizeof(double) + sizeof(unsigned long) - 1) / sizeof(unsigned long)];
-#else
- unsigned char bits[sizeof(double)];
-#endif
-};
-
-union ldoubleIEEE754 {
- long double v;
-#ifdef HAS_TYPE_PRUNING
- unsigned long bits[(sizeof(long double) + sizeof(unsigned long) - 1) / sizeof(unsigned long)];
-#else
- unsigned char bits[sizeof(long double)];
-#endif
-};
-
-struct pos_len {
- size_t sign_start, exp_start, mantissa_start, len;
-};
-
-void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest,
- const unsigned char *src, const struct ctf_float *src)
-{
- struct pos_len destpos, srcpos;
- union {
- unsigned long long u;
- long long s;
- } tmp;
-
- destpos.len = dest.exp_len + dest.mantissa_len;
- if (dest.byte_order == LITTLE_ENDIAN) {
- destpos.sign_start = destpos.len - 1;
- destpos.exp_start = destpos.sign_start - dest->exp_len;
- destpos.mantissa_start = 0;
- } else {
- destpos.sign_start = 0;
- destpos.exp_start = 1;
- destpos.mantissa_start = destpos.exp_start + dest->exp_len;
- }
-
- srcpos.len = src.exp_len + src.mantissa_len;
- if (src.byte_order == LITTLE_ENDIAN) {
- srcpos.sign_start = srcpos.len - 1;
- srcpos.exp_start = srcpos.sign_start - src->exp_len;
- srcpos.mantissa_start = 0;
- } else {
- srcpos.sign_start = 0;
- srcpos.exp_start = 1;
- srcpos.mantissa_start = srcpos.exp_start + src->exp_len;
- }
-
- /* sign */
- tmp.u = bitfield_unsigned_read(ptr, srcpos.sign_start, 1,
- src->byte_order);
- bitfield_unsigned_write(&u.bits, destpos.sign_start, 1,
- dest->byte_order, tmp.u);
-
- /* mantissa (without leading 1). No sign extend. */
- tmp.u = bitfield_unsigned_read(ptr, srcpos.mantissa_start,
- src->mantissa_len - 1, src->byte_order);
- bitfield_unsigned_write(&u.bits, destpos.mantissa_start,
- dest->mantissa_len - 1, dest->byte_order, tmp.u);
-
- /* exponent, with sign-extend. */
- tmp.s = bitfield_signed_read(ptr, srcpos.exp_start, src->exp_len,
- src->byte_order);
- bitfield_signed_write(&u.bits, destpos.exp_start, dest->exp_len,
- dest->byte_order, tmp.s);
-}
-
-double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src)
-{
- union doubleIEEE754 u;
- struct ctf_float dest = {
- .exp_len = sizeof(double) * CHAR_BIT - DBL_MANT_DIG,
- .mantissa_len = DBL_MANT_DIG,
- .byte_order = BYTE_ORDER,
- };
-
- float_copy(&u.bits, &dest, ptr, src);
- return u.v;
-}
-
-size_t ctf_double_write(unsigned char *ptr, const struct ctf_float *dest,
- double v)
-{
- union doubleIEEE754 u;
- struct ctf_float src = {
- .exp_len = sizeof(double) * CHAR_BIT - DBL_MANT_DIG,
- .mantissa_len = DBL_MANT_DIG,
- .byte_order = BYTE_ORDER,
- };
-
- if (!ptr)
- goto end;
- u.v = v;
- float_copy(ptr, dest, &u.bits, &src);
-end:
- return len;
-}
-
-long double ctf_ldouble_read(const unsigned char *ptr,
- const struct ctf_float *src)
-{
- union ldoubleIEEE754 u;
- struct ctf_float dest = {
- .exp_len = sizeof(double) * CHAR_BIT - LDBL_MANT_DIG,
- .mantissa_len = LDBL_MANT_DIG,
- .byte_order = BYTE_ORDER,
- };
-
- float_copy(&u.bits, &dest, ptr, src);
- return u.v;
-}
-
-size_t ctf_ldouble_write(unsigned char *ptr, const struct ctf_float *dest,
- long double v)
-{
- union ldoubleIEEE754 u;
- struct ctf_float src = {
- .exp_len = sizeof(double) * CHAR_BIT - LDBL_MANT_DIG,
- .mantissa_len = LDBL_MANT_DIG,
- .byte_order = BYTE_ORDER,
- };
-
- if (!ptr)
- goto end;
- u.v = v;
- float_copy(ptr, dest, &u.bits, &src);
-end:
- return len;
-}
+++ /dev/null
-/*
- * Common Trace Format
- *
- * Integers read/write functions.
- *
- * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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 <ctf/ctf-types.h>
-#include <stdint.h>
-#include <glib.h>
-#include <endian.h>
-
-uint64_t uint_read(const uint8_t *ptr, size_t len, int byte_order)
-{
- int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
-
- switch (len) {
- case 8:
- {
- uint8_t v;
-
- v = *(const uint8_t *)ptr;
- return v;
- }
- case 16:
- {
- uint16_t v;
-
- v = *(const uint16_t *)ptr;
- return rbo ? GUINT16_SWAP_LE_BE(v) : v;
- }
- case 32:
- {
- uint32_t v;
-
- v = *(const uint32_t *)ptr;
- return rbo ? GUINT32_SWAP_LE_BE(v) : v;
- }
- case 64:
- {
- uint64_t v;
-
- v = *(const uint64_t *)ptr;
- return rbo ? GUINT64_SWAP_LE_BE(v) : v;
- }
- default:
- assert(0);
- }
-}
-
-int64_t int_read(const uint8_t *ptr, size_t len, int byte_order)
-{
- int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
-
- switch (len) {
- case 8:
- {
- int8_t v;
-
- v = *(const int8_t *)ptr;
- return v;
- }
- case 16:
- {
- int16_t v;
-
- v = *(const int16_t *)ptr;
- return rbo ? GUINT16_SWAP_LE_BE(v) : v;
- }
- case 32:
- {
- int32_t v;
-
- v = *(const int32_t *)ptr;
- return rbo ? GUINT32_SWAP_LE_BE(v) : v;
- }
- case 64:
- {
- int64_t v;
-
- v = *(const int64_t *)ptr;
- return rbo ? GUINT64_SWAP_LE_BE(v) : v;
- }
- default:
- assert(0);
- }
-}
-
-size_t uint_write(uint8_t *ptr, size_t len, int byte_order, uint64_t v)
-{
- int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
-
- if (!ptr)
- goto end;
-
- switch (len) {
- case 8: *(uint8_t *)ptr = (uint8_t) v;
- break;
- case 16:
- *(uint16_t *)ptr = 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) v;
- break;
- case 64:
- *(uint64_t *)ptr = rbo ? GUINT64_SWAP_LE_BE(v) : v;
- break;
- default:
- assert(0);
- }
-end:
- return len;
-}
-
-size_t int_write(uint8_t *ptr, size_t len, int byte_order, int64_t v)
-{
- int rbo = (byte_order != BYTE_ORDER); /* reverse byte order */
-
- if (!ptr)
- goto end;
-
- switch (len) {
- case 8: *(int8_t *)ptr = (int8_t) v;
- break;
- case 16:
- *(int16_t *)ptr = 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) v;
- break;
- case 64:
- *(int64_t *)ptr = rbo ? GUINT64_SWAP_LE_BE(v) : v;
- break;
- default:
- assert(0);
- }
-end:
- return len;
-}
+++ /dev/null
-/*
- * Common Trace Format
- *
- * Strings read/write functions.
- *
- * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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 <ctf/ctf-types.h>
-#include <string.h>
-
-size_t string_copy(char *dest, const char *src)
-{
- size_t len = strlen(src) + 1;
-
- if (!dest)
- goto end;
- strcpy(dest, src);
-end:
- return len * 8;
-}
+++ /dev/null
-/*
- * Common Trace Format
- *
- * Structure write/access functions.
- *
- * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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 <ctf/ctf-types.h>
-#include <glib.h>
-
-
+++ /dev/null
-/*
- * Common Trace Format
- *
- * Types registry.
- *
- * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * 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 <ctf/ctf-types.h>
-#include <glib.h>
-#include <errno.h>
-
-struct type_class {
- GQuark qname;
- void (*read)();
- size_t (*write)();
-};
-
-struct type {
- struct type_class *class;
- size_t alignment; /* type alignment, in bits */
- ssize_t len; /* type length, in bits. -1 for dynamic size. */
-};
-
-/*
- * 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).
- */
-GHashTable *type_classes;
-
-struct type_class *ctf_lookup_type_class(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)())
-{
- struct type_class tc = g_new(struct type_class, 1);
- GQuark qname = g_quark_from_string(name);
-
- if (ctf_lookup_type_class(qname))
- return -EEXIST;
-
- g_hash_table_insert(type_classes,
- (gconstpointer) (unsigned long) qname,
- tc);
- return 0;
-}
-
-int ctf_init_types(void)
-{
- type_classes = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- NULL, g_free);
- if (!type_classes)
- return -ENOMEM;
- return 0;
-}
-
-int ctf_finalize_types(void)
-{
- g_hash_table_destroy(type_classes);
-}