1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to you under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 */
17
18 #include <avro/platform.h>
19 #include <stdlib.h>
20
21 #include "avro/basics.h"
22 #include "avro/io.h"
23 #include "avro/value.h"
24 #include "avro_private.h"
25 #include "encoding.h"
26
27
28 /*
29 * Forward declaration; this is basically the same as avro_value_sizeof,
30 * but it doesn't initialize size first. (Since it will have already
31 * been initialized in avro_value_sizeof itself).
32 */
33
34 static int
35 sizeof_value(avro_value_t *src, size_t *size);
36
37
38 static int
sizeof_array_value(avro_value_t * src,size_t * size)39 sizeof_array_value(avro_value_t *src, size_t *size)
40 {
41 int rval;
42 size_t element_count;
43 check(rval, avro_value_get_size(src, &element_count));
44
45 if (element_count > 0) {
46 *size += avro_binary_encoding.size_long(NULL, element_count);
47
48 size_t i;
49 for (i = 0; i < element_count; i++) {
50 avro_value_t child;
51 check(rval, avro_value_get_by_index(src, i, &child, NULL));
52 check(rval, sizeof_value(&child, size));
53 }
54 }
55
56 *size += avro_binary_encoding.size_long(NULL, 0);
57 return 0;
58 }
59
60
61 static int
sizeof_map_value(avro_value_t * src,size_t * size)62 sizeof_map_value(avro_value_t *src, size_t *size)
63 {
64 int rval;
65 size_t element_count;
66 check(rval, avro_value_get_size(src, &element_count));
67
68 if (element_count > 0) {
69 *size += avro_binary_encoding.size_long(NULL, element_count);
70
71 size_t i;
72 for (i = 0; i < element_count; i++) {
73 avro_value_t child;
74 const char *key;
75 check(rval, avro_value_get_by_index(src, i, &child, &key));
76 *size += avro_binary_encoding.size_string(NULL, key);
77 check(rval, sizeof_value(&child, size));
78 }
79 }
80
81 *size += avro_binary_encoding.size_long(NULL, 0);
82 return 0;
83 }
84
85 static int
sizeof_record_value(avro_value_t * src,size_t * size)86 sizeof_record_value(avro_value_t *src, size_t *size)
87 {
88 int rval;
89 size_t field_count;
90 check(rval, avro_value_get_size(src, &field_count));
91
92 size_t i;
93 for (i = 0; i < field_count; i++) {
94 avro_value_t field;
95 check(rval, avro_value_get_by_index(src, i, &field, NULL));
96 check(rval, sizeof_value(&field, size));
97 }
98
99 return 0;
100 }
101
102 static int
sizeof_union_value(avro_value_t * src,size_t * size)103 sizeof_union_value(avro_value_t *src, size_t *size)
104 {
105 int rval;
106 int discriminant;
107 avro_value_t branch;
108
109 check(rval, avro_value_get_discriminant(src, &discriminant));
110 check(rval, avro_value_get_current_branch(src, &branch));
111 *size += avro_binary_encoding.size_long(NULL, discriminant);
112 return sizeof_value(&branch, size);
113 }
114
115 static int
sizeof_value(avro_value_t * src,size_t * size)116 sizeof_value(avro_value_t *src, size_t *size)
117 {
118 int rval;
119
120 switch (avro_value_get_type(src)) {
121 case AVRO_BOOLEAN:
122 {
123 int val;
124 check(rval, avro_value_get_boolean(src, &val));
125 *size += avro_binary_encoding.size_boolean(NULL, val);
126 return 0;
127 }
128
129 case AVRO_BYTES:
130 {
131 const void *buf;
132 size_t sz;
133 check(rval, avro_value_get_bytes(src, &buf, &sz));
134 *size += avro_binary_encoding.size_bytes(NULL, (const char *) buf, sz);
135 return 0;
136 }
137
138 case AVRO_DOUBLE:
139 {
140 double val;
141 check(rval, avro_value_get_double(src, &val));
142 *size += avro_binary_encoding.size_double(NULL, val);
143 return 0;
144 }
145
146 case AVRO_FLOAT:
147 {
148 float val;
149 check(rval, avro_value_get_float(src, &val));
150 *size += avro_binary_encoding.size_float(NULL, val);
151 return 0;
152 }
153
154 case AVRO_INT32:
155 {
156 int32_t val;
157 check(rval, avro_value_get_int(src, &val));
158 *size += avro_binary_encoding.size_long(NULL, val);
159 return 0;
160 }
161
162 case AVRO_INT64:
163 {
164 int64_t val;
165 check(rval, avro_value_get_long(src, &val));
166 *size += avro_binary_encoding.size_long(NULL, val);
167 return 0;
168 }
169
170 case AVRO_NULL:
171 {
172 check(rval, avro_value_get_null(src));
173 *size += avro_binary_encoding.size_null(NULL);
174 return 0;
175 }
176
177 case AVRO_STRING:
178 {
179 const char *str;
180 size_t sz;
181 check(rval, avro_value_get_string(src, &str, &sz));
182 *size += avro_binary_encoding.size_bytes(NULL, str, sz-1);
183 return 0;
184 }
185
186 case AVRO_ARRAY:
187 return sizeof_array_value(src, size);
188
189 case AVRO_ENUM:
190 {
191 int val;
192 check(rval, avro_value_get_enum(src, &val));
193 *size += avro_binary_encoding.size_long(NULL, val);
194 return 0;
195 }
196
197 case AVRO_FIXED:
198 {
199 size_t sz;
200 check(rval, avro_value_get_fixed(src, NULL, &sz));
201 *size += sz;
202 return 0;
203 }
204
205 case AVRO_MAP:
206 return sizeof_map_value(src, size);
207
208 case AVRO_RECORD:
209 return sizeof_record_value(src, size);
210
211 case AVRO_UNION:
212 return sizeof_union_value(src, size);
213
214 default:
215 {
216 avro_set_error("Unknown schema type");
217 return EINVAL;
218 }
219 }
220
221 return 0;
222 }
223
224 int
avro_value_sizeof(avro_value_t * src,size_t * size)225 avro_value_sizeof(avro_value_t *src, size_t *size)
226 {
227 check_param(EINVAL, size, "size pointer");
228 *size = 0;
229 return sizeof_value(src, size);
230 }
231