1 | # ifndef EC_H
|
---|
2 | # define EC_H
|
---|
3 |
|
---|
4 | # ifndef CORD_H
|
---|
5 | # include "cord.h"
|
---|
6 | # endif
|
---|
7 |
|
---|
8 | /* Extensible cords are strings that may be destructively appended to. */
|
---|
9 | /* They allow fast construction of cords from characters that are */
|
---|
10 | /* being read from a stream. */
|
---|
11 | /*
|
---|
12 | * A client might look like:
|
---|
13 | *
|
---|
14 | * {
|
---|
15 | * CORD_ec x;
|
---|
16 | * CORD result;
|
---|
17 | * char c;
|
---|
18 | * FILE *f;
|
---|
19 | *
|
---|
20 | * ...
|
---|
21 | * CORD_ec_init(x);
|
---|
22 | * while(...) {
|
---|
23 | * c = getc(f);
|
---|
24 | * ...
|
---|
25 | * CORD_ec_append(x, c);
|
---|
26 | * }
|
---|
27 | * result = CORD_balance(CORD_ec_to_cord(x));
|
---|
28 | *
|
---|
29 | * If a C string is desired as the final result, the call to CORD_balance
|
---|
30 | * may be replaced by a call to CORD_to_char_star.
|
---|
31 | */
|
---|
32 |
|
---|
33 | # ifndef CORD_BUFSZ
|
---|
34 | # define CORD_BUFSZ 128
|
---|
35 | # endif
|
---|
36 |
|
---|
37 | typedef struct CORD_ec_struct {
|
---|
38 | CORD ec_cord;
|
---|
39 | char * ec_bufptr;
|
---|
40 | char ec_buf[CORD_BUFSZ+1];
|
---|
41 | } CORD_ec[1];
|
---|
42 |
|
---|
43 | /* This structure represents the concatenation of ec_cord with */
|
---|
44 | /* ec_buf[0 ... (ec_bufptr-ec_buf-1)] */
|
---|
45 |
|
---|
46 | /* Flush the buffer part of the extended chord into ec_cord. */
|
---|
47 | /* Note that this is almost the only real function, and it is */
|
---|
48 | /* implemented in 6 lines in cordxtra.c */
|
---|
49 | void CORD_ec_flush_buf(CORD_ec x);
|
---|
50 |
|
---|
51 | /* Convert an extensible cord to a cord. */
|
---|
52 | # define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord)
|
---|
53 |
|
---|
54 | /* Initialize an extensible cord. */
|
---|
55 | # define CORD_ec_init(x) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf)
|
---|
56 |
|
---|
57 | /* Append a character to an extensible cord. */
|
---|
58 | # define CORD_ec_append(x, c) \
|
---|
59 | { \
|
---|
60 | if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \
|
---|
61 | CORD_ec_flush_buf(x); \
|
---|
62 | } \
|
---|
63 | *((x)[0].ec_bufptr)++ = (c); \
|
---|
64 | }
|
---|
65 |
|
---|
66 | /* Append a cord to an extensible cord. Structure remains shared with */
|
---|
67 | /* original. */
|
---|
68 | void CORD_ec_append_cord(CORD_ec x, CORD s);
|
---|
69 |
|
---|
70 | # endif /* EC_H */
|
---|