Kirill Simonov avatar Kirill Simonov committed f459cf2

Implementing Reader: first tries.

Comments (0)

Files changed (4)

include/yaml/yaml.h

 #endif
 
 #include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
 
 /**
  * @defgroup version Version Information
     YAML_UTF16BE_ENCODING
 } yaml_encoding_t;
 
-/** @} */
-
-/*
-
+/** Many bad things could happen with the parser and emitter. */
 typedef enum {
     YAML_NO_ERROR,
 
     YAML_EMITTER_ERROR
 } yaml_error_type_t;
 
+/** @} */
+
+/*
+
 typedef enum {
     YAML_ANY_SCALAR_STYLE,
     YAML_PLAIN_SCALAR_STYLE,
  * 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.
 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;
     /** 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;
+
     /**
      * @}
      */
 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);
+
 /** @} */
 
 /*
 } 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
 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)
 
 #include <yaml/yaml.h>
 
+#include <assert.h>
+
 /*
- * Create a new parser.
+ * 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);
+}
+
+/*
+ * Free a dynamic memory block.
+ */
+
+void
+yaml_free(void *ptr)
+{
+    if (ptr) free(ptr);
+}
+
+/*
+ * Create a new parser object.
  */
 
 yaml_parser_t *
 {
     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));
 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;
+}
+
+
+#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... */
+
+}
+
+
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.