3 Copyright (C) 2002, 2003, 2008 Niels Möller
5 This file is part of GNU Nettle.
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
16 * the GNU General Public License as published by the Free
17 Software Foundation; either version 2 of the License, or (at your
18 option) any later version.
20 or both in parallel, as here.
22 GNU Nettle is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received copies of the GNU General Public License and
28 the GNU Lesser General Public License along with this program. If
29 not, see http://www.gnu.org/licenses/.
44 sexp_input_init(struct sexp_input *input, FILE *f)
51 sexp_get_raw_char(struct sexp_input *input)
53 int c = getc(input->f);
58 die("Read error: %s\n", strerror(errno));
60 input->ctype = SEXP_EOF_CHAR;
64 input->ctype = SEXP_NORMAL_CHAR;
70 sexp_get_char(struct sexp_input *input)
77 sexp_get_raw_char(input);
78 if (input->ctype == SEXP_EOF_CHAR)
79 die("Unexpected end of file in coded data.\n");
81 if (input->c == input->terminator)
83 input->ctype = SEXP_END_CHAR;
89 /* Decodes in place. Should always work, when we decode one
90 * character at a time. */
91 if (!input->coding->decode_update(&input->state,
94 die("Invalid coded data.\n");
100 sexp_get_raw_char(input);
104 sexp_next_char(struct sexp_input *input)
106 sexp_get_char(input);
107 if (input->ctype != SEXP_NORMAL_CHAR)
108 die("Unexpected end of file.\n");
114 sexp_push_char(struct sexp_input *input,
115 struct nettle_buffer *string)
117 assert(input->ctype == SEXP_NORMAL_CHAR);
119 if (!NETTLE_BUFFER_PUTC(string, input->c))
120 die("Virtual memory exhasuted.\n");
124 sexp_input_start_coding(struct sexp_input *input,
125 const struct nettle_armor *coding,
128 assert(!input->coding);
130 input->coding = coding;
131 input->coding->decode_init(&input->state);
132 input->terminator = terminator;
136 sexp_input_end_coding(struct sexp_input *input)
138 assert(input->coding);
140 if (!input->coding->decode_final(&input->state))
141 die("Invalid coded data.\n");
143 input->coding = NULL;
147 /* Return 0 at end-of-string */
149 sexp_get_quoted_char(struct sexp_input *input)
151 sexp_next_char(input);
160 sexp_next_char(input);
164 case 'b': input->c = '\b'; return 1;
165 case 't': input->c = '\t'; return 1;
166 case 'n': input->c = '\n'; return 1;
167 case 'f': input->c = '\f'; return 1;
168 case 'r': input->c = '\r'; return 1;
169 case '\\': input->c = '\\'; return 1;
172 /* FIXME: Not implemnted */
175 if (sexp_next_char(input) == '\r')
176 sexp_next_char(input);
180 if (sexp_next_char(input) == '\n')
181 sexp_next_char(input);
190 sexp_get_token_string(struct sexp_input *input,
191 struct nettle_buffer *string)
193 assert(!input->coding);
194 assert(input->ctype == SEXP_NORMAL_CHAR);
196 if (!TOKEN_CHAR(input->c))
197 die("Invalid token.\n");
201 sexp_push_char(input, string);
202 sexp_get_char(input);
204 while (input->ctype == SEXP_NORMAL_CHAR && TOKEN_CHAR(input->c));
206 assert (string->size);
210 sexp_get_string(struct sexp_input *input,
211 struct nettle_buffer *string)
213 nettle_buffer_reset(string);
214 input->token = SEXP_STRING;
219 while (sexp_get_quoted_char(input))
220 sexp_push_char(input, string);
222 sexp_get_char(input);
226 sexp_input_start_coding(input, &nettle_base16, '#');
230 sexp_input_start_coding(input, &nettle_base64, '|');
235 sexp_get_char(input);
236 switch (input->ctype)
238 case SEXP_NORMAL_CHAR:
239 sexp_push_char(input, string);
242 die("Unexpected end of file in coded string.\n");
244 sexp_input_end_coding(input);
245 sexp_get_char(input);
253 sexp_get_token_string(input, string);
259 sexp_get_string_length(struct sexp_input *input, enum sexp_mode mode,
260 struct nettle_buffer *string)
264 nettle_buffer_reset(string);
265 input->token = SEXP_STRING;
267 length = input->c - '0';
270 /* There must be no more digits */
271 sexp_next_char(input);
276 /* Get rest of digits */
279 sexp_next_char(input);
281 if (input->c < '0' || input->c > '9')
284 /* FIXME: Check for overflow? */
285 length = length * 10 + input->c - '0';
293 for (; length; length--)
295 sexp_next_char(input);
296 sexp_push_char(input, string);
302 if (mode != SEXP_ADVANCED)
303 die("Encountered quoted string in canonical mode.\n");
305 for (; length; length--)
306 if (sexp_get_quoted_char(input))
307 sexp_push_char(input, string);
309 die("Unexpected end of string.\n");
311 if (sexp_get_quoted_char(input))
312 die("Quoted string longer than expected.\n");
317 sexp_input_start_coding(input, &nettle_base16, '#');
321 sexp_input_start_coding(input, &nettle_base64, '|');
324 for (; length; length--)
326 sexp_next_char(input);
327 sexp_push_char(input, string);
329 sexp_get_char(input);
330 if (input->ctype != SEXP_END_CHAR)
331 die("Coded string too long.\n");
333 sexp_input_end_coding(input);
338 die("Invalid string.\n");
341 /* Skip the ending character. */
342 sexp_get_char(input);
346 sexp_get_comment(struct sexp_input *input, struct nettle_buffer *string)
348 nettle_buffer_reset(string);
350 assert(input->ctype == SEXP_NORMAL_CHAR);
351 assert(input->c == ';');
355 sexp_push_char(input, string);
356 sexp_get_raw_char(input);
358 while (input->ctype == SEXP_NORMAL_CHAR && input->c != '\n');
360 input->token = SEXP_COMMENT;
363 /* When called, input->c should be the first character of the current
366 * When returning, input->c should be the first character of the next
369 sexp_get_token(struct sexp_input *input, enum sexp_mode mode,
370 struct nettle_buffer *string)
376 input->token = SEXP_EOF;
380 input->token = SEXP_CODING_END;
381 sexp_input_end_coding(input);
382 sexp_get_char(input);
385 case SEXP_NORMAL_CHAR:
388 case '0': case '1': case '2': case '3': case '4':
389 case '5': case '6': case '7': case '8': case '9':
390 sexp_get_string_length(input, mode, string);
394 input->token = SEXP_LIST_START;
395 sexp_get_char(input);
399 input->token = SEXP_LIST_END;
400 sexp_get_char(input);
404 input->token = SEXP_DISPLAY_START;
405 sexp_get_char(input);
409 input->token = SEXP_DISPLAY_END;
410 sexp_get_char(input);
414 if (mode == SEXP_CANONICAL)
415 die("Unexpected transport data in canonical mode.\n");
417 sexp_input_start_coding(input, &nettle_base64, '}');
418 sexp_get_char(input);
420 input->token = SEXP_TRANSPORT_START;
424 case ' ': /* SPC, TAB, LF, CR */
428 if (mode == SEXP_CANONICAL)
429 die("Whitespace encountered in canonical mode.\n");
431 sexp_get_char(input);
434 case ';': /* Comments */
435 if (mode == SEXP_CANONICAL)
436 die("Comment encountered in canonical mode.\n");
438 sexp_get_comment(input, string);
442 /* Ought to be a string */
443 if (mode != SEXP_ADVANCED)
444 die("Encountered advanced string in canonical mode.\n");
446 sexp_get_string(input, string);