File: reader.h

package info (click to toggle)
ruby-oj 3.16.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,852 kB
  • sloc: ansic: 19,402; ruby: 11,451; makefile: 17
file content (137 lines) | stat: -rw-r--r-- 3,248 bytes parent folder | download
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 */