Add "encoding" for sequence and array of integers
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 May 2011 16:13:23 +0000 (12:13 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 17 May 2011 16:13:23 +0000 (12:13 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 files changed:
formats/ctf-text/types/array.c
formats/ctf-text/types/integer.c
formats/ctf/ctf.c
formats/ctf/metadata/ctf-visitor-generate-io-struct.c
formats/ctf/types/array.c
formats/ctf/types/sequence.c
include/babeltrace/ctf-text/types.h
include/babeltrace/ctf/types.h
include/babeltrace/types.h
types/array.c
types/float.c
types/integer.c
types/sequence.c

index 9524ba166ea17b6f4d78497a2cbadcbf62f5a33c..db941426d82da754d86650162c1f9c8260943849 100644 (file)
 int ctf_text_array_write(struct stream_pos *ppos, struct definition *definition)
 {
        struct ctf_text_stream_pos *pos = ctf_text_pos(ppos);
+       struct definition_array *array_definition =
+               container_of(definition, struct definition_array, p);
+       struct declaration_array *array_declaration =
+               array_definition->declaration;
+       struct declaration *elem = array_declaration->elem;
        int field_nr_saved;
-       int ret;
+       int ret = 0;
 
        if (!pos->dummy) {
                if (pos->field_nr++ != 0)
@@ -32,6 +37,28 @@ int ctf_text_array_write(struct stream_pos *ppos, struct definition *definition)
                if (pos->print_names)
                        fprintf(pos->fp, "%s = ",
                                g_quark_to_string(definition->name));
+       }
+
+       if (elem->id == CTF_TYPE_INTEGER) {
+               struct declaration_integer *integer_declaration =
+                       container_of(elem, struct declaration_integer, p);
+
+               if (integer_declaration->encoding == CTF_STRING_UTF8
+                     || integer_declaration->encoding == CTF_STRING_ASCII) {
+
+                       if (!(integer_declaration->len == CHAR_BIT
+                           && integer_declaration->p.alignment == CHAR_BIT)) {
+                               pos->string = array_definition->string;
+                               g_string_assign(array_definition->string, "");
+                               ret = array_rw(ppos, definition);
+                               pos->string = NULL;
+                       }
+                       fprintf(pos->fp, "\"%s\"", array_definition->string->str);
+                       return ret;
+               }
+       }
+
+       if (!pos->dummy) {
                fprintf(pos->fp, "[");
                pos->depth++;
        }
index 3d1c459fd91b9259949526200e469b75d273c206..1337eca3ab13df44bb89e7ee5903d381dd743a88 100644 (file)
@@ -40,6 +40,19 @@ int ctf_text_integer_write(struct stream_pos *ppos, struct definition *definitio
                fprintf(pos->fp, "%s = ",
                        g_quark_to_string(definition->name));
 
+       if (integer_declaration->encoding == CTF_STRING_ASCII
+           || integer_declaration->encoding == CTF_STRING_UTF8) {
+
+               if (!integer_declaration->signedness) {
+                       g_string_append_c(pos->string,
+                               (int) integer_definition->value._unsigned);
+               } else {
+                       g_string_append_c(pos->string,
+                               (int) integer_definition->value._signed);
+               }
+               return 0;
+       }
+
        switch (integer_declaration->base) {
        case 0: /* default */
        case 10:
index 13c87eae176651fe97b1fd0c25d3871e5f02f6a4..1ba00a67232d59f5fb76bac2a07d8daea2e01984 100644 (file)
@@ -63,8 +63,8 @@ rw_dispatch read_dispatch_table[] = {
        [ CTF_TYPE_STRING ] = ctf_string_read,
        [ CTF_TYPE_STRUCT ] = ctf_struct_rw,
        [ CTF_TYPE_VARIANT ] = ctf_variant_rw,
-       [ CTF_TYPE_ARRAY ] = ctf_array_rw,
-       [ CTF_TYPE_SEQUENCE ] = ctf_sequence_rw,
+       [ CTF_TYPE_ARRAY ] = ctf_array_read,
+       [ CTF_TYPE_SEQUENCE ] = ctf_sequence_read,
 };
 
 static
@@ -75,8 +75,8 @@ rw_dispatch write_dispatch_table[] = {
        [ CTF_TYPE_STRING ] = ctf_string_write,
        [ CTF_TYPE_STRUCT ] = ctf_struct_rw,
        [ CTF_TYPE_VARIANT ] = ctf_variant_rw,
-       [ CTF_TYPE_ARRAY ] = ctf_array_rw,
-       [ CTF_TYPE_SEQUENCE ] = ctf_sequence_rw,
+       [ CTF_TYPE_ARRAY ] = ctf_array_write,
+       [ CTF_TYPE_SEQUENCE ] = ctf_sequence_write,
 };
 
 static
index 9dffdcbf50a0cf5c938035ebff6f3746df21e3e8..29068563f7657d7786d4a74b8323f40e794e5a65 100644 (file)
@@ -325,7 +325,7 @@ struct declaration *ctf_type_declarator_visit(FILE *fd, int depth,
                                         */
                                        integer_declaration = integer_declaration_new(integer_declaration->len,
                                                integer_declaration->byte_order, integer_declaration->signedness,
-                                               integer_declaration->p.alignment, 16);
+                                               integer_declaration->p.alignment, 16, integer_declaration->encoding);
                                        nested_declaration = &integer_declaration->p;
                                }
                        }
@@ -1076,6 +1076,7 @@ struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
        int signedness = 0;
        int has_alignment = 0, has_size = 0;
        int base = 0;
+       enum ctf_string_encoding encoding = CTF_STRING_NONE;
        struct declaration_integer *integer_declaration;
 
        cds_list_for_each_entry(expression, expressions, siblings) {
@@ -1164,6 +1165,34 @@ struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
                                        __func__);
                                return NULL;
                        }
+               } else if (!strcmp(left->u.unary_expression.u.string, "encoding")) {
+                       char *s_right;
+
+                       if (right->u.unary_expression.type != UNARY_STRING) {
+                               fprintf(fd, "[error] %s: encoding: expecting unary string\n",
+                                       __func__);
+                               return NULL;
+                       }
+                       s_right = concatenate_unary_strings(&expression->u.ctf_expression.right);
+                       if (!s_right) {
+                               fprintf(fd, "[error] %s: unexpected unary expression for integer base\n", __func__);
+                               g_free(s_right);
+                               return NULL;
+                       }
+                       if (!strcmp(s_right, "UTF8")
+                           || !strcmp(s_right, "utf8")
+                           || !strcmp(s_right, "utf-8")
+                           || !strcmp(s_right, "UTF-8"))
+                               encoding = CTF_STRING_UTF8;
+                       else if (!strcmp(s_right, "ASCII")
+                           || !strcmp(s_right, "ascii"))
+                               encoding = CTF_STRING_ASCII;
+                       else {
+                               fprintf(fd, "[error] %s: unknown string encoding \"%s\"\n", __func__, s_right);
+                               g_free(s_right);
+                               return NULL;
+                       }
+                       g_free(s_right);
                } else {
                        fprintf(fd, "[error] %s: unknown attribute name %s\n",
                                __func__, left->u.unary_expression.u.string);
@@ -1184,7 +1213,8 @@ struct declaration *ctf_declaration_integer_visit(FILE *fd, int depth,
                }
        }
        integer_declaration = integer_declaration_new(size,
-                               byte_order, signedness, alignment, base);
+                               byte_order, signedness, alignment,
+                               base, encoding);
        return &integer_declaration->p;
 }
 
