diff options
Diffstat (limited to 'gc/include/ec.h')
-rw-r--r-- | gc/include/ec.h | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/gc/include/ec.h b/gc/include/ec.h new file mode 100644 index 0000000..c829b83 --- /dev/null +++ b/gc/include/ec.h @@ -0,0 +1,70 @@ +# ifndef EC_H +# define EC_H + +# ifndef CORD_H +# include "cord.h" +# endif + +/* Extensible cords are strings that may be destructively appended to. */ +/* They allow fast construction of cords from characters that are */ +/* being read from a stream. */ +/* + * A client might look like: + * + * { + * CORD_ec x; + * CORD result; + * char c; + * FILE *f; + * + * ... + * CORD_ec_init(x); + * while(...) { + * c = getc(f); + * ... + * CORD_ec_append(x, c); + * } + * result = CORD_balance(CORD_ec_to_cord(x)); + * + * If a C string is desired as the final result, the call to CORD_balance + * may be replaced by a call to CORD_to_char_star. + */ + +# ifndef CORD_BUFSZ +# define CORD_BUFSZ 128 +# endif + +typedef struct CORD_ec_struct { + CORD ec_cord; + char * ec_bufptr; + char ec_buf[CORD_BUFSZ+1]; +} CORD_ec[1]; + +/* This structure represents the concatenation of ec_cord with */ +/* ec_buf[0 ... (ec_bufptr-ec_buf-1)] */ + +/* Flush the buffer part of the extended chord into ec_cord. */ +/* Note that this is almost the only real function, and it is */ +/* implemented in 6 lines in cordxtra.c */ +void CORD_ec_flush_buf(CORD_ec x); + +/* Convert an extensible cord to a cord. */ +# define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord) + +/* Initialize an extensible cord. */ +# define CORD_ec_init(x) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf) + +/* Append a character to an extensible cord. */ +# define CORD_ec_append(x, c) \ + { \ + if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \ + CORD_ec_flush_buf(x); \ + } \ + *((x)[0].ec_bufptr)++ = (c); \ + } + +/* Append a cord to an extensible cord. Structure remains shared with */ +/* original. */ +void CORD_ec_append_cord(CORD_ec x, CORD s); + +# endif /* EC_H */ |