Beispiel #1
0
KvpFrame *
kvp_frame_get_frame(const KvpFrame *frame, const char *path)
{
    char *key = NULL;
    frame = get_trailer_or_null (frame, path, &key);
    return kvp_value_get_frame(kvp_frame_get_slot (frame, key));
}
Beispiel #2
0
KvpValue *
kvp_frame_get_slot_path (KvpFrame *frame,
                         const char *first_key, ...)
{
    va_list ap;
    KvpValue *value;
    const char *key;

    if (!frame || !first_key) return NULL;

    va_start (ap, first_key);

    key = first_key;
    value = NULL;

    while (TRUE)
    {
        value = kvp_frame_get_slot (frame, key);
        if (!value) break;

        key = va_arg (ap, const char *);
        if (!key) break;

        frame = kvp_value_get_frame (value);
        if (!frame)
        {
            value = NULL;
            break;
        }
    }

    va_end (ap);

    return value;
}
Beispiel #3
0
/* Get pointer to last frame in path, or NULL if the path doesn't
 * exist. The string stored in keypath will be hopelessly mangled .
 */
static inline const KvpFrame *
kvp_frame_get_frame_or_null_slash_trash (const KvpFrame *frame, char *key_path)
{
    KvpValue *value;
    char *key, *next;
    if (!frame || !key_path) return NULL;

    key = key_path;
    key --;

    while (key)
    {
        key ++;
        while ('/' == *key)
        {
            key++;
        }
        if (0x0 == *key) break;    /* trailing slash */
        next = strchr (key, '/');
        if (next) *next = 0x0;

        value = kvp_frame_get_slot (frame, key);
        if (!value) return NULL;
        frame = kvp_value_get_frame (value);
        if (!frame) return NULL;

        key = next;
    }
    return frame;
}
Beispiel #4
0
void
kvp_frame_set_slot_path (KvpFrame *frame,
                         const KvpValue *new_value,
                         const char *first_key, ...)
{
    va_list ap;
    const char *key;

    if (!frame) return;

    g_return_if_fail (first_key && *first_key != '\0');

    va_start (ap, first_key);

    key = first_key;

    while (TRUE)
    {
        KvpValue *value;
        const char *next_key;

        next_key = va_arg (ap, const char *);
        if (!next_key)
        {
            kvp_frame_set_slot (frame, key, new_value);
            break;
        }

        g_return_if_fail (*next_key != '\0');

        value = kvp_frame_get_slot (frame, key);
        if (!value)
        {
            KvpFrame *new_frame = kvp_frame_new ();
            KvpValue *frame_value = kvp_value_new_frame (new_frame);

            kvp_frame_set_slot_nc (frame, key, frame_value);

            value = kvp_frame_get_slot (frame, key);
            if (!value) break;
        }

        frame = kvp_value_get_frame (value);
        if (!frame) break;

        key = next_key;
    }

    va_end (ap);
}
Beispiel #5
0
/* Get the named frame, or create it if it doesn't exist.
 * gcc -O3 should inline it.  It performs no error checks,
 * the caller is responsible of passing good keys and frames.
 */
static inline KvpFrame *
get_or_make (KvpFrame *fr, const char * key)
{
    KvpFrame *next_frame;
    KvpValue *value;

    value = kvp_frame_get_slot (fr, key);
    if (value)
    {
        next_frame = kvp_value_get_frame (value);
    }
    else
    {
        next_frame = kvp_frame_new ();
        kvp_frame_set_slot_nc (fr, key,
                               kvp_value_new_frame_nc (next_frame));
    }
    return next_frame;
}
Beispiel #6
0
void
kvp_frame_set_slot_path_gslist (KvpFrame *frame,
                                const KvpValue *new_value,
                                GSList *key_path)
{
    if (!frame || !key_path) return;

    while (TRUE)
    {
        const char *key = static_cast<char*>(key_path->data);
        KvpValue *value;

        if (!key)
            return;

        g_return_if_fail (*key != '\0');

        key_path = key_path->next;
        if (!key_path)
        {
            kvp_frame_set_slot (frame, key, new_value);
            return;
        }

        value = kvp_frame_get_slot (frame, key);
        if (!value)
        {
            KvpFrame *new_frame = kvp_frame_new ();
            KvpValue *frame_value = kvp_value_new_frame (new_frame);

            kvp_frame_set_slot_nc (frame, key, frame_value);

            value = kvp_frame_get_slot (frame, key);
            if (!value)
                return;
        }

        frame = kvp_value_get_frame (value);
        if (!frame)
            return;
    }
}
/* Check if the session requires features unknown to this version of GnuCash.
 *
 * Returns a message to display if we found unknown features, NULL if we're okay.
 */