index 3fd0ad427ebdc6548043294cd62f324a04bfeb89..71475014b9034e33bdc055aa355de4ee527d0b82 100644 (file)
 
 #include <babeltrace/ctf/types.h>
 
-int ctf_array_rw(struct stream_pos *pos, struct definition *definition)
+int ctf_array_read(struct stream_pos *ppos, struct definition *definition)
 {
-       return array_rw(pos, definition);
+       struct definition_array *array_definition =
+               container_of(definition, struct definition_array, p);
+       struct declaration_array *array_declaration =
+               array_definition->declaration;
+       struct declaration *elem = array_declaration->elem;
+       struct ctf_stream_pos *pos =
+               container_of(ppos, struct ctf_stream_pos, parent);
+
+       if (elem->id == CTF_TYPE_INTEGER) {
+               struct declaration_integer *integer_declaration =
+                       container_of(elem, struct declaration_integer, p);
+
+               if (integer_declaration->encoding == CTF_STRING_UTF8
+                     || integer_declaration->encoding == CTF_STRING_ASCII) {
+
+                       if (integer_declaration->len == CHAR_BIT
+                           && integer_declaration->p.alignment == CHAR_BIT) {
+
+                               ctf_align_pos(pos, integer_declaration->p.alignment);
+                               if (!ctf_pos_access_ok(pos, array_declaration->len * CHAR_BIT))
+                                       return -EFAULT;
+
+                               g_string_assign(array_definition->string, "");
+                               g_string_insert_len(array_definition->string,
+                                       0, (char *) ctf_get_pos_addr(pos),
+                                       array_declaration->len);
+                               ctf_move_pos(pos, array_declaration->len * CHAR_BIT);
+                               return 0;
+                       }
+               }
+       }
+       return array_rw(ppos, definition);
+}
+
+int ctf_array_write(struct stream_pos *ppos, struct definition *definition)
+{
+       struct definition_array *array_definition =
+               container_of(definition, struct definition_array, p);
+       struct declaration_array *array_declaration =
+               array_definition->declaration;
+       struct declaration *elem = array_declaration->elem;
+       struct ctf_stream_pos *pos =
+               container_of(ppos, struct ctf_stream_pos, parent);
+
+       if (elem->id == CTF_TYPE_INTEGER) {
+               struct declaration_integer *integer_declaration =
+                       container_of(elem, struct declaration_integer, p);
+
+               if (integer_declaration->encoding == CTF_STRING_UTF8
+                     || integer_declaration->encoding == CTF_STRING_ASCII) {
+
+                       if (integer_declaration->len == CHAR_BIT
+                           && integer_declaration->p.alignment == CHAR_BIT) {
+
+                               ctf_align_pos(pos, integer_declaration->p.alignment);
+                               if (!ctf_pos_access_ok(pos, array_declaration->len * CHAR_BIT))
+                                       return -EFAULT;
+
+                               memcpy((char *) ctf_get_pos_addr(pos),
+                                       array_definition->string->str,
+                                       array_declaration->len);
+                               ctf_move_pos(pos, array_declaration->len * CHAR_BIT);
+                               return 0;
+                       }
+               }
+       }
+       return array_rw(ppos, definition);
 }
