summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxi <xi@18f92427-320e-0410-9341-c67f048884a3>2006-05-27 17:19:07 +0000
committerxi <xi@18f92427-320e-0410-9341-c67f048884a3>2006-05-27 17:19:07 +0000
commit9f2aadeadd713e7d041616d84c3033a822e559bf (patch)
tree57b669d90579bb58e5b88c21596e45b0f0283c35
parent9ffe24228eb6bbd279208671b6ca79371175bc97 (diff)
downloadlibyaml-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.h161
-rw-r--r--src/Makefile.am2
-rw-r--r--src/api.c135
-rw-r--r--src/reader.c53
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)
diff --git a/src/api.c b/src/api.c
index cffa8e9..0594727 100644
--- a/src/api.c
+++ b/src/api.c
@@ -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... */
+
+}
+
+
+