diff options
author | xi <xi@18f92427-320e-0410-9341-c67f048884a3> | 2006-05-27 17:19:07 +0000 |
---|---|---|
committer | xi <xi@18f92427-320e-0410-9341-c67f048884a3> | 2006-05-27 17:19:07 +0000 |
commit | 9f2aadeadd713e7d041616d84c3033a822e559bf (patch) | |
tree | 57b669d90579bb58e5b88c21596e45b0f0283c35 | |
parent | 9ffe24228eb6bbd279208671b6ca79371175bc97 (diff) | |
download | libyaml-9f2aadeadd713e7d041616d84c3033a822e559bf.tar.gz |
Implementing Reader: first tries.
git-svn-id: http://svn.pyyaml.org/libyaml/trunk@179 18f92427-320e-0410-9341-c67f048884a3
-rw-r--r-- | include/yaml/yaml.h | 161 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/api.c | 135 | ||||
-rw-r--r-- | src/reader.c | 53 |
4 files changed, 331 insertions, 20 deletions
diff --git a/include/yaml/yaml.h b/include/yaml/yaml.h index 40cd9af..c4bd0ba 100644 --- a/include/yaml/yaml.h +++ b/include/yaml/yaml.h @@ -16,6 +16,8 @@ extern "C" { #endif #include <stdlib.h> +#include <stdio.h> +#include <string.h> /** * @defgroup version Version Information @@ -62,10 +64,7 @@ typedef enum { YAML_UTF16BE_ENCODING } yaml_encoding_t; -/** @} */ - -/* - +/** Many bad things could happen with the parser and emitter. */ typedef enum { YAML_NO_ERROR, @@ -79,6 +78,10 @@ typedef enum { YAML_EMITTER_ERROR } yaml_error_type_t; +/** @} */ + +/* + typedef enum { YAML_ANY_SCALAR_STYLE, YAML_PLAIN_SCALAR_STYLE, @@ -249,19 +252,18 @@ typedef struct { * source. The handler should write not more than @a size bytes to the @a * buffer. The number of written bytes should be set to the @a length variable. * - * @param[in] ext A pointer to an application data specified by - * @c yaml_parser_set_read_handler. - * @param[out] buffer The buffer to write the data from the source. - * @param[in] size The size of the buffer. - * @param[out] length The actual number of bytes read from the source. + * @param[in] ext A pointer to an application data specified by + * @c yaml_parser_set_read_handler. + * @param[out] buffer The buffer to write the data from the source. + * @param[in] size The size of the buffer. + * @param[out] size_read The actual number of bytes read from the source. * * @returns On success, the handler should return @c 1. If the handler failed, * the returned value should be @c 0. On EOF, the handler should set the * @a length to @c 0 and return @c 1. */ -typedef int yaml_read_handler_t(void *ext, yaml_char_t *buffer, size_t size, - size_t *length); - +typedef int yaml_read_handler_t(void *ext, unsigned char *buffer, size_t size, + size_t *size_read); /** * The parser structure. @@ -273,15 +275,26 @@ typedef int yaml_read_handler_t(void *ext, yaml_char_t *buffer, size_t size, typedef struct { /** + * @name Error handling + * @{ + */ + + error_type_t error; + + /** + * @} + */ + + /** * @name Reader stuff * @{ */ /** Read handler */ - yaml_read_handler_t *reader; + yaml_read_handler_t *read_handler; /** A pointer for passing to the read handler. */ - void *reader_ext; + void *read_handler_data; /** EOF flag */ int eof; @@ -289,18 +302,39 @@ typedef struct { /** The pointer to the beginning of the working buffer. */ yaml_char_t *buffer; + /** The size of the buffer (in bytes). */ + size_t buffer_size; + /** The pointer to the current character in the working buffer. */ - yaml_char_t *pointer; + yaml_char_t *buffer_pointer; + + /** The number of unread characters in the buffer (in characters). */ + size_t buffer_length; /** The remaining undecoded characters. */ unsigned char *raw_buffer; - /** The size of the raw buffer. */ + /** The size of the raw buffer (in bytes). */ size_t raw_buffer_size; + /** Is the application responsible for freeing the raw buffer? */ + int raw_buffer_foreign; + /** The input encoding. */ yaml_encoding_t encoding; + /** The offset of the current position (in bytes). */ + size_t offset; + + /** The index of the current position (in characters). */ + size_t index; + + /** The line of the current position (starting from @c 0). */ + size_t line; + + /** The column of the current position (starting from @c 0). */ + size_t column; + /** * @} */ @@ -328,6 +362,57 @@ yaml_parser_new(void); void yaml_parser_delete(yaml_parser_t *parser); +/** + * Set a string input. + * + * Note that the @a input pointer must be valid while the @a parser object + * exists. The application is responsible for destroing @a input after + * destroying the @a parser. + * + * @param[in] parser A parser object. + * @param[in] input A source data. + * @param[in] length The length of the source data in bytes. + */ + +void +yaml_parser_set_input_string(yaml_parser_t *parser, + unsigned char *input, size_t size); + + +/** + * Set a file input. + * + * @a file should be a file object open for reading. The application is + * responsible for closing the @a file. + * + * @param[in] parser A parser object. + * @param[in] file An open file. + */ + +void +yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file); + +/** + * Set a generic input handler. + * + * @param[in] parser A parser object. + * @param[in] handler A read handler. + * @param[in] data Any application data for passing to the read handler. + */ + +void +yaml_parser_set_input(yaml_parser_t *parser, + yaml_read_handler_t *handler, void *data); + +/** + * Set the source encoding. + * + * @param[in] encoding The source encoding. + */ + +void +yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding); + /** @} */ /* @@ -335,6 +420,50 @@ typedef struct { } yaml_emitter_t; */ +/** + * @defgroup internal Internal Definitions + * @{ + */ + +/** + * Allocate a dynamic memory block. + * + * @param[in] size Size of a memory block, \c 0 is valid. + * + * @returns @c yaml_malloc returns a pointer to a newly allocated memory block, + * or @c NULL if it failed. + */ + +void * +yaml_malloc(size_t size); + +/** + * Reallocate a dynamic memory block. + * + * @param[in] ptr A pointer to an existing memory block, \c NULL is + * valid. + * @param[in] size A size of a new block, \c 0 is valid. + * + * @returns @c yaml_realloc returns a pointer to a reallocated memory block, + * or @c NULL if it failed. + */ + +void * +yaml_realloc(void *ptr, size_t size); + +/** + * Free a dynamic memory block. + * + * @param[in] ptr A pointer to an existing memory block, \c NULL is + * valid. + */ + +void +yaml_free(void *ptr); + +/** @} */ + + #ifdef __cplusplus } #endif diff --git a/src/Makefile.am b/src/Makefile.am index fac4a55..6816d81 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ AM_CPPFLAGS = -I$(top_srcdir)/include lib_LTLIBRARIES = libyaml.la -libyaml_la_SOURCES = version.c api.c +libyaml_la_SOURCES = version.c api.c reader.c libyaml_la_LDFLAGS = -release $(YAML_LT_RELEASE) -version-info $(YAML_LT_CURRENT):$(YAML_LT_REVISION):$(YAML_LT_AGE) @@ -5,8 +5,40 @@ #include <yaml/yaml.h> +#include <assert.h> + +/* + * Allocate a dynamic memory block. + */ + +void * +yaml_malloc(size_t size) +{ + return malloc(size ? size : 1); +} + +/* + * Reallocate a dynamic memory block. + */ + +void * +yaml_realloc(void *ptr, size_t size) +{ + return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1); +} + /* - * Create a new parser. + * Free a dynamic memory block. + */ + +void +yaml_free(void *ptr) +{ + if (ptr) free(ptr); +} + +/* + * Create a new parser object. */ yaml_parser_t * @@ -14,7 +46,7 @@ yaml_parser_new(void) { yaml_parser_t *parser; - parser = malloc(sizeof(yaml_parser_t)); + parser = yaml_malloc(sizeof(yaml_parser_t)); if (!parser) return NULL; memset(parser, 0, sizeof(yaml_parser_t)); @@ -29,6 +61,103 @@ yaml_parser_new(void) void yaml_parser_delete(yaml_parser_t *parser) { - free(parser); + assert(parser); /* Non-NULL parser object expected. */ + + yaml_free(parser->buffer); + if (!parser->raw_buffer_foreign) + yaml_free(parser->raw_buffer); + + memset(parser, 0, sizeof(yaml_parser_t)); + + yaml_free(parser); +} + +/* + * String read handler (always returns error). + */ + +static int +yaml_string_read_handler(void *data, unsigned char *buffer, size_t size, + size_t *size_read) +{ + *size_read = 0; + return 1; +} + +/* + * File read handler. + */ + +static int +yaml_file_read_handler(void *data, unsigned char *buffer, size_t size, + size_t *size_read) +{ + *size_read = fread(buffer, 1, size, (FILE *)ext); + return !ferror((FILE *)ext); +} + +/* + * Set a string input. + */ + +void +yaml_parser_set_input_string(yaml_parser_t *parser, + unsigned char *input, size_t size) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->reader); /* You can set the source only once. */ + assert(input); /* Non-NULL input string expected. */ + + parser->read_handler = yaml_string_read_handler; + parser->read_handler_data = NULL; + + /* We use the input string as a raw (undecoded) buffer. */ + parser->raw_buffer = input; + parser->raw_buffer_size = size; + parser->raw_buffer_foreign = 1; +} + +/* + * Set a file input. + */ + +void +yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->reader); /* You can set the source only once. */ + assert(file); /* Non-NULL file object expected. */ + + parser->read_handler = yaml_file_read_handler; + parser->read_handler_data = file; +} + +/* + * Set a generic input. + */ + +void +yaml_parser_set_input(yaml_parser_t *parser, + yaml_read_handler_t *handler, void *data) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->reader); /* You can set the source only once. */ + assert(handler); /* Non-NULL read handler expected. */ + + parser->read_handler = handler; + parser->read_handler_data = data +} + +/* + * Set the source encoding. + */ + +void +yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->encoding); /* Encoding is already set or detected. */ + + parser->encoding = encoding; } diff --git a/src/reader.c b/src/reader.c new file mode 100644 index 0000000..787f785 --- /dev/null +++ b/src/reader.c @@ -0,0 +1,53 @@ + +#define RAW_BUFFER_SIZE 16384 +#define BUFFER_SIZE (RAW_BUFFER_SIZE*2) /* Should be enough for decoding + the whole raw buffer. */ + +/* + * Ensure that the buffer contains at least length characters. + * Return 1 on success, 0 on failure. + */ + +int +yaml_parser_update_reader(yaml_parser_t *parser, size_t length) +{ + /* If the EOF flag is set, do nothing. */ + + if (parser->eof) + return 1; + + /* First, let us check that the buffers are allocated. */ + + if (!parser->buffer) { + parser->buffer = yaml_malloc(BUFFER_SIZE); + if (!parser->buffer) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + parser->buffer_size = BUFFER_SIZE; + parser->buffer_pointer = parser->buffer; + parser->buffer_length = 0; + } + + if (!parser->raw_buffer) { + parser->raw_buffer = yaml_malloc(RAW_BUFFER_SIZE); + if (!parser->raw_buffer) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + parser->raw_buffer_size = RAW_BUFFER_SIZE; + } + + /* Next, determine the input encoding. */ + + if (!parser->encoding) { + if (!yaml_parser_determine_encoding(parser)) + return 0; + } + + /* more... */ + +} + + + |