index acd4c7c0fca8310efc5bc890283525122d533fa1..a14d5891027370cac352bc5522aebd6d5c38aed8 100644 (file)
 
 #include <babeltrace/ctf/types.h>
 
-int ctf_sequence_rw(struct stream_pos *ppos, struct definition *definition)
+int ctf_sequence_read(struct stream_pos *ppos, struct definition *definition)
 {
-       struct declaration *declaration = definition->declaration;
+       struct definition_sequence *sequence_definition =
+               container_of(definition, struct definition_sequence, p);
+       struct declaration_sequence *sequence_declaration =
+               sequence_definition->declaration;
+       struct declaration *elem = sequence_declaration->elem;
        struct ctf_stream_pos *pos = ctf_pos(ppos);
 
-       ctf_align_pos(pos, declaration->alignment);
+       if (elem->id == CTF_TYPE_INTEGER) {
+               struct declaration_integer *integer_declaration =
+                       container_of(elem, struct declaration_integer, p);
+
+               if (integer_declaration->encoding == CTF_STRING_UTF8
+                     || integer_declaration->encoding == CTF_STRING_ASCII) {
+
+                       if (integer_declaration->len == CHAR_BIT
+                           && integer_declaration->p.alignment == CHAR_BIT) {
+                               uint64_t len = sequence_len(sequence_definition);
+
+                               ctf_align_pos(pos, integer_declaration->p.alignment);
+                               if (!ctf_pos_access_ok(pos, len * CHAR_BIT))
+                                       return -EFAULT;
+
+                               g_string_assign(sequence_definition->string, "");
+                               g_string_insert_len(sequence_definition->string,
+                                       0, (char *) ctf_get_pos_addr(pos), len);
+                               ctf_move_pos(pos, len * CHAR_BIT);
+                               return 0;
+                       }
+               }
+       }
+       return sequence_rw(ppos, definition);
+}
+
+int ctf_sequence_write(struct stream_pos *ppos, struct definition *definition)
+{
+       struct definition_sequence *sequence_definition =
+               container_of(definition, struct definition_sequence, p);
+       struct declaration_sequence *sequence_declaration =
+               sequence_definition->declaration;
+       struct declaration *elem = sequence_declaration->elem;
+       struct ctf_stream_pos *pos = ctf_pos(ppos);
+
+       if (elem->id == CTF_TYPE_INTEGER) {
+               struct declaration_integer *integer_declaration =
+                       container_of(elem, struct declaration_integer, p);
+
+               if (integer_declaration->encoding == CTF_STRING_UTF8
+                     || integer_declaration->encoding == CTF_STRING_ASCII) {
+
+                       if (integer_declaration->len == CHAR_BIT
+                           && integer_declaration->p.alignment == CHAR_BIT) {
+                               uint64_t len = sequence_len(sequence_definition);
+
+                               ctf_align_pos(pos, integer_declaration->p.alignment);
+                               if (!ctf_pos_access_ok(pos, len * CHAR_BIT))
+                                       return -EFAULT;
+
+                               memcpy((char *) ctf_get_pos_addr(pos),
+                                       sequence_definition->string->str, len);
+                               ctf_move_pos(pos, len * CHAR_BIT);
+                               return 0;
+                       }
+               }
+       }
        return sequence_rw(ppos, definition);
 }
