1 /*
2 * Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved.
3 *
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
6 *
7 * Permission is hereby granted to use or copy this program
8 * for any purpose, provided the above notices are retained on all copies.
9 * Permission to modify the code and to distribute modified code is granted,
10 * provided the above notices are retained, and a notice that the code was
11 * modified is included with the above copyright notice.
12 */
13 14 #ifndef EC_H
15 #define EC_H
16 17 #ifndef CORD_H
18 # include "cord.h"
19 #endif
20 21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 25 /*
26 * Extensible cords are strings that may be destructively appended to.
27 * They allow fast construction of cords from characters that are being
28 * read from a stream.
29 *
30 * A client might look like:
31 * ```
32 * CORD_ec x;
33 * CORD result;
34 * char c;
35 * FILE *f;
36 *
37 * CORD_ec_init(x);
38 * while (...) {
39 * c = getc(f);
40 * ...
41 * CORD_ec_append(x, c);
42 * }
43 * result = CORD_balance(CORD_ec_to_cord(x));
44 * ```
45 *
46 * If a C string is desired as the final result, the call to `CORD_balance`
47 * may be replaced by a call to `CORD_to_char_star`.
48 */
49 50 #ifndef CORD_BUFSZ
51 # define CORD_BUFSZ 128
52 #endif
53 54 /**
55 * This structure represents the concatenation of `ec_cord` with
56 * `ec_buf[0 .. ec_bufptr - ec_buf - 1]`.
57 */
58 typedef struct CORD_ec_struct {
59 CORD ec_cord;
60 char *ec_bufptr;
61 char ec_buf[CORD_BUFSZ + 1];
62 } CORD_ec[1];
63 64 /** Flush the buffer part of the extended cord into extensible cord. */
65 CORD_API void CORD_ec_flush_buf(CORD_ec);
66 67 /** Convert an extensible cord to a cord. */
68 #define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord)
69 70 /** Initialize an extensible cord. */
71 #define CORD_ec_init(x) \
72 ((x)[0].ec_cord = 0, (void)((x)[0].ec_bufptr = (x)[0].ec_buf))
73 74 /** Append a character to an extensible cord. */
75 #define CORD_ec_append(x, c) \
76 ((void)((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ \
77 ? (CORD_ec_flush_buf(x), 0) \
78 : 0), \
79 (void)(*(x)[0].ec_bufptr++ = (c)))
80 81 /**
82 * Append a cord to an extensible cord. Structure remains shared with
83 * the original.
84 */
85 CORD_API void CORD_ec_append_cord(CORD_ec, CORD);
86 87 #ifdef __cplusplus
88 } /* extern "C" */
89 #endif
90 91 #endif /* EC_H */
92