int ff_ape_write_tag(AVFormatContext *s) { AVDictionaryEntry *e = NULL; int64_t start, end; int size, count = 0; if (!s->pb->seekable) return 0; start = avio_tell(s->pb); // header avio_write(s->pb, "APETAGEX", 8); // id avio_wl32 (s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, 0); // reserve space for size avio_wl32(s->pb, 0); // reserve space for tag count // flags avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER | APE_TAG_FLAG_IS_HEADER); ffio_fill(s->pb, 0, 8); // reserved while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) { int val_len; if (!string_is_ascii(e->key)) { av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n"); continue; } val_len = strlen(e->value); avio_wl32(s->pb, val_len); // value length avio_wl32(s->pb, 0); // item flags avio_put_str(s->pb, e->key); // key avio_write(s->pb, e->value, val_len); // value count++; } size = avio_tell(s->pb) - start; // footer avio_write(s->pb, "APETAGEX", 8); // id avio_wl32 (s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, size); // size avio_wl32(s->pb, count); // tag count // flags avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER); ffio_fill(s->pb, 0, 8); // reserved // update values in the header end = avio_tell(s->pb); avio_seek(s->pb, start + 12, SEEK_SET); avio_wl32(s->pb, size); avio_wl32(s->pb, count); avio_seek(s->pb, end, SEEK_SET); return 0; }
int ff_ape_write_tag(AVFormatContext *s) { AVDictionaryEntry *e = NULL; int size, ret, count = 0; AVIOContext *dyn_bc = NULL; uint8_t *dyn_buf = NULL; if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0) goto end; // flags avio_wl32(dyn_bc, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER | APE_TAG_FLAG_IS_HEADER); ffio_fill(dyn_bc, 0, 8); // reserved ff_standardize_creation_time(s); while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) { int val_len; if (!string_is_ascii(e->key)) { av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n"); continue; } val_len = strlen(e->value); avio_wl32(dyn_bc, val_len); // value length avio_wl32(dyn_bc, 0); // item flags avio_put_str(dyn_bc, e->key); // key avio_write(dyn_bc, e->value, val_len); // value count++; } if (!count) goto end; size = avio_close_dyn_buf(dyn_bc, &dyn_buf); if (size <= 0) goto end; size += 20; // header avio_write(s->pb, "APETAGEX", 8); // id avio_wl32(s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, size); avio_wl32(s->pb, count); avio_write(s->pb, dyn_buf, size - 20); // footer avio_write(s->pb, "APETAGEX", 8); // id avio_wl32(s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, size); // size avio_wl32(s->pb, count); // tag count // flags avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER); ffio_fill(s->pb, 0, 8); // reserved end: if (dyn_bc && !dyn_buf) avio_close_dyn_buf(dyn_bc, &dyn_buf); av_freep(&dyn_buf); return ret; }
/* * Helper function for pgp_armor. Converts arrays of keys and values into * plain C arrays, and checks that they don't contain invalid characters. */ static int parse_key_value_arrays(ArrayType *key_array, ArrayType *val_array, char ***p_keys, char ***p_values) { int nkdims = ARR_NDIM(key_array); int nvdims = ARR_NDIM(val_array); char **keys, **values; Datum *key_datums, *val_datums; bool *key_nulls, *val_nulls; int key_count, val_count; int i; if (nkdims > 1 || nkdims != nvdims) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("wrong number of array subscripts"))); if (nkdims == 0) return 0; deconstruct_array(key_array, TEXTOID, -1, false, 'i', &key_datums, &key_nulls, &key_count); deconstruct_array(val_array, TEXTOID, -1, false, 'i', &val_datums, &val_nulls, &val_count); if (key_count != val_count) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("mismatched array dimensions"))); keys = (char **) palloc(sizeof(char *) * key_count); values = (char **) palloc(sizeof(char *) * val_count); for (i = 0; i < key_count; i++) { char *v; /* Check that the key doesn't contain anything funny */ if (key_nulls[i]) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("null value not allowed for header key"))); v = TextDatumGetCString(key_datums[i]); if (!string_is_ascii(v)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("header key must not contain non-ASCII characters"))); if (strstr(v, ": ")) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("header key must not contain \": \""))); if (strchr(v, '\n')) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("header key must not contain newlines"))); keys[i] = v; /* And the same for the value */ if (val_nulls[i]) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("null value not allowed for header value"))); v = TextDatumGetCString(val_datums[i]); if (!string_is_ascii(v)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("header value must not contain non-ASCII characters"))); if (strchr(v, '\n')) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("header value must not contain newlines"))); values[i] = v; } *p_keys = keys; *p_values = values; return key_count; }