index 0670b3d6dffdf182a09c4963f309a9e72213833b..7703e7b8e25148272f5c6ed91f8e0264ea0d4706 100644 (file)
@@ -39,6 +39,7 @@ struct ctf_text_stream_pos {
        int dummy;              /* disable output */
        int print_names;        /* print field names */
        int field_nr;
+       GString *string;        /* Current string */
 };
 
 static inline
index 95c0d5e2659056aeee33b1d09d0f23ce8a7fe2a4..1ec2ad5a497ba07472667db066b478f8803fc8c6 100644 (file)
@@ -76,8 +76,10 @@ int ctf_enum_read(struct stream_pos *pos, struct definition *definition);
 int ctf_enum_write(struct stream_pos *pos, struct definition *definition);
 int ctf_struct_rw(struct stream_pos *pos, struct definition *definition);
 int ctf_variant_rw(struct stream_pos *pos, struct definition *definition);
-int ctf_array_rw(struct stream_pos *pos, struct definition *definition);
-int ctf_sequence_rw(struct stream_pos *pos, struct definition *definition);
+int ctf_array_read(struct stream_pos *pos, struct definition *definition);
+int ctf_array_write(struct stream_pos *pos, struct definition *definition);
+int ctf_sequence_read(struct stream_pos *pos, struct definition *definition);
+int ctf_sequence_write(struct stream_pos *pos, struct definition *definition);
 
 void ctf_move_pos_slow(struct ctf_stream_pos *pos, size_t offset, int whence);
 
index 2aa45b8a0cdfbe6f33f0cd290bf50064ecaeae88..da9ca5c5faeabef771f70fcadf5e57599ffc209a 100644 (file)
@@ -129,6 +129,13 @@ int generic_rw(struct stream_pos *pos, struct definition *definition)
        return call(pos, definition);
 }
 
+enum ctf_string_encoding {
+       CTF_STRING_NONE = 0,
+       CTF_STRING_UTF8,
+       CTF_STRING_ASCII,
+       CTF_STRING_UNKNOWN,
+};
+
 /*
  * 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
@@ -140,6 +147,7 @@ struct declaration_integer {
        int byte_order;         /* byte order */
        int signedness;
        int base;               /* Base for pretty-printing: 2, 8, 10, 16 */
