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 static int 29 write_array_value(avro_writer_t writer, avro_value_t *src) 30 { 31 int rval; 32 size_t element_count; 33 check(rval, avro_value_get_size(src, &element_count)); 34 35 if (element_count > 0) { 36 check_prefix(rval, avro_binary_encoding.write_long 37 (writer, element_count), 38 "Cannot write array block count: "); 39 40 size_t i; 41 for (i = 0; i < element_count; i++) { 42 avro_value_t child; 43 check(rval, avro_value_get_by_index(src, i, &child, NULL)); 44 check(rval, avro_value_write(writer, &child)); 45 } 46 } 47 48 check_prefix(rval, avro_binary_encoding.write_long(writer, 0), 49 "Cannot write array block count: "); 50 return 0; 51 } 52 53 54 static int 55 write_map_value(avro_writer_t writer, avro_value_t *src) 56 { 57 int rval; 58 size_t element_count; 59 check(rval, avro_value_get_size(src, &element_count)); 60 61 if (element_count > 0) { 62 check_prefix(rval, avro_binary_encoding.write_long 63 (writer, element_count), 64 "Cannot write map block count: "); 65 66 size_t i; 67 for (i = 0; i < element_count; i++) { 68 avro_value_t child; 69 const char *key; 70 check(rval, avro_value_get_by_index(src, i, &child, &key)); 71 check(rval, avro_binary_encoding.write_string(writer, key)); 72 check(rval, avro_value_write(writer, &child)); 73 } 74 } 75 76 check_prefix(rval, avro_binary_encoding.write_long(writer, 0), 77 "Cannot write map block count: "); 78 return 0; 79 } 80 81 static int 82 write_record_value(avro_writer_t writer, avro_value_t *src) 83 { 84 int rval; 85 size_t field_count; 86 check(rval, avro_value_get_size(src, &field_count)); 87 88 size_t i; 89 for (i = 0; i < field_count; i++) { 90 avro_value_t field; 91 check(rval, avro_value_get_by_index(src, i, &field, NULL)); 92 check(rval, avro_value_write(writer, &field)); 93 } 94 95 return 0; 96 } 97 98 static int 99 write_union_value(avro_writer_t writer, avro_value_t *src) 100 { 101 int rval; 102 int discriminant; 103 avro_value_t branch; 104 105 check(rval, avro_value_get_discriminant(src, &discriminant)); 106 check(rval, avro_value_get_current_branch(src, &branch)); 107 check(rval, avro_binary_encoding.write_long(writer, discriminant)); 108 return avro_value_write(writer, &branch); 109 } 110 111 int 112 avro_value_write(avro_writer_t writer, avro_value_t *src) 113 { 114 int rval; 115 116 switch (avro_value_get_type(src)) { 117 case AVRO_BOOLEAN: 118 { 119 int val; 120 check(rval, avro_value_get_boolean(src, &val)); 121 return avro_binary_encoding.write_boolean(writer, val); 122 } 123 124 case AVRO_BYTES: 125 { 126 const void *buf; 127 size_t size; 128 check(rval, avro_value_get_bytes(src, &buf, &size)); 129 return avro_binary_encoding.write_bytes(writer, (const char *) buf, size); 130 } 131 132 case AVRO_DOUBLE: 133 { 134 double val; 135 check(rval, avro_value_get_double(src, &val)); 136 return avro_binary_encoding.write_double(writer, val); 137 } 138 139 case AVRO_FLOAT: 140 { 141 float val; 142 check(rval, avro_value_get_float(src, &val)); 143 return avro_binary_encoding.write_float(writer, val); 144 } 145 146 case AVRO_INT32: 147 { 148 int32_t val; 149 check(rval, avro_value_get_int(src, &val)); 150 return avro_binary_encoding.write_long(writer, val); 151 } 152 153 case AVRO_INT64: 154 { 155 int64_t val; 156 check(rval, avro_value_get_long(src, &val)); 157 return avro_binary_encoding.write_long(writer, val); 158 } 159 160 case AVRO_NULL: 161 { 162 check(rval, avro_value_get_null(src)); 163 return avro_binary_encoding.write_null(writer); 164 } 165 166 case AVRO_STRING: 167 { 168 const char *str; 169 size_t size; 170 check(rval, avro_value_get_string(src, &str, &size)); 171 return avro_binary_encoding.write_bytes(writer, str, size-1); 172 } 173 174 case AVRO_ARRAY: 175 return write_array_value(writer, src); 176 177 case AVRO_ENUM: 178 { 179 int val; 180 check(rval, avro_value_get_enum(src, &val)); 181 return avro_binary_encoding.write_long(writer, val); 182 } 183 184 case AVRO_FIXED: 185 { 186 const void *buf; 187 size_t size; 188 check(rval, avro_value_get_fixed(src, &buf, &size)); 189 return avro_write(writer, (void *) buf, size); 190 } 191 192 case AVRO_MAP: 193 return write_map_value(writer, src); 194 195 case AVRO_RECORD: 196 return write_record_value(writer, src); 197 198 case AVRO_UNION: 199 return write_union_value(writer, src); 200 201 default: 202 { 203 avro_set_error("Unknown schema type"); 204 return EINVAL; 205 } 206 } 207 208 return 0; 209 } 210