#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/types.h>
#include <stdint.h>
+#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include <glib.h>
struct bt_field_common_string {
struct bt_field_common common;
- GString *payload;
+ GArray *buf;
+ size_t size;
};
struct bt_field_enumeration {
bt_field_common_create_func field_create_func,
GDestroyNotify field_release_func);
+BT_HIDDEN
+int bt_field_common_string_initialize(struct bt_field_common *field,
+ struct bt_field_type_common *type,
+ bt_object_release_func release_func,
+ struct bt_field_common_methods *methods);
+
BT_HIDDEN
int bt_field_common_generic_validate(struct bt_field_common *field);
BT_HIDDEN
void bt_field_common_sequence_reset_recursive(struct bt_field_common *field);
-BT_HIDDEN
-void bt_field_common_string_reset(struct bt_field_common *field);
-
BT_HIDDEN
void bt_field_common_generic_set_is_frozen(struct bt_field_common *field,
bool is_frozen);
BT_ASSERT_PRE_FIELD_COMMON_IS_SET(field, "String field");
BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field,
BT_FIELD_TYPE_ID_STRING, "Field");
- return string->payload->str;
+ return (const char *) string->buf->data;
}
static inline
const char *value)
{
struct bt_field_common_string *string = BT_FROM_COMMON(field);
+ size_t str_len;
BT_ASSERT_PRE_NON_NULL(field, "String field");
BT_ASSERT_PRE_NON_NULL(value, "Value");
BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field,
BT_FIELD_TYPE_ID_STRING, "Field");
- if (string->payload) {
- g_string_assign(string->payload, value);
- } else {
- string->payload = g_string_new(value);
- }
-
- bt_field_common_set(field, true);
- return 0;
-}
-
-static inline
-int bt_field_common_string_append(struct bt_field_common *field,
- const char *value)
-{
- struct bt_field_common_string *string_field = BT_FROM_COMMON(field);
+ str_len = strlen(value);
- BT_ASSERT_PRE_NON_NULL(field, "String field");
- BT_ASSERT_PRE_NON_NULL(value, "Value");
- BT_ASSERT_PRE_FIELD_COMMON_HOT(field, "String field");
- BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field,
- BT_FIELD_TYPE_ID_STRING, "Field");
-
- if (string_field->payload) {
- g_string_append(string_field->payload, value);
- } else {
- string_field->payload = g_string_new(value);
+ if (str_len + 1 > string->buf->len) {
+ g_array_set_size(string->buf, str_len + 1);
}
+ memcpy(string->buf->data, value, str_len);
+ ((char *) string->buf->data)[str_len] = '\0';
+ string->size = str_len;
bt_field_common_set(field, true);
return 0;
}
const char *value, unsigned int length)
{
struct bt_field_common_string *string_field = BT_FROM_COMMON(field);
+ char *data;
+ size_t new_size;
BT_ASSERT_PRE_NON_NULL(field, "String field");
BT_ASSERT_PRE_NON_NULL(value, "Value");
BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field,
BT_FIELD_TYPE_ID_STRING, "Field");
- /* make sure no null bytes are appended */
+ /* Make sure no null bytes are appended */
BT_ASSERT_PRE(memchr(value, '\0', length) == NULL,
"String value to append contains a null character: "
"partial-value=\"%.32s\", length=%u", value, length);
- if (string_field->payload) {
- g_string_append_len(string_field->payload, value, length);
- } else {
- string_field->payload = g_string_new_len(value, length);
+ new_size = string_field->size + length;
+
+ if (new_size + 1 > string_field->buf->len) {
+ g_array_set_size(string_field->buf, new_size + 1);
}
+ data = string_field->buf->data;
+ memcpy(data + string_field->size, value, length);
+ ((char *) string_field->buf->data)[new_size] = '\0';
+ string_field->size = new_size;
bt_field_common_set(field, true);
return 0;
}
+static inline
+int bt_field_common_string_append(struct bt_field_common *field,
+ const char *value)
+{
+ BT_ASSERT_PRE_NON_NULL(value, "Value");
+
+ return bt_field_common_string_append_len(field, value,
+ strlen(value));
+}
+
static inline
int bt_field_common_string_clear(struct bt_field_common *field)
{
BT_ASSERT_PRE_FIELD_COMMON_HOT(field, "String field");
BT_ASSERT_PRE_FIELD_COMMON_HAS_TYPE_ID(field,
BT_FIELD_TYPE_ID_STRING, "Field");
-
- if (string_field->payload) {
- g_string_set_size(string_field->payload, 0);
- } else {
- string_field->payload = g_string_new(NULL);
- }
-
+ string_field->size = 0;
bt_field_common_set(field, true);
return 0;
}
BT_LOGD("Finalizing common string field object: addr=%p", field);
bt_field_common_finalize(field);
- if (string->payload) {
- g_string_free(string->payload, TRUE);
+ if (string->buf) {
+ g_array_free(string->buf, TRUE);
}
}
.validate = bt_field_common_generic_validate,
.copy = NULL,
.is_set = bt_field_common_generic_is_set,
- .reset = bt_field_common_string_reset,
+ .reset = bt_field_common_generic_reset,
};
static struct bt_field_common_methods bt_field_structure_methods = {
return ret;
}
+BT_HIDDEN
+int bt_field_common_string_initialize(struct bt_field_common *field,
+ struct bt_field_type_common *type,
+ bt_object_release_func release_func,
+ struct bt_field_common_methods *methods)
+{
+ int ret = 0;
+ struct bt_field_common_string *string = BT_FROM_COMMON(field);
+
+ BT_LOGD("Initializing common string field object: ft-addr=%p", type);
+ bt_field_common_initialize(field, type, release_func, methods);
+ string->buf = g_array_sized_new(FALSE, FALSE, sizeof(char), 1);
+ if (!string->buf) {
+ ret = -1;
+ goto end;
+ }
+
+ g_array_index(string->buf, char, 0) = '\0';
+ BT_LOGD("Initialized common string field object: addr=%p, ft-addr=%p",
+ field, type);
+
+end:
+ return ret;
+}
+
static
struct bt_field *bt_field_variant_create(struct bt_field_type *type)
{
BT_LOGD("Creating string field object: ft-addr=%p", type);
if (string) {
- bt_field_common_initialize(BT_TO_COMMON(string),
+ bt_field_common_string_initialize(BT_TO_COMMON(string),
(void *) type, NULL, &bt_field_string_methods);
BT_LOGD("Created string field object: addr=%p, ft-addr=%p",
string, type);
sequence->length = 0;
}
-BT_HIDDEN
-void bt_field_common_string_reset(struct bt_field_common *field)
-{
- struct bt_field_common_string *string = BT_FROM_COMMON(field);
-
- BT_ASSERT(field);
- bt_field_common_generic_reset(field);
-
- if (string->payload) {
- g_string_truncate(string->payload, 0);
- }
-}
-
BT_HIDDEN
void bt_field_common_generic_set_is_frozen(struct bt_field_common *field,
bool is_frozen)