root / trunk / ext / yamlbyte / yamlbyte.h

Revision 109, 6.5 kB (checked in by cce, 5 years ago)

adding both forms of the API, plus the WHOLE_SCALAR bytecode

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*  yamlbyte.h
2 *
3 *  The YAML bytecode "C" interface header file.   See the YAML bytecode
4 *  reference for bytecode sequence rules and for the meaning of each
5 *  bytecode.
6 */
7
8#ifndef YAMLBYTE_H
9#define YAMLBYTE_H
10#include <stddef.h>
11
12/* define what a character is */
13typedef unsigned char yamlbyte_utf8_t;
14typedef unsigned short yamlbyte_utf16_t;
15#ifdef YAMLBYTE_UTF8
16  #ifdef YAMLBYTE_UTF16
17    #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
18  #endif
19  typedef yamlbyte_utf8_t yamlbyte_char_t;
20#else
21  #ifdef YAMLBYTE_UTF16
22    typedef yamlbyte_utf16_t yamlbyte_char_t;
23  #else
24    #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
25  #endif
26#endif
27
28/* specify list of bytecodes */
29#define YAMLBYTE_FINISH          ((yamlbyte_char_t) 0)
30#define YAMLBYTE_DOCUMENT        ((yamlbyte_char_t)'D')
31#define YAMLBYTE_DIRECTIVE       ((yamlbyte_char_t)'V')
32#define YAMLBYTE_PAUSE           ((yamlbyte_char_t)'P')
33#define YAMLBYTE_MAPPING         ((yamlbyte_char_t)'M')
34#define YAMLBYTE_SEQUENCE        ((yamlbyte_char_t)'S')
35#define YAMLBYTE_END_BRANCH      ((yamlbyte_char_t)'E')
36#define YAMLBYTE_SCALAR          ((yamlbyte_char_t)'S')
37#define YAMLBYTE_CONTINUE        ((yamlbyte_char_t)'C')
38#define YAMLBYTE_NEWLINE         ((yamlbyte_char_t)'N')
39#define YAMLBYTE_NULLCHAR        ((yamlbyte_char_t)'Z')
40#define YAMLBYTE_ANCHOR          ((yamlbyte_char_t)'A')
41#define YAMLBYTE_ALIAS           ((yamlbyte_char_t)'R')
42#define YAMLBYTE_TRANSFER        ((yamlbyte_char_t)'T')
43/* formatting bytecodes */
44#define YAMLBYTE_COMMENT         ((yamlbyte_char_t)'c')
45#define YAMLBYTE_INDENT          ((yamlbyte_char_t)'i')
46#define YAMLBYTE_STYLE           ((yamlbyte_char_t)'s')
47/* other bytecodes */
48#define YAMLBYTE_LINE_NUMBER     ((yamlbyte_char_t)'#')
49#define YAMLBYTE_WHOLE_SCALAR    ((yamlbyte_char_t)'<')
50#define YAMLBYTE_NOTICE          ((yamlbyte_char_t)'!')
51#define YAMLBYTE_SPAN            ((yamlbyte_char_t)')')
52#define YAMLBYTE_ALLOC           ((yamlbyte_char_t)'@')
53
54/* second level style bytecodes, ie "s>" */
55#define YAMLBYTE_FLOW            ((yamlbyte_char_t)'>')
56#define YAMLBYTE_LITERAL         ((yamlbyte_char_t)'|')
57#define YAMLBYTE_BLOCK           ((yamlbyte_char_t)'b')
58#define YAMLBYTE_PLAIN           ((yamlbyte_char_t)'p')
59#define YAMLBYTE_INLINE_MAPPING  ((yamlbyte_char_t)'{')
60#define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[')
61#define YAMLBYTE_SINGLE_QUOTED   ((yamlbyte_char_t)39)
62#define YAMLBYTE_DOUBLE_QUOTED   ((yamlbyte_char_t)'"')
63
64/*
65 * The "C" API has two variants, one based on instructions,
66 * with events delivered via pointers; and the other one
67 * is character based where one or more instructions are
68 * serialized into a buffer.
69 *
70 * Note: In the instruction based API, WHOLE_SCALAR does
71 *       not have the '<here' marshalling stuff.
72 */
73
74typedef void * yamlbyte_consumer_t;
75typedef void * yamlbyte_producer_t;
76
77/* push and pull APIs need a way to communicate results */
78typedef enum {
79    YAMLBYTE_OK          = 0,     /* proceed                        */
80    YAMLBYTE_E_MEMORY    = 'M',   /* could not allocate memory      */
81    YAMLBYTE_E_READ      = 'R',   /* input stream read error        */
82    YAMLBYTE_E_WRITE     = 'W',   /* output stream write error      */
83    YAMLBYTE_E_OTHER     = '?',   /* some other error condition     */
84    YAMLBYTE_E_PARSE     = 'P',   /* parse error, check bytecodes   */
85} yamlbyte_result_t;
86 
87typedef const yamlbyte_char_t *yamlbyte_buff_t;
88
89/*
90 *  The "Instruction" API
91 */
92
93typedef struct yaml_instruction {
94    yamlbyte_char_t bytecode;
95    yamlbyte_buff_t start;
96    yamlbyte_buff_t finish;  /* open range, *finish is _not_ part */
97} *yamlbyte_inst_t;
98
99/* producer pushes the instruction with one bytecode event to the
100 * consumer; if the consumer's result is not YAMLBYTE_OK, then
101 * the producer should stop */
102typedef
103  yamlbyte_result_t
104   (*yamlbyte_push_t)(
105     yamlbyte_consumer_t self,
106     yamlbyte_inst_t  inst
107   );
108
109/* consumer pulls a bytecode instruction from the producer; in this
110 * case the instruction (and is buffer) are owned by the producer and
111 * will remain valid till the pull function is called once again;
112 * if the instruction is NULL, then there are no more results; and
113 * it is important to call the pull function till it returns NULL so
114 * that the producer can clean up its memory allocations */
115typedef
116   yamlbyte_result_t
117    (*yamlbyte_pull_t)(
118      yamlbyte_producer_t self,
119      yamlbyte_inst_t *inst   /* to be filled in by the producer */
120    );
121
122/*
123 *  Buffer based API
124 */
125
126/* producer pushes a null terminated buffer filled with one or more
127 * bytecode events to the consumer; if the consumer's result is not
128 * YAMLBYTE_OK, then the producer should stop */
129typedef
130  yamlbyte_result_t
131   (*yamlbyte_pushbuff_t)(
132     yamlbyte_consumer_t self,
133     yamlbyte_buff_t  buff
134   );
135
136/* consumer pulls bytecode events from the producer; in this case
137 * the buffer is owned by the producer, and will remain valid till
138 * the pull function is called once again; if the buffer pointer
139 * is set to NULL, then there are no more results; it is important
140 * to call the pull function till it returns NULL so that the
141 * producer can clean up its memory allocations */
142typedef
143   yamlbyte_result_t
144    (*yamlbyte_pullbuff_t)(
145      yamlbyte_producer_t self,
146      yamlbyte_buff_t *buff   /* to be filled in by the producer */
147    );
148
149/* convert a pull interface to a push interface; the reverse process
150 * requires threads and thus is language dependent */
151#define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result)       \
152    do {                                                         \
153        yamlbyte_pullbuff_t _pull = (pull);                              \
154        yamlbyte_pushbuff_t _push = (push);                              \
155        yamlbyte_result_t _result = YAMLBYTE_OK;                         \
156        yamlbyte_producer_t _producer = (producer);                  \
157        yamlbyte_consumer_t _consumer = (consumer);                  \
158        while(1) {                                               \
159            yamlbyte_buff_t buff = NULL;                           \
160            _result = _pull(_producer,&buff);                    \
161            if(YAMLBYTE_OK != result || NULL == buff)                \
162                break;                                           \
163            _result = _push(_consumer,buff);                     \
164            if(YAMLBYTE_OK != result)                                \
165                break;                                           \
166        }                                                        \
167        (result) = _result;                                      \
168    } while(0)
169
170#endif
Note: See TracBrowser for help on using the browser.