3
* Writing s-expressions.
6
/* nettle, low-level cryptographics library
8
* Copyright (C) 2002 Niels M�ller
10
* The nettle library is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU Lesser General Public License as published by
12
* the Free Software Foundation; either version 2.1 of the License, or (at your
13
* option) any later version.
15
* The nettle library is distributed in the hope that it will be useful, but
16
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18
* License for more details.
20
* You should have received a copy of the GNU Lesser General Public License
21
* along with the nettle library; see the file COPYING.LIB. If not, write to
22
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
43
/* Code copied from sexp-conv.c: sexp_put_length */
45
format_prefix(struct nettle_buffer *buffer,
49
unsigned prefix_length = 1;
53
unsigned next = digit * 10;
63
for (; digit; length %= digit, digit /= 10)
64
if (!NETTLE_BUFFER_PUTC(buffer, '0' + length / digit))
67
if (!NETTLE_BUFFER_PUTC(buffer, ':'))
71
return prefix_length + 1;
75
format_string(struct nettle_buffer *buffer,
76
unsigned length, const uint8_t *s)
78
unsigned prefix_length = format_prefix(buffer, length);
82
if (buffer && !nettle_buffer_write(buffer, length, s))
85
return prefix_length + length;
89
sexp_vformat(struct nettle_buffer *buffer, const char *format, va_list args)
99
const char *start = format - 1;
100
unsigned length = 1 + strcspn(format, "()% \t");
101
unsigned output_length = format_string(buffer, length, start);
105
done += output_length;
106
format = start + length;
119
if (buffer && !NETTLE_BUFFER_PUTC(buffer, '('))
128
if (buffer && !NETTLE_BUFFER_PUTC(buffer, ')'))
151
/* Allow unbalanced parenthesis */
152
if (buffer && !NETTLE_BUFFER_PUTC(buffer, format[-1]))
161
unsigned output_length;
165
s = va_arg(args, const char *);
170
length = va_arg(args, unsigned);
171
s = va_arg(args, const char *);
174
output_length = format_string(buffer, length, s);
178
done += output_length;
185
unsigned output_length;
189
s = va_arg(args, const char *);
197
length = va_arg(args, unsigned);
198
s = va_arg(args, const char *);
203
if (buffer && !NETTLE_BUFFER_PUTC(buffer, '['))
207
output_length = format_string(buffer, length, s);
212
done += output_length;
214
if (buffer && !NETTLE_BUFFER_PUTC(buffer, ']'))
228
s = va_arg(args, const char *);
233
length = va_arg(args, unsigned);
234
s = va_arg(args, const char *);
237
if (buffer && !nettle_buffer_write(buffer, length, s))
245
uint32_t x = va_arg(args, uint32_t);
250
else if (x < 0x8000L)
252
else if (x < 0x800000L)
254
else if (x < 0x80000000L)
259
if (buffer && !(NETTLE_BUFFER_PUTC(buffer, '0' + length)
260
&& NETTLE_BUFFER_PUTC(buffer, ':')))
263
done += (2 + length);
269
/* Leading byte needed for the sign. */
270
if (!NETTLE_BUFFER_PUTC(buffer, 0))
274
if (!NETTLE_BUFFER_PUTC(buffer, x >> 24))
278
if (!NETTLE_BUFFER_PUTC(buffer, (x >> 16) & 0xff))
282
if (!NETTLE_BUFFER_PUTC(buffer, (x >> 8) & 0xff))
286
if (!NETTLE_BUFFER_PUTC(buffer, x & 0xff))
297
const MP_INT *n = va_arg(args, const MP_INT *);
299
unsigned prefix_length;
301
length = nettle_mpz_sizeinbase_256_s(n);
302
prefix_length = format_prefix(buffer, length);
306
done += prefix_length;
310
uint8_t *space = nettle_buffer_space(buffer, length);
314
nettle_mpz_get_str_256(length, space, n);
319
#else /* ! HAVE_LIBGMP */
321
#endif /* ! HAVE_LIBGMP */
330
sexp_format(struct nettle_buffer *buffer, const char *format, ...)
335
va_start(args, format);
336
done = sexp_vformat(buffer, format, args);