1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// Copyright (c) 2011 Peter Ohler. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for license details.
#ifndef OJ_READER_H
#define OJ_READER_H
#include "mem.h"
typedef struct _reader {
char base[0x00001000];
char *head;
char *end;
char *tail;
char *read_end; /* one past last character read */
char *pro; /* protection start, buffer can not slide past this point */
char *str; /* start of current string being read */
long pos;
int line;
int col;
int free_head;
int (*read_func)(struct _reader *reader);
union {
int fd;
VALUE io;
const char *in_str;
};
} *Reader;
extern void oj_reader_init(Reader reader, VALUE io, int fd, bool to_s);
extern int oj_reader_read(Reader reader);
static inline char reader_get(Reader reader) {
// printf("*** drive get from '%s' from start: %ld buf: %p from read_end: %ld\n",
// reader->tail, reader->tail - reader->head, reader->head, reader->read_end - reader->tail);
if (reader->read_end <= reader->tail) {
if (0 != oj_reader_read(reader)) {
return '\0';
}
}
if ('\n' == *reader->tail) {
reader->line++;
reader->col = 0;
}
reader->col++;
reader->pos++;
return *reader->tail++;
}
static inline void reader_backup(Reader reader) {
reader->tail--;
reader->col--;
reader->pos--;
if (0 >= reader->col) {
reader->line--;
// allow col to be negative since we never backup twice in a row
}
}
static inline void reader_protect(Reader reader) {
reader->pro = reader->tail;
reader->str = reader->tail; // can't have str before pro
}
static inline void reader_release(Reader reader) {
reader->pro = 0;
}
/* Starts by reading a character so it is safe to use with an empty or
* compacted buffer.
*/
static inline char reader_next_non_white(Reader reader) {
char c;
while ('\0' != (c = reader_get(reader))) {
switch (c) {
case ' ':
case '\t':
case '\f':
case '\n':
case '\r': break;
default: return c;
}
}
return '\0';
}
/* Starts by reading a character so it is safe to use with an empty or
* compacted buffer.
*/
static inline char reader_next_white(Reader reader) {
char c;
while ('\0' != (c = reader_get(reader))) {
switch (c) {
case ' ':
case '\t':
case '\f':
case '\n':
case '\r':
case '\0': return c;
default: break;
}
}
return '\0';
}
static inline int reader_expect(Reader reader, const char *s) {
for (; '\0' != *s; s++) {
if (reader_get(reader) != *s) {
return -1;
}
}
return 0;
}
static inline void reader_cleanup(Reader reader) {
if (reader->free_head && 0 != reader->head) {
OJ_R_FREE((char *)reader->head);
reader->head = 0;
reader->free_head = 0;
}
}
static inline int is_white(char c) {
switch (c) {
case ' ':
case '\t':
case '\f':
case '\n':
case '\r': return 1;
default: break;
}
return 0;
}
#endif /* OJ_READER_H */
|