Ruby  1.9.3p392(2013-02-22revision39386)
yamlbyte.h
Go to the documentation of this file.
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 */
13 typedef unsigned char yamlbyte_utf8_t;
14 typedef 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)'Q')
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 
74 typedef void * yamlbyte_consumer_t;
75 typedef void * yamlbyte_producer_t;
76 
77 /* push and pull APIs need a way to communicate results */
78 typedef 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 */
87 
88 typedef const yamlbyte_char_t *yamlbyte_buff_t;
89 
90 /*
91  * The "Instruction" API
92  */
93 
94 typedef struct yaml_instruction {
95  yamlbyte_char_t bytecode;
97  yamlbyte_buff_t finish; /* open range, *finish is _not_ part */
99 
100 /* producer pushes the instruction with one bytecode event to the
101  * consumer; if the consumer's result is not YAMLBYTE_OK, then
102  * the producer should stop */
103 typedef
106  yamlbyte_consumer_t self,
107  yamlbyte_inst_t inst
108  );
109 
110 /* consumer pulls a bytecode instruction from the producer; in this
111  * case the instruction (and is buffer) are owned by the producer and
112  * will remain valid till the pull function is called once again;
113  * if the instruction is NULL, then there are no more results; and
114  * it is important to call the pull function till it returns NULL so
115  * that the producer can clean up its memory allocations */
116 typedef
119  yamlbyte_producer_t self,
120  yamlbyte_inst_t *inst /* to be filled in by the producer */
121  );
122 
123 /*
124  * Buffer based API
125  */
126 
127 /* producer pushes a null terminated buffer filled with one or more
128  * bytecode events to the consumer; if the consumer's result is not
129  * YAMLBYTE_OK, then the producer should stop */
130 typedef
133  yamlbyte_consumer_t self,
134  yamlbyte_buff_t buff
135  );
136 
137 /* consumer pulls bytecode events from the producer; in this case
138  * the buffer is owned by the producer, and will remain valid till
139  * the pull function is called once again; if the buffer pointer
140  * is set to NULL, then there are no more results; it is important
141  * to call the pull function till it returns NULL so that the
142  * producer can clean up its memory allocations */
143 typedef
146  yamlbyte_producer_t self,
147  yamlbyte_buff_t *buff /* to be filled in by the producer */
148  );
149 
150 /* convert a pull interface to a push interface; the reverse process
151  * requires threads and thus is language dependent */
152 #define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result) \
153  do { \
154  yamlbyte_pullbuff_t _pull = (pull); \
155  yamlbyte_pushbuff_t _push = (push); \
156  yamlbyte_result_t _result = YAMLBYTE_OK; \
157  yamlbyte_producer_t _producer = (producer); \
158  yamlbyte_consumer_t _consumer = (consumer); \
159  while(1) { \
160  yamlbyte_buff_t buff = NULL; \
161  _result = _pull(_producer,&buff); \
162  if(YAMLBYTE_OK != result || NULL == buff) \
163  break; \
164  _result = _push(_consumer,buff); \
165  if(YAMLBYTE_OK != result) \
166  break; \
167  } \
168  (result) = _result; \
169  } while(0)
170 
171 #endif
172