| | 208 | typedef struct { |
| | 209 | IoYAML *self; |
| | 210 | ByteArray *buffer; |
| | 211 | } IoYAMLout; |
| | 212 | |
| | 213 | void |
| | 214 | IoYAML_emitHandler(SyckEmitter *e, st_data_t data) |
| | 215 | { |
| | 216 | IoYAMLout *out = (IoYAMLout *)e->bonus; |
| | 217 | IoYAML *self = out->self; |
| | 218 | IoObject *obj = (IoObject *)data; |
| | 219 | |
| | 220 | if (ISNIL(obj)) |
| | 221 | { |
| | 222 | syck_emit_scalar(e, "null", scalar_none, 0, 0, 0, "", 0); |
| | 223 | } |
| | 224 | else if (ISBOOL(obj)) |
| | 225 | { |
| | 226 | char *bool_s = ISTRUE(obj) ? "true" : "false"; |
| | 227 | syck_emit_scalar(e, "boolean", scalar_none, 0, 0, 0, (char *)bool_s, strlen(bool_s)); |
| | 228 | } |
| | 229 | else if (ISSEQ(obj)) |
| | 230 | { |
| | 231 | syck_emit_scalar(e, "string", scalar_none, 0, 0, 0, (char *)IOSEQ_BYTES(obj), IOSEQ_LENGTH(obj)); |
| | 232 | } |
| | 233 | else if (ISNUMBER(obj)) |
| | 234 | { |
| | 235 | /* should handle floats as well */ |
| | 236 | char buf[30]; /* find a better way, if possible */ |
| | 237 | snprintf(buf, sizeof(buf), "%i", (int)CNUMBER(obj)); |
| | 238 | syck_emit_scalar(e, "number", scalar_none, 0, 0, 0, buf, strlen(buf)); |
| | 239 | } |
| | 240 | else if (ISLIST(obj)) |
| | 241 | { |
| | 242 | syck_emit_seq(e, "seq", seq_none); |
| | 243 | size_t len = IoList_rawSize(obj); |
| | 244 | size_t i = 0; |
| | 245 | for (i = 0; i < len; i++) |
| | 246 | { |
| | 247 | syck_emit_item(e, (st_data_t)IoList_rawAt_(obj, i)); |
| | 248 | } |
| | 249 | syck_emit_end(e); |
| | 250 | } |
| | 251 | else if (ISMAP(obj)) |
| | 252 | { |
| | 253 | syck_emit_map(e, "map", map_none); |
| | 254 | IoList *keys = IoMap_rawKeys(obj); |
| | 255 | size_t len = IoList_rawSize(keys); |
| | 256 | size_t i = 0; |
| | 257 | for (i = 0; i < len; i++) |
| | 258 | { |
| | 259 | IoSymbol *k = IoList_rawAt_(obj, i); |
| | 260 | syck_emit_item(e, (st_data_t)k); |
| | 261 | syck_emit_item(e, (st_data_t)IoMap_rawAt(obj, k)); |
| | 262 | } |
| | 263 | syck_emit_end(e); |
| | 264 | } |
| | 265 | } |
| | 266 | |
| | 267 | void |
| | 268 | IoYAML_outputHandler(SyckEmitter *e, char *str, long len) |
| | 269 | { |
| | 270 | IoYAMLout *out = (IoYAMLout *)e->bonus; |
| | 271 | ByteArray_appendBytes_size_(out->buffer, str, len); |
| | 272 | } |
| | 273 | |
| 209 | | return self; |
| 210 | | } |
| | 276 | ByteArray *buffer = ByteArray_new(); |
| | 277 | IoObject *obj = IoMessage_locals_valueArgAt_(m, locals, 0); |
| | 278 | SyckEmitter *emitter = syck_new_emitter(); |
| | 279 | IoYAMLout *out = S_ALLOC(IoYAMLout); |
| | 280 | out->self = self; |
| | 281 | out->buffer = buffer; |
| | 282 | emitter->bonus = (void *)out; |
| | 283 | |
| | 284 | syck_emitter_handler(emitter, IoYAML_emitHandler); |
| | 285 | syck_output_handler(emitter, IoYAML_outputHandler); |
| | 286 | syck_emit(emitter, (st_data_t)obj); |
| | 287 | syck_emitter_flush(emitter, 0); |
| | 288 | syck_free_emitter(emitter); |
| | 289 | S_FREE(out); |
| | 290 | |
| | 291 | return IoSeq_newWithByteArray_copy_(self->state, buffer, 0); |
| | 292 | } |