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., 51 Franklin Street, Fifth Floor, Boston,
42 format_prefix(struct nettle_buffer
*buffer
,
46 unsigned prefix_length
= 1;
50 unsigned next
= digit
* 10;
60 for (; digit
; length
%= digit
, digit
/= 10)
61 if (!NETTLE_BUFFER_PUTC(buffer
, '0' + length
/ digit
))
64 if (!NETTLE_BUFFER_PUTC(buffer
, ':'))
68 return prefix_length
+ 1;
72 format_string(struct nettle_buffer
*buffer
,
73 unsigned length
, const uint8_t *s
)
75 unsigned prefix_length
= format_prefix(buffer
, length
);
79 if (buffer
&& !nettle_buffer_write(buffer
, length
, s
))
82 return prefix_length
+ length
;
86 sexp_vformat(struct nettle_buffer
*buffer
, const char *format
, va_list args
)
96 const char *start
= format
- 1;
97 unsigned length
= 1 + strcspn(format
, "()% \t");
98 unsigned output_length
= format_string(buffer
, length
, start
);
102 done
+= output_length
;
103 format
= start
+ length
;
116 if (buffer
&& !NETTLE_BUFFER_PUTC(buffer
, '('))
125 if (buffer
&& !NETTLE_BUFFER_PUTC(buffer
, ')'))
148 /* Allow unbalanced parenthesis */
149 if (buffer
&& !NETTLE_BUFFER_PUTC(buffer
, format
[-1]))
158 unsigned output_length
;
162 s
= va_arg(args
, const char *);
167 length
= va_arg(args
, unsigned);
168 s
= va_arg(args
, const char *);
171 output_length
= format_string(buffer
, length
, s
);
175 done
+= output_length
;
182 unsigned output_length
;
186 s
= va_arg(args
, const char *);
194 length
= va_arg(args
, unsigned);
195 s
= va_arg(args
, const char *);
200 if (buffer
&& !NETTLE_BUFFER_PUTC(buffer
, '['))
204 output_length
= format_string(buffer
, length
, s
);
209 done
+= output_length
;
211 if (buffer
&& !NETTLE_BUFFER_PUTC(buffer
, ']'))
225 s
= va_arg(args
, const char *);
230 length
= va_arg(args
, unsigned);
231 s
= va_arg(args
, const char *);
234 if (buffer
&& !nettle_buffer_write(buffer
, length
, s
))
242 uint32_t x
= va_arg(args
, uint32_t);
247 else if (x
< 0x8000L
)
249 else if (x
< 0x800000L
)
251 else if (x
< 0x80000000L
)
256 if (buffer
&& !(NETTLE_BUFFER_PUTC(buffer
, '0' + length
)
257 && NETTLE_BUFFER_PUTC(buffer
, ':')))
260 done
+= (2 + length
);
266 /* Leading byte needed for the sign. */
267 if (!NETTLE_BUFFER_PUTC(buffer
, 0))
271 if (!NETTLE_BUFFER_PUTC(buffer
, x
>> 24))
275 if (!NETTLE_BUFFER_PUTC(buffer
, (x
>> 16) & 0xff))
279 if (!NETTLE_BUFFER_PUTC(buffer
, (x
>> 8) & 0xff))
283 if (!NETTLE_BUFFER_PUTC(buffer
, x
& 0xff))
293 const MP_INT
*n
= va_arg(args
, const MP_INT
*);
295 unsigned prefix_length
;
297 length
= nettle_mpz_sizeinbase_256_s(n
);
298 prefix_length
= format_prefix(buffer
, length
);
302 done
+= prefix_length
;
306 uint8_t *space
= nettle_buffer_space(buffer
, length
);
310 nettle_mpz_get_str_256(length
, space
, n
);
323 sexp_format(struct nettle_buffer
*buffer
, const char *format
, ...)
328 va_start(args
, format
);
329 done
= sexp_vformat(buffer
, format
, args
);