/** * pk_manifest_new_from_data: * @data: The manifest data. * @length: The length of data. * * Creates a new instance of #PkManifest from a buffer of data. * * Returns: the newly created #PkManifest instance. * * Side effects: None. */ PkManifest* pk_manifest_new_from_data (const guint8 *data, /* IN */ gsize length) /* IN */ { PkManifest *manifest; EggBuffer *buffer; ENTRY; manifest = pk_manifest_new(); buffer = egg_buffer_new_from_data(data, length); if (!decode(manifest, buffer)) { GOTO(error); } egg_buffer_unref(buffer); RETURN(manifest); error: egg_buffer_unref(buffer); pk_manifest_unref(manifest); RETURN(NULL); }
/** * pka_encoder_real_encode_samples: * @manifest: A #PkaManifest. * * Default encoder for samples. * * Returns: None. * Side effects: None. */ static gboolean pka_encoder_real_encode_samples (PkaManifest *manifest, /* IN */ PkaSample **samples, /* IN */ gint n_samples, /* IN */ guint8 **data, /* OUT */ gsize *data_len) /* OUT */ { EggBuffer *buf; struct timespec mts; struct timespec sts; struct timespec rel; guint64 rel_composed; PkaResolution res; const guint8 *tbuf; gsize tlen; gint i; g_return_val_if_fail(data != NULL, FALSE); g_return_val_if_fail(data_len != NULL, FALSE); ENTRY; buf = egg_buffer_new(); pka_manifest_get_timespec(manifest, &mts); res = pka_manifest_get_resolution(manifest); for (i = 0; i < n_samples; i++) { /* * Add the source identifier. */ egg_buffer_write_tag(buf, 1, EGG_BUFFER_UINT); egg_buffer_write_uint(buf, pka_sample_get_source_id(samples[i])); /* * Add the relative time since the manifest; loosing un-needed * precision to aide varint encoding. */ pka_sample_get_timespec(samples[i], &sts); timespec_subtract(&sts, &mts, &rel); rel_composed = pka_resolution_apply(res, &rel); egg_buffer_write_tag(buf, 2, EGG_BUFFER_UINT64); egg_buffer_write_uint64(buf, rel_composed); /* * The sample is a protobuf inspired blob but is not protobuf compat. * * This was so that we could save significant message and repeated type * overhead that is not needed for introspection since we have the * manifest to provide us that data. * * Therefore, we simply treat the sample as an opaque buffer for the * other side to unwrap. */ pka_sample_get_data(samples[i], &tbuf, &tlen); egg_buffer_write_tag(buf, 3, EGG_BUFFER_DATA); egg_buffer_write_data(buf, tbuf, tlen); } egg_buffer_get_buffer(buf, &tbuf, &tlen); *data = g_malloc(tlen); *data_len = tlen; memcpy(*data, tbuf, tlen); egg_buffer_unref(buf); RETURN(TRUE); }
static gboolean pka_encoder_real_encode_manifest (PkaManifest *manifest, /* IN */ guint8 **data, /* IN */ gsize *data_len) /* IN */ { EggBuffer *buf, *mbuf, *ebuf; struct timespec ts; guint64 t; const guint8 *tbuf; gsize tlen; gint rows; gint i; g_return_val_if_fail(manifest != NULL, FALSE); g_return_val_if_fail(data != NULL, FALSE); g_return_val_if_fail(data_len != NULL, FALSE); ENTRY; buf = egg_buffer_new(); /* * Field 1: Timestamp. Currently encoded in microseconds. We should * determine what we want to do long-term. */ pka_manifest_get_timespec(manifest, &ts); timespec_to_usec(&ts, &t); egg_buffer_write_tag(buf, 1, EGG_BUFFER_UINT64); egg_buffer_write_uint64(buf, t); /* * Desired sample resolution. This allows us to save considerable * width in the relative-timestamp per sample. */ egg_buffer_write_tag(buf, 2, EGG_BUFFER_ENUM); egg_buffer_write_uint(buf, pka_manifest_get_resolution(manifest)); /* * Source index offset within the channel. */ egg_buffer_write_tag(buf, 3, EGG_BUFFER_UINT); egg_buffer_write_uint(buf, pka_manifest_get_source_id(manifest)); /* * Create a new buffer for the repeated data series. */ ebuf = egg_buffer_new(); /* * Write the manifest data description. This is a set of embedded * messages within the message. */ rows = pka_manifest_get_n_rows(manifest); for (i = 1; i <= rows; i++) { mbuf = egg_buffer_new(); /* * Write the row identifier. */ egg_buffer_write_tag(mbuf, 1, EGG_BUFFER_UINT); egg_buffer_write_uint(mbuf, i); /* * Write the row type. */ egg_buffer_write_tag(mbuf, 2, EGG_BUFFER_ENUM); egg_buffer_write_uint(mbuf, pka_manifest_get_row_type(manifest, i)); /* * Write the row name. */ egg_buffer_write_tag(mbuf, 3, EGG_BUFFER_STRING); egg_buffer_write_string(mbuf, pka_manifest_get_row_name(manifest, i)); /* * Embed the message as a data blob. */ egg_buffer_get_buffer(mbuf, &tbuf, &tlen); egg_buffer_write_data(ebuf, tbuf, tlen); egg_buffer_unref(mbuf); } /* * Add the repeated message length and data. */ egg_buffer_get_buffer(ebuf, &tbuf, &tlen); egg_buffer_write_tag(buf, 4, EGG_BUFFER_REPEATED); egg_buffer_write_data(buf, tbuf, tlen); egg_buffer_unref(ebuf); /* * Copy the buffer to the destination. */ egg_buffer_get_buffer(buf, &tbuf, &tlen); *data = g_malloc(tlen); *data_len = tlen; memcpy(*data, tbuf, tlen); egg_buffer_unref(buf); RETURN(TRUE); }