| | 337 | } |
| | 338 | |
| | 339 | /* |
| | 340 | * Create a new emitter object. |
| | 341 | */ |
| | 342 | |
| | 343 | YAML_DECLARE(int) |
| | 344 | yaml_emitter_initialize(yaml_emitter_t *emitter) |
| | 345 | { |
| | 346 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 347 | |
| | 348 | memset(emitter, 0, sizeof(yaml_emitter_t)); |
| | 349 | if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE)) |
| | 350 | goto error; |
| | 351 | if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE)) |
| | 352 | goto error; |
| | 353 | if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE)) |
| | 354 | goto error; |
| | 355 | if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE)) |
| | 356 | goto error; |
| | 357 | if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE)) |
| | 358 | goto error; |
| | 359 | if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE)) |
| | 360 | goto error; |
| | 361 | |
| | 362 | return 1; |
| | 363 | |
| | 364 | error: |
| | 365 | |
| | 366 | BUFFER_DEL(emitter, emitter->buffer); |
| | 367 | BUFFER_DEL(emitter, emitter->raw_buffer); |
| | 368 | STACK_DEL(emitter, emitter->states); |
| | 369 | QUEUE_DEL(emitter, emitter->events); |
| | 370 | STACK_DEL(emitter, emitter->indents); |
| | 371 | STACK_DEL(emitter, emitter->tag_directives); |
| | 372 | |
| | 373 | return 0; |
| | 374 | } |
| | 375 | |
| | 376 | /* |
| | 377 | * Destroy an emitter object. |
| | 378 | */ |
| | 379 | |
| | 380 | YAML_DECLARE(void) |
| | 381 | yaml_emitter_delete(yaml_emitter_t *emitter) |
| | 382 | { |
| | 383 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 384 | |
| | 385 | BUFFER_DEL(emitter, emitter->buffer); |
| | 386 | BUFFER_DEL(emitter, emitter->raw_buffer); |
| | 387 | STACK_DEL(emitter, emitter->states); |
| | 388 | while (!QUEUE_EMPTY(emitter, emitter->events)) { |
| | 389 | yaml_event_delete(&DEQUEUE(emitter, emitter->events)); |
| | 390 | } |
| | 391 | STACK_DEL(emitter, emitter->indents); |
| | 392 | while (!STACK_EMPTY(empty, emitter->tag_directives)) { |
| | 393 | yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); |
| | 394 | yaml_free(tag_directive.handle); |
| | 395 | yaml_free(tag_directive.prefix); |
| | 396 | } |
| | 397 | STACK_DEL(emitter, emitter->tag_directives); |
| | 398 | |
| | 399 | memset(emitter, 0, sizeof(yaml_emitter_t)); |
| | 400 | } |
| | 401 | |
| | 402 | /* |
| | 403 | * String write handler. |
| | 404 | */ |
| | 405 | |
| | 406 | static int |
| | 407 | yaml_string_write_handler(void *data, unsigned char *buffer, size_t size) |
| | 408 | { |
| | 409 | yaml_emitter_t *emitter = data; |
| | 410 | |
| | 411 | if (emitter->output.string.size + *emitter->output.string.size_written |
| | 412 | < size) { |
| | 413 | memcpy(emitter->output.string.buffer |
| | 414 | + *emitter->output.string.size_written, |
| | 415 | buffer, |
| | 416 | emitter->output.string.size |
| | 417 | - *emitter->output.string.size_written); |
| | 418 | *emitter->output.string.size_written = emitter->output.string.size; |
| | 419 | return 0; |
| | 420 | } |
| | 421 | |
| | 422 | memcpy(emitter->output.string.buffer |
| | 423 | + *emitter->output.string.size_written, buffer, size); |
| | 424 | *emitter->output.string.size_written += size; |
| | 425 | return 1; |
| | 426 | } |
| | 427 | |
| | 428 | /* |
| | 429 | * File write handler. |
| | 430 | */ |
| | 431 | |
| | 432 | static int |
| | 433 | yaml_file_write_handler(void *data, unsigned char *buffer, size_t size) |
| | 434 | { |
| | 435 | yaml_emitter_t *emitter = data; |
| | 436 | |
| | 437 | return (fwrite(buffer, 1, size, emitter->output.file) == size); |
| | 438 | } |
| | 439 | /* |
| | 440 | * Set a string output. |
| | 441 | */ |
| | 442 | |
| | 443 | YAML_DECLARE(void) |
| | 444 | yaml_emitter_set_output_string(yaml_emitter_t *emitter, |
| | 445 | unsigned char *output, size_t size, size_t *size_written) |
| | 446 | { |
| | 447 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 448 | assert(!emitter->write_handler); /* You can set the output only once. */ |
| | 449 | assert(output); /* Non-NULL output string expected. */ |
| | 450 | |
| | 451 | emitter->write_handler = yaml_string_write_handler; |
| | 452 | emitter->write_handler_data = emitter; |
| | 453 | |
| | 454 | emitter->output.string.buffer = output; |
| | 455 | emitter->output.string.size = size; |
| | 456 | emitter->output.string.size_written = size_written; |
| | 457 | *size_written = 0; |
| | 458 | } |
| | 459 | |
| | 460 | /* |
| | 461 | * Set a file output. |
| | 462 | */ |
| | 463 | |
| | 464 | YAML_DECLARE(void) |
| | 465 | yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file) |
| | 466 | { |
| | 467 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 468 | assert(!emitter->write_handler); /* You can set the output only once. */ |
| | 469 | assert(file); /* Non-NULL file object expected. */ |
| | 470 | |
| | 471 | emitter->write_handler = yaml_file_write_handler; |
| | 472 | emitter->write_handler_data = emitter; |
| | 473 | |
| | 474 | emitter->output.file = file; |
| | 475 | } |
| | 476 | |
| | 477 | /* |
| | 478 | * Set a generic output handler. |
| | 479 | */ |
| | 480 | |
| | 481 | YAML_DECLARE(void) |
| | 482 | yaml_emitter_set_output(yaml_emitter_t *emitter, |
| | 483 | yaml_write_handler_t *handler, void *data) |
| | 484 | { |
| | 485 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 486 | assert(!emitter->write_handler); /* You can set the output only once. */ |
| | 487 | assert(handler); /* Non-NULL handler object expected. */ |
| | 488 | |
| | 489 | emitter->write_handler = handler; |
| | 490 | emitter->write_handler_data = data; |
| | 491 | } |
| | 492 | |
| | 493 | /* |
| | 494 | * Set the output encoding. |
| | 495 | */ |
| | 496 | |
| | 497 | YAML_DECLARE(void) |
| | 498 | yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) |
| | 499 | { |
| | 500 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 501 | assert(!emitter->encoding); /* You can set encoding only once. */ |
| | 502 | |
| | 503 | emitter->encoding = encoding; |
| | 504 | } |
| | 505 | |
| | 506 | /* |
| | 507 | * Set the canonical output style. |
| | 508 | */ |
| | 509 | |
| | 510 | YAML_DECLARE(void) |
| | 511 | yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical) |
| | 512 | { |
| | 513 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 514 | |
| | 515 | emitter->canonical = (canonical != 0); |
| | 516 | } |
| | 517 | |
| | 518 | /* |
| | 519 | * Set the indentation increment. |
| | 520 | */ |
| | 521 | |
| | 522 | YAML_DECLARE(void) |
| | 523 | yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) |
| | 524 | { |
| | 525 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 526 | |
| | 527 | emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; |
| | 528 | } |
| | 529 | |
| | 530 | /* |
| | 531 | * Set the preferred line width. |
| | 532 | */ |
| | 533 | |
| | 534 | YAML_DECLARE(void) |
| | 535 | yaml_emitter_set_width(yaml_emitter_t *emitter, int width) |
| | 536 | { |
| | 537 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 538 | |
| | 539 | emitter->best_width = (width > 0) ? width : 0; |
| | 540 | } |
| | 541 | |
| | 542 | /* |
| | 543 | * Set if unescaped non-ASCII characters are allowed. |
| | 544 | */ |
| | 545 | |
| | 546 | YAML_DECLARE(void) |
| | 547 | yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode) |
| | 548 | { |
| | 549 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 550 | |
| | 551 | emitter->unicode = (unicode != 0); |
| | 552 | } |
| | 553 | |
| | 554 | /* |
| | 555 | * Set the preferred line break character. |
| | 556 | */ |
| | 557 | |
| | 558 | YAML_DECLARE(void) |
| | 559 | yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) |
| | 560 | { |
| | 561 | assert(emitter); /* Non-NULL emitter object expected. */ |
| | 562 | |
| | 563 | emitter->line_break = line_break; |