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 */ 71