gchar *gnc_features_test_unknown (QofBook *book)
{
    KvpFrame *frame = qof_book_get_slots (book);
    KvpValue *value;

    /* Setup the known_features hash table */
    gnc_features_init();

    g_assert(frame);
    value = kvp_frame_get_value(frame, "features");

    if (value)
    {
        GList* features_list = NULL;
        frame = kvp_value_get_frame(value);
        g_assert(frame);

        /* Iterate over the members of this frame for unknown features */
        kvp_frame_for_each_slot(frame, &gnc_features_test_one, &features_list);
        if (features_list)
        {
            GList *i;
            char* msg = g_strdup(
                            _("This Dataset contains features not supported by this "
                              "version of GnuCash.  You must use a newer version of "
                              "GnuCash in order to support the following features:"
                             ));

            for (i = features_list; i; i = i->next)
            {
                char *tmp = g_strconcat(msg, "\n* ", i->data, NULL);
                g_free (msg);
                msg = tmp;
            }

            g_list_free(features_list);
            return msg;
        }
    }

    return NULL;
}
Beispiel #8
0
KvpValue *
kvp_frame_get_slot_path_gslist (KvpFrame *frame,
                                const GSList *key_path)
{
    if (!frame || !key_path) return NULL;

    while (TRUE)
    {
        const char *key = static_cast<const char*>(key_path->data);
        KvpValue *value;

        if (!key) break;

        value = kvp_frame_get_slot (frame, key);
        if (!value) break;

        key_path = key_path->next;
        if (!key_path) return value;

        frame = kvp_value_get_frame (value);
        if (!frame) break;
    }
    return NULL;
}
Beispiel #9
0
gchar*
kvp_value_to_string(const KvpValue *val)
{
    gchar *tmp1;
    gchar *tmp2;
    const gchar *ctmp;

    g_return_val_if_fail(val, NULL);

    switch (kvp_value_get_type(val))
    {
    case KVP_TYPE_GINT64:
        return g_strdup_printf("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
                               kvp_value_get_gint64(val));
        break;

    case KVP_TYPE_DOUBLE:
        return g_strdup_printf("KVP_VALUE_DOUBLE(%g)",
                               kvp_value_get_double(val));
        break;

    case KVP_TYPE_NUMERIC:
        tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val));
        tmp2 = g_strdup_printf("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_STRING:
        tmp1 = kvp_value_get_string (val);
        return g_strdup_printf("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
        break;

    case KVP_TYPE_GUID:
        gchar guidstr[GUID_ENCODING_LENGTH+1];
        guid_to_string_buff(kvp_value_get_guid(val),guidstr);
        tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr);
        return tmp2;
        break;

    case KVP_TYPE_TIMESPEC:
        tmp1 = g_new0 (char, 40);
        gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
        tmp2 = g_strdup_printf("KVP_VALUE_TIMESPEC(%s)", tmp1);
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_BINARY:
    {
        guint64 len;
        void *data;
        data = kvp_value_get_binary(val, &len);
        tmp1 = binary_to_string(data, len);
        return g_strdup_printf("KVP_VALUE_BINARY(%s)", tmp1 ? tmp1 : "");
    }
    break;

    case KVP_TYPE_GLIST:
        tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
        tmp2 = g_strdup_printf("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_FRAME:
        tmp1 = kvp_frame_to_string(kvp_value_get_frame(val));
        tmp2 = g_strdup_printf("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_GDATE:
        return g_strdup_printf("KVP_VALUE_GDATE(%04d-%02d-%02d)",
                               g_date_get_year(&val->value.gdate),
                               g_date_get_month(&val->value.gdate),
                               g_date_get_day(&val->value.gdate));
    default:
	break;
    }
    g_assert(FALSE); /* must not be reached */
    return g_strdup("");
}
Beispiel #10
0
static void
save_slot( const gchar* key, KvpValue* value, gpointer data )
{
    slot_info_t* pSlot_info = (slot_info_t*)data;
    gsize curlen;

    g_return_if_fail( key != NULL );
    g_return_if_fail( value != NULL );
    g_return_if_fail( data != NULL );

    // Ignore if we've already run into a failure
    if ( !pSlot_info->is_ok )
    {
        return;
    }

    curlen = pSlot_info->path->len;
    pSlot_info->pKvpValue = value;
    if ( curlen != 0 )
    {
        (void)g_string_append( pSlot_info->path, "/" );
    }
    (void)g_string_append( pSlot_info->path, key );
    pSlot_info->value_type = kvp_value_get_type( value );

    switch ( pSlot_info->value_type )
    {
    case KVP_TYPE_FRAME:
    {
        KvpFrame* pKvpFrame = kvp_value_get_frame( value );
        GncGUID guid = guid_new_return();
        slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid );
        KvpValue *oldValue = pSlot_info->pKvpValue;
        pSlot_info->pKvpValue = kvp_value_new_guid( &guid );
        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
                            OP_DB_INSERT, TABLE_NAME,
                            TABLE_NAME, pSlot_info,
                            col_table );
        g_return_if_fail( pSlot_info->is_ok );
        kvp_frame_for_each_slot( pKvpFrame, save_slot, pNewInfo );
        kvp_value_delete( pSlot_info->pKvpValue );
        pSlot_info->pKvpValue = oldValue;
        g_string_free( pNewInfo->path, TRUE );
        g_slice_free( slot_info_t, pNewInfo );
    }
    break;
    case KVP_TYPE_GLIST:
    {
        GList *cursor;
        GncGUID guid = guid_new_return();
        slot_info_t *pNewInfo = slot_info_copy( pSlot_info, &guid );
        KvpValue *oldValue = pSlot_info->pKvpValue;
        pSlot_info->pKvpValue = kvp_value_new_guid( &guid );
        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
                            OP_DB_INSERT, TABLE_NAME,
                            TABLE_NAME, pSlot_info,
                            col_table );
        g_return_if_fail( pSlot_info->is_ok );
        for (cursor = kvp_value_get_glist(value); cursor; cursor = cursor->next)
        {
            kvp_value *val = (kvp_value*)cursor->data;
            save_slot("", val, pNewInfo);
        }
        kvp_value_delete( pSlot_info->pKvpValue );
        pSlot_info->pKvpValue = oldValue;
        g_string_free( pNewInfo->path, TRUE );
        g_slice_free( slot_info_t, pNewInfo );
    }
    break;
    default:
    {
        pSlot_info->is_ok = gnc_sql_do_db_operation( pSlot_info->be,
                            OP_DB_INSERT, TABLE_NAME,
                            TABLE_NAME, pSlot_info,
                            col_table );
    }
    break;
    }

    (void)g_string_truncate( pSlot_info->path, curlen );
}
static void
add_kvp_value_node(xmlNodePtr node, gchar *tag, kvp_value* val)
{
    xmlNodePtr val_node;
    gchar *tmp_str1;
    kvp_value_t kvp_type;

    kvp_type = kvp_value_get_type(val);

    if (kvp_type == KVP_TYPE_STRING)
        val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, BAD_CAST kvp_value_get_string(val));
    else if (kvp_type == KVP_TYPE_TIMESPEC)
        val_node = NULL;
    else if (kvp_type == KVP_TYPE_GDATE)
    {
        GDate d = kvp_value_get_gdate(val);
        val_node = gdate_to_dom_tree(tag, &d);
        xmlAddChild (node, val_node);
    }
    else
        val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, NULL);

    switch (kvp_value_get_type(val))
    {
    case KVP_TYPE_GINT64:
        add_text_to_node(val_node, "integer",
                         g_strdup_printf("%" G_GINT64_FORMAT,
                                         kvp_value_get_gint64(val)));
        break;
    case KVP_TYPE_DOUBLE:
        add_text_to_node(val_node, "double",
                         double_to_string(kvp_value_get_double(val)));
        break;
    case KVP_TYPE_NUMERIC:
        add_text_to_node(val_node, "numeric",
                         gnc_numeric_to_string(kvp_value_get_numeric(val)));
        break;
    case KVP_TYPE_STRING:
        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string");
        break;
    case KVP_TYPE_GUID:
        /* THREAD-UNSAFE */
        add_text_to_node(val_node, "guid",
                         g_strdup(guid_to_string(kvp_value_get_guid(val))));
        break;
    case KVP_TYPE_TIMESPEC:
    {
        Timespec ts = kvp_value_get_timespec (val);

        val_node = timespec_to_dom_tree (tag, &ts);
        xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec");
        xmlAddChild (node, val_node);
    }
    break;
    case KVP_TYPE_GDATE:
        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "gdate");
        break;
    case KVP_TYPE_BINARY:
    {
        guint64 size;
        void *binary_data = kvp_value_get_binary(val, &size);
        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "binary");
        g_return_if_fail(binary_data);
        tmp_str1 = binary_to_string(binary_data, size);
        xmlNodeSetContent(val_node, BAD_CAST tmp_str1);
        g_free(tmp_str1);
    }
    break;
    case KVP_TYPE_GLIST:
    {
        GList *cursor;

        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "list");
        for (cursor = kvp_value_get_glist(val); cursor; cursor = cursor->next)
        {
            kvp_value *val = (kvp_value*)cursor->data;
            add_kvp_value_node(val_node, "slot:value", val);
        }
    }

    break;
    case KVP_TYPE_FRAME:
    {
        kvp_frame *frame;

        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "frame");

        frame = kvp_value_get_frame (val);
        if (!frame || !kvp_frame_get_hash (frame))
            break;

        g_hash_table_foreach_sorted(kvp_frame_get_hash(frame),
                                    add_kvp_slot, val_node, (GCompareFunc)strcmp);
    }
    break;

    }
}
Beispiel #12
0
static void
add_kvp_value_node(xmlNodePtr node, gchar *tag, KvpValue* val)
{
    xmlNodePtr val_node;
    kvp_value_t kvp_type;

    kvp_type = kvp_value_get_type(val);

    if (kvp_type == KVP_TYPE_STRING)
    {
	gchar *newstr = g_strdup (kvp_value_get_string(val));
        val_node = xmlNewTextChild(node, NULL, BAD_CAST tag,
				   checked_char_cast (newstr));
	g_free (newstr);
    }
    else if (kvp_type == KVP_TYPE_TIMESPEC)
        val_node = NULL;
    else if (kvp_type == KVP_TYPE_GDATE)
    {
        GDate d = kvp_value_get_gdate(val);
        val_node = gdate_to_dom_tree(tag, &d);
        xmlAddChild (node, val_node);
    }
    else
        val_node = xmlNewTextChild(node, NULL, BAD_CAST tag, NULL);

    switch (kvp_value_get_type(val))
    {
    case KVP_TYPE_GINT64:
        add_text_to_node(val_node, "integer",
                         g_strdup_printf("%" G_GINT64_FORMAT,
                                         kvp_value_get_gint64(val)));
        break;
    case KVP_TYPE_DOUBLE:
        add_text_to_node(val_node, "double",
                         double_to_string(kvp_value_get_double(val)));
        break;
    case KVP_TYPE_NUMERIC:
        add_text_to_node(val_node, "numeric",
                         gnc_numeric_to_string(kvp_value_get_numeric(val)));
        break;
    case KVP_TYPE_STRING:
        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "string");
        break;
    case KVP_TYPE_GUID:
    {
        gchar guidstr[GUID_ENCODING_LENGTH+1];
        guid_to_string_buff(kvp_value_get_guid(val), guidstr);
        add_text_to_node(val_node, "guid", guidstr);
        break;
    }
    case KVP_TYPE_TIMESPEC:
    {
        Timespec ts = kvp_value_get_timespec (val);

        val_node = timespec_to_dom_tree (tag, &ts);
        xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec");
        xmlAddChild (node, val_node);
    }
    break;
    case KVP_TYPE_GDATE:
        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "gdate");
    break;
    case KVP_TYPE_GLIST:
    {
        GList *cursor;

        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "list");
        for (cursor = kvp_value_get_glist(val); cursor; cursor = cursor->next)
        {
            KvpValue *val = (KvpValue*)cursor->data;
            add_kvp_value_node(val_node, "slot:value", val);
        }
    }

    break;
    case KVP_TYPE_FRAME:
    {
        KvpFrame *frame;
        const char ** keys;
        unsigned int i;

        xmlSetProp(val_node, BAD_CAST "type", BAD_CAST "frame");

        frame = kvp_value_get_frame (val);
        if (!frame)
            break;

        keys = kvp_frame_get_keys(frame);
        for (i = 0; keys[i]; ++i)
            add_kvp_slot(keys[i], kvp_frame_get_value(frame, keys[i]), val_node);
        g_free(keys);
    }
    break;
    default:
	break;
    }
}