+       enum ctf_string_encoding encoding;
 };
 
 struct definition_integer {
@@ -225,12 +233,6 @@ struct definition_enum {
        GArray *value;
 };
 
-enum ctf_string_encoding {
-       CTF_STRING_UTF8 = 0,
-       CTF_STRING_ASCII,
-       CTF_STRING_UNKNOWN,
-};
-
 struct declaration_string {
        struct declaration p;
        enum ctf_string_encoding encoding;
@@ -297,6 +299,7 @@ struct definition_array {
        struct declaration_array *declaration;
        struct definition_scope *scope;
        GPtrArray *elems;               /* Array of pointers to struct definition */
+       GString *string;                /* String for encoded integer children */
 };
 
 struct declaration_sequence {
@@ -312,6 +315,7 @@ struct definition_sequence {
        struct definition_scope *scope;
        struct definition_integer *length;
        GPtrArray *elems;               /* Array of pointers to struct definition */
+       GString *string;                /* String for encoded integer children */
 };
 
 int register_declaration(GQuark declaration_name,
@@ -381,7 +385,7 @@ void definition_unref(struct definition *definition);
 
 struct declaration_integer *integer_declaration_new(size_t len, int byte_order,
                                  int signedness, size_t alignment,
-                                 int base);
+                                 int base, enum ctf_string_encoding encoding);
 
 /*
  * mantissa_len is the length of the number of bytes represented by the mantissa
index 0be26476df8605945713bb74927a0848cfd9ed85..6c17299a532718cc52841b62497f2616456720f9 100644 (file)
@@ -110,6 +110,25 @@ struct definition *
        ret = register_field_definition(field_name, &array->p,
                                        parent_scope);
        assert(!ret);
+       array->string = NULL;
+       array->elems = NULL;
+
+       if (array_declaration->elem->id == CTF_TYPE_INTEGER) {
+               struct declaration_integer *integer_declaration =
+                       container_of(array_declaration->elem, struct declaration_integer, p);
+
+               if (integer_declaration->encoding == CTF_STRING_UTF8
+                     || integer_declaration->encoding == CTF_STRING_ASCII) {
+
+                       array->string = g_string_new("");
+
+                       if (integer_declaration->len == CHAR_BIT
+                           && integer_declaration->p.alignment == CHAR_BIT) {
+                               return &array->p;
+                       }
+               }
+       }
+
        array->elems = g_ptr_array_sized_new(array_declaration->len);
        g_ptr_array_set_size(array->elems, array_declaration->len);
        for (i = 0; i < array_declaration->len; i++) {
@@ -129,6 +148,7 @@ struct definition *
                if (!*field)
                        goto error;
        }
+
        return &array->p;
 
 error:
@@ -152,13 +172,17 @@ void _array_definition_free(struct definition *definition)
                container_of(definition, struct definition_array, p);
        uint64_t i;
 
-       for (i = 0; i < array->elems->len; i++) {
-               struct definition *field;
+       if (array->string)
+               (void) g_string_free(array->string, TRUE);
+       if (array->elems) {
+               for (i = 0; i < array->elems->len; i++) {
+                       struct definition *field;
 
-               field = g_ptr_array_index(array->elems, i);
-               field->declaration->definition_free(field);
+                       field = g_ptr_array_index(array->elems, i);
+                       field->declaration->definition_free(field);
+               }
+               (void) g_ptr_array_free(array->elems, TRUE);
        }
-       (void) g_ptr_array_free(array->elems, TRUE);
        free_definition_scope(array->scope);
        declaration_unref(array->p.declaration);
        g_free(array);
@@ -166,11 +190,15 @@ void _array_definition_free(struct definition *definition)
 
 uint64_t array_len(struct definition_array *array)
 {
+       if (!array->elems)
+               return array->string->len;
        return array->elems->len;
 }
 
 struct definition *array_index(struct definition_array *array, uint64_t i)
 {
+       if (!array->elems)
+               return NULL;
        if (i >= array->elems->len)
                return NULL;
        return g_ptr_array_index(array->elems, i);
index 5ae831ce2a745e3beaeff5973f59ac051ffd7ec7..dab8d0da734536b29e953840b3761453cbd93b6b 100644 (file)
@@ -58,11 +58,14 @@ struct declaration_float *
        float_declaration->byte_order = byte_order;
 
        float_declaration->sign = integer_declaration_new(1,
-                                           byte_order, false, 1, 2);
+                                               byte_order, false, 1, 2,
+                                               CTF_STRING_NONE);
        float_declaration->mantissa = integer_declaration_new(mantissa_len - 1,
-                                               byte_order, false, 1, 10);
+                                               byte_order, false, 1, 10,
+                                               CTF_STRING_NONE);
        float_declaration->exp = integer_declaration_new(exp_len,
-                                          byte_order, true, 1, 10);
+                                               byte_order, true, 1, 10,
+                                               CTF_STRING_NONE);
        return float_declaration;
 }
 
index 940963a51ec5a2fea08cb0cd197a21573303d8c8..6a95b939c70526a3ecaba05dfd2c5a111d11a6ab 100644 (file)
@@ -39,7 +39,8 @@ void _integer_declaration_free(struct declaration *declaration)
 
 struct declaration_integer *
        integer_declaration_new(size_t len, int byte_order,
-                        int signedness, size_t alignment, int base)
+                        int signedness, size_t alignment, int base,
+                        enum ctf_string_encoding encoding)
 {
        struct declaration_integer *integer_declaration;
 
@@ -54,6 +55,7 @@ struct declaration_integer *
        integer_declaration->byte_order = byte_order;
        integer_declaration->signedness = signedness;
        integer_declaration->base = base;
+       integer_declaration->encoding = encoding;
        return integer_declaration;
 }
 
index 119522d7de7a084f42345aef5a73b999755ebf7e..676d9ef6c57c87296b6efc57031a653add5f3ecf 100644 (file)
@@ -151,6 +151,26 @@ struct definition *_sequence_definition_new(struct declaration *declaration,
                goto error;
        }
        definition_ref(len_parent);
+
+       sequence->string = NULL;
+       sequence->elems = NULL;
+
+       if (sequence_declaration->elem->id == CTF_TYPE_INTEGER) {
+               struct declaration_integer *integer_declaration =
+                       container_of(sequence_declaration->elem, struct declaration_integer, p);
+
+               if (integer_declaration->encoding == CTF_STRING_UTF8
+                     || integer_declaration->encoding == CTF_STRING_ASCII) {
+
+                       sequence->string = g_string_new("");
+
+                       if (integer_declaration->len == CHAR_BIT
+                           && integer_declaration->p.alignment == CHAR_BIT) {
+                               return &sequence->p;
+                       }
+               }
+       }
+
        sequence->elems = g_ptr_array_new();
        return &sequence->p;
 
@@ -169,11 +189,15 @@ void _sequence_definition_free(struct definition *definition)
        struct definition *len_definition = &sequence->length->p;
        uint64_t i;
 
-       for (i = 0; i < sequence->elems->len; i++) {
-               struct definition *field;
+       if (sequence->string)
+               (void) g_string_free(sequence->string, TRUE);
+       if (sequence->elems) {
+               for (i = 0; i < sequence->elems->len; i++) {
+                       struct definition *field;
 
-               field = g_ptr_array_index(sequence->elems, i);
-               field->declaration->definition_free(field);
+                       field = g_ptr_array_index(sequence->elems, i);
+                       field->declaration->definition_free(field);
+               }
        }
        (void) g_ptr_array_free(sequence->elems, TRUE);
        definition_unref(len_definition);
@@ -189,6 +213,8 @@ uint64_t sequence_len(struct definition_sequence *sequence)
 
 struct definition *sequence_index(struct definition_sequence *sequence, uint64_t i)
 {
+       if (!sequence->elems)
+               return NULL;
        if (i >= sequence->length->value._unsigned)
                return NULL;
        assert(i < sequence->elems->len);
This page took 0.033441 seconds and 4 git commands to generate.