-
Notifications
You must be signed in to change notification settings - Fork 0
/
iteratee.h
98 lines (84 loc) · 2.45 KB
/
iteratee.h
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
/*
* Copyright (C) 2010 Valery V. Vorotyntsev <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _ITERATEE_H
#define _ITERATEE_H
/*
* Iteratee-based I/O
*
* In essence, an iteratee takes a chunk of the input stream and
* returns one of:
* - the computed result and the remaining part of the stream;
* - the indication that iteratee needs more data, along with the
* continuation to process these data;
* - a message to the stream producer (e.g., to rewind the stream) or
* an error indicator.
*
* See also:
* http://okmij.org/ftp/papers/LL3-collections-enumerators.txt
* http://okmij.org/ftp/Streams.html
*/
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "util.h"
typedef enum { IE_CONT, IE_DONE } IterV;
/*
* A stream is a (continuing) sequence of bytes bundled in Chunks.
*
* data Stream el = EOF (Maybe ErrMsg) | Chunk [el]
*/
struct Stream {
enum {
S_EOF, /* stream is exhausted (due to EOF or some error) */
S_CHUNK /* stream is not terminated yet */
} type;
/*
* Pointer to chunk data (S_CHUNK only).
*
* Meaningless for S_EOF.
*/
const uint8_t *data;
/*
* Size of chunk (S_CHUNK only).
*
* Zero length signifies a stream with no currently available
* data but which is still continuing. A stream processor
* should, informally speaking, ``suspend itself'' and wait
* for more data to arrive.
*
* Meaningless for S_EOF.
*/
size_t size;
/*
* Error message.
*
* NULL if EOF was reached without error; otherwise this is a
* pointer to an error message (or a control message in general).
*/
char *errmsg;
};
#define STREAM_INIT { S_EOF, NULL, 0, NULL }
/*
* Produce formatted error message.
*
* Do nothing if `str->errmsg' is not NULL, thus keeping the original
* error message.
*
* NOTE: This function calls malloc(3). Be sure to free(3)
* `str->errmsg' eventually.
*/
void set_error(struct Stream *str, const char *format, ...);
/* -- Some primitive iteratees -------------------------------------- */
/*
* Attempt to read the next byte of the stream and store it in `*c'.
* Set an error if the stream is terminated.
*/
IterV head(uint8_t *c, struct Stream *str);
/* Skip prefix bytes that satisfy the predicate. */
IterV drop_while(bool (*p)(uint8_t c), struct Stream *str);
#endif /* _ITERATEE_H */