1
/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
6
#include "dsync-serializer.h"
7
#include "dsync-deserializer.h"
9
struct dsync_deserializer {
12
const char *const *required_fields;
13
const char *const *keys;
14
unsigned int *required_field_indexes;
15
unsigned int required_field_count;
18
struct dsync_deserializer_decoder {
20
struct dsync_deserializer *deserializer;
21
const char *const *values;
22
unsigned int values_count;
25
static bool field_find(const char *const *names, const char *name,
30
for (i = 0; names[i] != NULL; i++) {
31
if (strcmp(names[i], name) == 0) {
39
int dsync_deserializer_init(const char *name, const char *const *required_fields,
40
const char *header_line,
41
struct dsync_deserializer **deserializer_r,
44
struct dsync_deserializer *deserializer;
45
const char **dup_required_fields;
46
unsigned int i, required_count;
49
*deserializer_r = NULL;
51
pool = pool_alloconly_create("dsync deserializer", 1024);
52
deserializer = p_new(pool, struct dsync_deserializer, 1);
53
deserializer->pool = pool;
54
deserializer->name = p_strdup(pool, name);
55
deserializer->keys = (void *)p_strsplit_tabescaped(pool, header_line);
57
deserializer->required_field_count = required_count =
58
required_fields == NULL ? 0 :
59
str_array_length(required_fields);
60
dup_required_fields = p_new(pool, const char *, required_count + 1);
61
deserializer->required_field_indexes =
62
p_new(pool, unsigned int, required_count + 1);
63
for (i = 0; i < required_count; i++) {
64
dup_required_fields[i] =
65
p_strdup(pool, required_fields[i]);
66
if (!field_find(deserializer->keys, required_fields[i],
67
&deserializer->required_field_indexes[i])) {
68
*error_r = t_strdup_printf(
69
"Header missing required field %s",
75
deserializer->required_fields = dup_required_fields;
77
*deserializer_r = deserializer;
81
void dsync_deserializer_deinit(struct dsync_deserializer **_deserializer)
83
struct dsync_deserializer *deserializer = *_deserializer;
85
*_deserializer = NULL;
87
pool_unref(&deserializer->pool);
90
int dsync_deserializer_decode_begin(struct dsync_deserializer *deserializer,
92
struct dsync_deserializer_decoder **decoder_r,
95
struct dsync_deserializer_decoder *decoder;
102
pool = pool_alloconly_create("dsync deserializer decode", 1024);
103
decoder = p_new(pool, struct dsync_deserializer_decoder, 1);
104
decoder->pool = pool;
105
decoder->deserializer = deserializer;
106
values = p_strsplit_tabescaped(pool, input);
109
for (i = 0; values[i] != NULL; i++) {
110
if (values[i][0] == NULL_CHR) {
112
if (values[i][1] == '\0')
118
decoder->values_count = i;
120
/* see if all required fields exist */
121
for (i = 0; i < deserializer->required_field_count; i++) {
122
unsigned int ridx = deserializer->required_field_indexes[i];
124
if (ridx >= decoder->values_count || values[ridx] == NULL) {
125
*error_r = t_strdup_printf("Missing required field %s",
126
deserializer->required_fields[i]);
131
decoder->values = (void *)values;
133
*decoder_r = decoder;
138
dsync_deserializer_find_field(struct dsync_deserializer *deserializer,
139
const char *key, unsigned int *idx_r)
143
for (i = 0; deserializer->keys[i] != NULL; i++) {
144
if (strcmp(deserializer->keys[i], key) == 0) {
152
bool dsync_deserializer_decode_try(struct dsync_deserializer_decoder *decoder,
153
const char *key, const char **value_r)
157
if (!dsync_deserializer_find_field(decoder->deserializer, key, &idx) ||
158
idx >= decoder->values_count) {
162
*value_r = decoder->values[idx];
163
return *value_r != NULL;
168
dsync_deserializer_decode_get(struct dsync_deserializer_decoder *decoder,
173
if (!dsync_deserializer_decode_try(decoder, key, &value)) {
174
i_panic("dsync_deserializer_decode_get() "
175
"used for non-required key %s", key);
181
dsync_deserializer_decoder_get_name(struct dsync_deserializer_decoder *decoder)
183
return decoder->deserializer->name;
186
void dsync_deserializer_decode_finish(struct dsync_deserializer_decoder **_decoder)
188
struct dsync_deserializer_decoder *decoder = *_decoder;
192
pool_unref(&decoder->pool);