GError * gridd_client_exec_and_decode (const gchar *to, gdouble seconds, GByteArray *req, GSList **out, body_decoder_f decode) { GByteArray ** bodies = NULL; GError *err = gridd_client_exec4 (to, seconds, req, (out && decode) ? &bodies : NULL); if (err) { metautils_gba_cleanv (bodies); return err; } if (out && decode && bodies) { GSList *items = NULL; for (GByteArray **pbody=bodies; *pbody && !err ;pbody++) { GByteArray *body = *pbody; if (!body->data || body->len<=0) continue; GSList *l = NULL; if (!decode(&l, body->data, body->len, &err)) { g_prefix_error (&err, "Decoding error: "); break; } if (l) items = metautils_gslist_precat (items, l); } *out = items; items = NULL; } metautils_gba_cleanv (bodies); return err; }
GError * metautils_unpack_bodyv (GByteArray **bodyv, GSList **result, body_decoder_f decoder) { GError *err = NULL; GSList *items = NULL; for (GByteArray **p=bodyv; *p && !err ;++p) { GSList *l = NULL; if (!decoder (&l, (*p)->data, (*p)->len, NULL)) err = NEWERROR (CODE_PROXY_ERROR, "Bad payload from service"); else items = metautils_gslist_precat (items, l); } *result = items; return err; }
static GError* _list (const char *target, GByteArray *request, struct list_result_s *out, gchar ***out_properties) { GError *err = NULL; GTree *props = NULL; gboolean _cb(gpointer ctx, MESSAGE reply) { (void) ctx; /* Extract replied aliases */ GSList *l = NULL; GError *e = metautils_message_extract_body_encoded(reply, FALSE, &l, bean_sequence_decoder); if (e) { GRID_DEBUG("Callback error : %s", e->message); err = e; return FALSE; } out->beans = metautils_gslist_precat (out->beans, l); /* Extract list flags */ e = metautils_message_extract_boolean (reply, NAME_MSGKEY_TRUNCATED, FALSE, &out->truncated); if (e) g_clear_error (&e); gchar *tok = NULL; tok = metautils_message_extract_string_copy (reply, NAME_MSGKEY_NEXTMARKER); oio_str_reuse (&out->next_marker, tok); /* Extract properties and merge them into the temporary TreeSet. */ if (out_properties) { gchar **names = metautils_message_get_field_names (reply); for (gchar **n=names ; n && *n ;++n) { if (!g_str_has_prefix (*n, NAME_MSGKEY_PREFIX_PROPERTY)) continue; g_tree_replace (props, g_strdup((*n) + sizeof(NAME_MSGKEY_PREFIX_PROPERTY) - 1), metautils_message_extract_string_copy(reply, *n)); } if (names) g_strfreev (names); } return TRUE; }
static gssize abstract_sequence_unmarshall(const struct abstract_sequence_handler_s *h, GSList ** list, const void *asn1_encoded, gsize asn1_encoded_size, GError ** err) { gssize consumed; void *result = NULL; gint i = 0, max = 0; asn_dec_rval_t decRet; struct anonymous_sequence_s *abstract_sequence; GSList *api_result = NULL; void func_free(void *d) { if (!d) return; h->clean_ASN1(d, FALSE); } if (!asn1_encoded || !list) { GSETERROR(err, "Invalid parameter"); return -1; } asn_codec_ctx_t codecCtx = {0}; codecCtx.max_stack_size = ASN1C_MAX_STACK; decRet = ber_decode(&codecCtx, h->asn1_descriptor, &(result), asn1_encoded, asn1_encoded_size); switch (decRet.code) { case RC_OK: abstract_sequence = (struct anonymous_sequence_s *) result; /*fill the list with the content of the array */ for (i = 0, max = abstract_sequence->list.count; i < max; i++) { void *api_structure; api_structure = g_malloc0(h->api_size); if (!h->map_ASN1_to_API(abstract_sequence->list.array[i], api_structure)) { GSETERROR(err,"Element of type [%s] ASN-to-API conversion error", h->type_name); if (api_structure) h->clean_API(api_structure); abstract_sequence->list.free = &func_free; asn_set_empty(abstract_sequence); free(abstract_sequence); abstract_sequence = NULL; if (api_result) { g_slist_foreach(api_result, api_gclean, h->clean_API); g_slist_free(api_result); } return -1; } api_result = g_slist_prepend(api_result, api_structure); } abstract_sequence->list.free = &func_free; asn_set_empty(abstract_sequence); free(abstract_sequence); abstract_sequence = NULL; *list = metautils_gslist_precat(*list, api_result); consumed = decRet.consumed; return consumed; case RC_FAIL: GSETERROR(err, "sequence unmarshalling error (%"G_GSIZE_FORMAT" consumed)", decRet.consumed); return -1; case RC_WMORE: GSETERROR(err, "sequence unmarshalling error (uncomplete)"); return 0; default: GSETERROR(err, "Serialisation produced an unknow return code : %d", decRet.code); return -1; } return -1; }