int len;
int count;
int offset;
+ int text_offset;
+ gboolean include_len;
} RecordDataString;
typedef struct RecordDataTree RecordDataTree;
gssize len)
{
RecordDataString *s, tmp;
+ gboolean include_len = len >= 0;
if (len < 0)
len = strlen (str);
if (s)
{
s->count++;
+ s->include_len |= include_len;
return s;
}
s->string = g_string_chunk_insert_len (data->chunks, str, len);
s->len = len;
s->count = 1;
+ s->include_len = include_len;
g_hash_table_add (data->strings, s);
return s;
}
}
+static int
+marshal_uint32_len (guint32 v)
+{
+ if (v < 128)
+ return 1;
+
+ if (v < (1<<14))
+ return 2;
+
+ if (v < (1<<21))
+ return 3;
+
+ if (v < (1<<28))
+ return 4;
+
+ return 5;
+}
+
static void
marshal_tree (GString *marshaled,
RecordDataTree *tree)
break;
case RECORD_TYPE_TEXT:
marshal_uint32 (marshaled, RECORD_TYPE_TEXT);
- marshal_uint32 (marshaled, tree->data->offset);
+ marshal_uint32 (marshaled, tree->data->text_offset);
break;
case RECORD_TYPE_END_ELEMENT:
default:
for (l = string_table; l != NULL; l = l->next)
{
RecordDataString *s = l->data;
+
+ if (s->include_len)
+ {
+ s->text_offset = offset;
+ offset += marshal_uint32_len (s->len);
+ }
+
s->offset = offset;
offset += s->len + 1;
}
for (l = string_table; l != NULL; l = l->next)
{
RecordDataString *s = l->data;
+
+ if (s->include_len)
+ marshal_uint32 (marshaled, s->len);
+
g_string_append_len (marshaled, s->string, s->len + 1);
}
return strings + offset;
}
+static const char *
+demarshal_text (const char **tree,
+ const char *strings,
+ guint32 *len)
+{
+ guint32 offset = demarshal_uint32 (tree);
+ const char *str = strings + offset;
+
+ *len = demarshal_uint32 (&str);
+ return str;
+}
+
static void
propagate_error (GtkBuildableParseContext *context,
GError **dest,
const char *strings,
GError **error)
{
+ guint32 len;
const char *text;
GError *tmp_error = NULL;
- text = demarshal_string (tree, strings);
+ text = demarshal_text (tree, strings, &len);
(*context->internal_callbacks->text) (NULL,
text,
- strlen (text),
+ len,
context,
&tmp_error);