1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/bio/b_print.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,848 @@
1.4 +/* crypto/bio/b_print.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +/*
1.62 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.63 + */
1.64 +/* disable assert() unless BIO_DEBUG has been defined */
1.65 +#ifndef BIO_DEBUG
1.66 +# ifndef NDEBUG
1.67 +# define NDEBUG
1.68 +# endif
1.69 +#endif
1.70 +
1.71 +/*
1.72 + * Stolen from tjh's ssl/ssl_trc.c stuff.
1.73 + */
1.74 +
1.75 +#include <stdio.h>
1.76 +#include <string.h>
1.77 +#include <ctype.h>
1.78 +#include <assert.h>
1.79 +#include <limits.h>
1.80 +#include "cryptlib.h"
1.81 +#ifndef NO_SYS_TYPES_H
1.82 +#include <sys/types.h>
1.83 +#endif
1.84 +#include <openssl/bn.h> /* To get BN_LLONG properly defined */
1.85 +#include <openssl/bio.h>
1.86 +
1.87 +#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
1.88 +# ifndef HAVE_LONG_LONG
1.89 +# define HAVE_LONG_LONG 1
1.90 +# endif
1.91 +#endif
1.92 +
1.93 +/***************************************************************************/
1.94 +
1.95 +/*
1.96 + * Copyright Patrick Powell 1995
1.97 + * This code is based on code written by Patrick Powell <papowell@astart.com>
1.98 + * It may be used for any purpose as long as this notice remains intact
1.99 + * on all source code distributions.
1.100 + */
1.101 +
1.102 +/*
1.103 + * This code contains numerious changes and enhancements which were
1.104 + * made by lots of contributors over the last years to Patrick Powell's
1.105 + * original code:
1.106 + *
1.107 + * o Patrick Powell <papowell@astart.com> (1995)
1.108 + * o Brandon Long <blong@fiction.net> (1996, for Mutt)
1.109 + * o Thomas Roessler <roessler@guug.de> (1998, for Mutt)
1.110 + * o Michael Elkins <me@cs.hmc.edu> (1998, for Mutt)
1.111 + * o Andrew Tridgell <tridge@samba.org> (1998, for Samba)
1.112 + * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP)
1.113 + * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
1.114 + * o ... (for OpenSSL)
1.115 + */
1.116 +
1.117 +#ifdef HAVE_LONG_DOUBLE
1.118 +#define LDOUBLE long double
1.119 +#else
1.120 +#define LDOUBLE double
1.121 +#endif
1.122 +
1.123 +#if HAVE_LONG_LONG
1.124 +# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
1.125 +# define LLONG __int64
1.126 +# else
1.127 +# define LLONG long long
1.128 +# endif
1.129 +#else
1.130 +#define LLONG long
1.131 +#endif
1.132 +
1.133 +static void fmtstr (char **, char **, size_t *, size_t *,
1.134 + const char *, int, int, int);
1.135 +static void fmtint (char **, char **, size_t *, size_t *,
1.136 + LLONG, int, int, int, int);
1.137 +static void fmtfp (char **, char **, size_t *, size_t *,
1.138 + LDOUBLE, int, int, int);
1.139 +static void doapr_outch (char **, char **, size_t *, size_t *, int);
1.140 +static void _dopr(char **sbuffer, char **buffer,
1.141 + size_t *maxlen, size_t *retlen, int *truncated,
1.142 + const char *format, va_list args);
1.143 +
1.144 +/* format read states */
1.145 +#define DP_S_DEFAULT 0
1.146 +#define DP_S_FLAGS 1
1.147 +#define DP_S_MIN 2
1.148 +#define DP_S_DOT 3
1.149 +#define DP_S_MAX 4
1.150 +#define DP_S_MOD 5
1.151 +#define DP_S_CONV 6
1.152 +#define DP_S_DONE 7
1.153 +
1.154 +/* format flags - Bits */
1.155 +#define DP_F_MINUS (1 << 0)
1.156 +#define DP_F_PLUS (1 << 1)
1.157 +#define DP_F_SPACE (1 << 2)
1.158 +#define DP_F_NUM (1 << 3)
1.159 +#define DP_F_ZERO (1 << 4)
1.160 +#define DP_F_UP (1 << 5)
1.161 +#define DP_F_UNSIGNED (1 << 6)
1.162 +
1.163 +/* conversion flags */
1.164 +#define DP_C_SHORT 1
1.165 +#define DP_C_LONG 2
1.166 +#define DP_C_LDOUBLE 3
1.167 +#define DP_C_LLONG 4
1.168 +
1.169 +/* some handy macros */
1.170 +#define char_to_int(p) (p - '0')
1.171 +#define OSSL_MAX(p,q) ((p >= q) ? p : q)
1.172 +
1.173 +static void
1.174 +_dopr(
1.175 + char **sbuffer,
1.176 + char **buffer,
1.177 + size_t *maxlen,
1.178 + size_t *retlen,
1.179 + int *truncated,
1.180 + const char *format,
1.181 + va_list args)
1.182 +{
1.183 + char ch;
1.184 + LLONG value;
1.185 + LDOUBLE fvalue;
1.186 + char *strvalue;
1.187 + int min;
1.188 + int max;
1.189 + int state;
1.190 + int flags;
1.191 + int cflags;
1.192 + size_t currlen;
1.193 +
1.194 + state = DP_S_DEFAULT;
1.195 + flags = currlen = cflags = min = 0;
1.196 + max = -1;
1.197 + ch = *format++;
1.198 +
1.199 + while (state != DP_S_DONE) {
1.200 + if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
1.201 + state = DP_S_DONE;
1.202 +
1.203 + switch (state) {
1.204 + case DP_S_DEFAULT:
1.205 + if (ch == '%')
1.206 + state = DP_S_FLAGS;
1.207 + else
1.208 + doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
1.209 + ch = *format++;
1.210 + break;
1.211 + case DP_S_FLAGS:
1.212 + switch (ch) {
1.213 + case '-':
1.214 + flags |= DP_F_MINUS;
1.215 + ch = *format++;
1.216 + break;
1.217 + case '+':
1.218 + flags |= DP_F_PLUS;
1.219 + ch = *format++;
1.220 + break;
1.221 + case ' ':
1.222 + flags |= DP_F_SPACE;
1.223 + ch = *format++;
1.224 + break;
1.225 + case '#':
1.226 + flags |= DP_F_NUM;
1.227 + ch = *format++;
1.228 + break;
1.229 + case '0':
1.230 + flags |= DP_F_ZERO;
1.231 + ch = *format++;
1.232 + break;
1.233 + default:
1.234 + state = DP_S_MIN;
1.235 + break;
1.236 + }
1.237 + break;
1.238 + case DP_S_MIN:
1.239 + if (isdigit((unsigned char)ch)) {
1.240 + min = 10 * min + char_to_int(ch);
1.241 + ch = *format++;
1.242 + } else if (ch == '*') {
1.243 + min = va_arg(args, int);
1.244 + ch = *format++;
1.245 + state = DP_S_DOT;
1.246 + } else
1.247 + state = DP_S_DOT;
1.248 + break;
1.249 + case DP_S_DOT:
1.250 + if (ch == '.') {
1.251 + state = DP_S_MAX;
1.252 + ch = *format++;
1.253 + } else
1.254 + state = DP_S_MOD;
1.255 + break;
1.256 + case DP_S_MAX:
1.257 + if (isdigit((unsigned char)ch)) {
1.258 + if (max < 0)
1.259 + max = 0;
1.260 + max = 10 * max + char_to_int(ch);
1.261 + ch = *format++;
1.262 + } else if (ch == '*') {
1.263 + max = va_arg(args, int);
1.264 + ch = *format++;
1.265 + state = DP_S_MOD;
1.266 + } else
1.267 + state = DP_S_MOD;
1.268 + break;
1.269 + case DP_S_MOD:
1.270 + switch (ch) {
1.271 + case 'h':
1.272 + cflags = DP_C_SHORT;
1.273 + ch = *format++;
1.274 + break;
1.275 + case 'l':
1.276 + if (*format == 'l') {
1.277 + cflags = DP_C_LLONG;
1.278 + format++;
1.279 + } else
1.280 + cflags = DP_C_LONG;
1.281 + ch = *format++;
1.282 + break;
1.283 + case 'q':
1.284 + cflags = DP_C_LLONG;
1.285 + ch = *format++;
1.286 + break;
1.287 + case 'L':
1.288 + cflags = DP_C_LDOUBLE;
1.289 + ch = *format++;
1.290 + break;
1.291 + default:
1.292 + break;
1.293 + }
1.294 + state = DP_S_CONV;
1.295 + break;
1.296 + case DP_S_CONV:
1.297 + switch (ch) {
1.298 + case 'd':
1.299 + case 'i':
1.300 + switch (cflags) {
1.301 + case DP_C_SHORT:
1.302 + value = (short int)va_arg(args, int);
1.303 + break;
1.304 + case DP_C_LONG:
1.305 + value = va_arg(args, long int);
1.306 + break;
1.307 + case DP_C_LLONG:
1.308 + value = va_arg(args, LLONG);
1.309 + break;
1.310 + default:
1.311 + value = va_arg(args, int);
1.312 + break;
1.313 + }
1.314 + fmtint(sbuffer, buffer, &currlen, maxlen,
1.315 + value, 10, min, max, flags);
1.316 + break;
1.317 + case 'X':
1.318 + flags |= DP_F_UP;
1.319 + /* FALLTHROUGH */
1.320 + case 'x':
1.321 + case 'o':
1.322 + case 'u':
1.323 + flags |= DP_F_UNSIGNED;
1.324 + switch (cflags) {
1.325 + case DP_C_SHORT:
1.326 + value = (unsigned short int)va_arg(args, unsigned int);
1.327 + break;
1.328 + case DP_C_LONG:
1.329 + value = (LLONG) va_arg(args,
1.330 + unsigned long int);
1.331 + break;
1.332 + case DP_C_LLONG:
1.333 + value = va_arg(args, unsigned LLONG);
1.334 + break;
1.335 + default:
1.336 + value = (LLONG) va_arg(args,
1.337 + unsigned int);
1.338 + break;
1.339 + }
1.340 + fmtint(sbuffer, buffer, &currlen, maxlen, value,
1.341 + ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
1.342 + min, max, flags);
1.343 + break;
1.344 + case 'f':
1.345 + if (cflags == DP_C_LDOUBLE)
1.346 + fvalue = va_arg(args, LDOUBLE);
1.347 + else
1.348 + fvalue = va_arg(args, double);
1.349 + fmtfp(sbuffer, buffer, &currlen, maxlen,
1.350 + fvalue, min, max, flags);
1.351 + break;
1.352 + case 'E':
1.353 + flags |= DP_F_UP;
1.354 + case 'e':
1.355 + if (cflags == DP_C_LDOUBLE)
1.356 + fvalue = va_arg(args, LDOUBLE);
1.357 + else
1.358 + fvalue = va_arg(args, double);
1.359 + break;
1.360 + case 'G':
1.361 + flags |= DP_F_UP;
1.362 + case 'g':
1.363 + if (cflags == DP_C_LDOUBLE)
1.364 + fvalue = va_arg(args, LDOUBLE);
1.365 + else
1.366 + fvalue = va_arg(args, double);
1.367 + break;
1.368 + case 'c':
1.369 + doapr_outch(sbuffer, buffer, &currlen, maxlen,
1.370 + va_arg(args, int));
1.371 + break;
1.372 + case 's':
1.373 + strvalue = va_arg(args, char *);
1.374 + if (max < 0) {
1.375 + if (buffer)
1.376 + max = INT_MAX;
1.377 + else
1.378 + max = *maxlen;
1.379 + }
1.380 + fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
1.381 + flags, min, max);
1.382 + break;
1.383 + case 'p':
1.384 + value = (long)va_arg(args, void *);
1.385 + fmtint(sbuffer, buffer, &currlen, maxlen,
1.386 + value, 16, min, max, flags|DP_F_NUM);
1.387 + break;
1.388 + case 'n': /* XXX */
1.389 + if (cflags == DP_C_SHORT) {
1.390 + short int *num;
1.391 + num = va_arg(args, short int *);
1.392 + *num = currlen;
1.393 + } else if (cflags == DP_C_LONG) { /* XXX */
1.394 + long int *num;
1.395 + num = va_arg(args, long int *);
1.396 + *num = (long int) currlen;
1.397 + } else if (cflags == DP_C_LLONG) { /* XXX */
1.398 + LLONG *num;
1.399 + num = va_arg(args, LLONG *);
1.400 + *num = (LLONG) currlen;
1.401 + } else {
1.402 + int *num;
1.403 + num = va_arg(args, int *);
1.404 + *num = currlen;
1.405 + }
1.406 + break;
1.407 + case '%':
1.408 + doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
1.409 + break;
1.410 + case 'w':
1.411 + /* not supported yet, treat as next char */
1.412 + ch = *format++;
1.413 + break;
1.414 + default:
1.415 + /* unknown, skip */
1.416 + break;
1.417 + }
1.418 + ch = *format++;
1.419 + state = DP_S_DEFAULT;
1.420 + flags = cflags = min = 0;
1.421 + max = -1;
1.422 + break;
1.423 + case DP_S_DONE:
1.424 + break;
1.425 + default:
1.426 + break;
1.427 + }
1.428 + }
1.429 + *truncated = (currlen > *maxlen - 1);
1.430 + if (*truncated)
1.431 + currlen = *maxlen - 1;
1.432 + doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
1.433 + *retlen = currlen - 1;
1.434 + return;
1.435 +}
1.436 +
1.437 +static void
1.438 +fmtstr(
1.439 + char **sbuffer,
1.440 + char **buffer,
1.441 + size_t *currlen,
1.442 + size_t *maxlen,
1.443 + const char *value,
1.444 + int flags,
1.445 + int min,
1.446 + int max)
1.447 +{
1.448 + int padlen, strln;
1.449 + int cnt = 0;
1.450 +
1.451 + if (value == 0)
1.452 + value = "<NULL>";
1.453 + for (strln = 0; value[strln]; ++strln)
1.454 + ;
1.455 + padlen = min - strln;
1.456 + if (padlen < 0)
1.457 + padlen = 0;
1.458 + if (flags & DP_F_MINUS)
1.459 + padlen = -padlen;
1.460 +
1.461 + while ((padlen > 0) && (cnt < max)) {
1.462 + doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
1.463 + --padlen;
1.464 + ++cnt;
1.465 + }
1.466 + while (*value && (cnt < max)) {
1.467 + doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
1.468 + ++cnt;
1.469 + }
1.470 + while ((padlen < 0) && (cnt < max)) {
1.471 + doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
1.472 + ++padlen;
1.473 + ++cnt;
1.474 + }
1.475 +}
1.476 +
1.477 +static void
1.478 +fmtint(
1.479 + char **sbuffer,
1.480 + char **buffer,
1.481 + size_t *currlen,
1.482 + size_t *maxlen,
1.483 + LLONG value,
1.484 + int base,
1.485 + int min,
1.486 + int max,
1.487 + int flags)
1.488 +{
1.489 + int signvalue = 0;
1.490 + const char *prefix = "";
1.491 + unsigned LLONG uvalue;
1.492 + char convert[DECIMAL_SIZE(value)+3];
1.493 + int place = 0;
1.494 + int spadlen = 0;
1.495 + int zpadlen = 0;
1.496 + int caps = 0;
1.497 +
1.498 + if (max < 0)
1.499 + max = 0;
1.500 + uvalue = value;
1.501 + if (!(flags & DP_F_UNSIGNED)) {
1.502 + if (value < 0) {
1.503 + signvalue = '-';
1.504 + uvalue = -value;
1.505 + } else if (flags & DP_F_PLUS)
1.506 + signvalue = '+';
1.507 + else if (flags & DP_F_SPACE)
1.508 + signvalue = ' ';
1.509 + }
1.510 + if (flags & DP_F_NUM) {
1.511 + if (base == 8) prefix = "0";
1.512 + if (base == 16) prefix = "0x";
1.513 + }
1.514 + if (flags & DP_F_UP)
1.515 + caps = 1;
1.516 + do {
1.517 + convert[place++] =
1.518 + (caps ? "0123456789ABCDEF" : "0123456789abcdef")
1.519 + [uvalue % (unsigned) base];
1.520 + uvalue = (uvalue / (unsigned) base);
1.521 + } while (uvalue && (place < (int)sizeof(convert)));
1.522 + if (place == sizeof(convert))
1.523 + place--;
1.524 + convert[place] = 0;
1.525 +
1.526 + zpadlen = max - place;
1.527 + spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
1.528 + if (zpadlen < 0)
1.529 + zpadlen = 0;
1.530 + if (spadlen < 0)
1.531 + spadlen = 0;
1.532 + if (flags & DP_F_ZERO) {
1.533 + zpadlen = OSSL_MAX(zpadlen, spadlen);
1.534 + spadlen = 0;
1.535 + }
1.536 + if (flags & DP_F_MINUS)
1.537 + spadlen = -spadlen;
1.538 +
1.539 + /* spaces */
1.540 + while (spadlen > 0) {
1.541 + doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
1.542 + --spadlen;
1.543 + }
1.544 +
1.545 + /* sign */
1.546 + if (signvalue)
1.547 + doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
1.548 +
1.549 + /* prefix */
1.550 + while (*prefix) {
1.551 + doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
1.552 + prefix++;
1.553 + }
1.554 +
1.555 + /* zeros */
1.556 + if (zpadlen > 0) {
1.557 + while (zpadlen > 0) {
1.558 + doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
1.559 + --zpadlen;
1.560 + }
1.561 + }
1.562 + /* digits */
1.563 + while (place > 0)
1.564 + doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
1.565 +
1.566 + /* left justified spaces */
1.567 + while (spadlen < 0) {
1.568 + doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
1.569 + ++spadlen;
1.570 + }
1.571 + return;
1.572 +}
1.573 +
1.574 +static LDOUBLE
1.575 +abs_val(LDOUBLE value)
1.576 +{
1.577 + LDOUBLE result = value;
1.578 + if (value < 0)
1.579 + result = -value;
1.580 + return result;
1.581 +}
1.582 +
1.583 +static LDOUBLE
1.584 +pow_10(int in_exp)
1.585 +{
1.586 + LDOUBLE result = 1;
1.587 + while (in_exp) {
1.588 + result *= 10;
1.589 + in_exp--;
1.590 + }
1.591 + return result;
1.592 +}
1.593 +
1.594 +static long
1.595 +roundv(LDOUBLE value)
1.596 +{
1.597 + long intpart;
1.598 + intpart = (long) value;
1.599 + value = value - intpart;
1.600 + if (value >= 0.5)
1.601 + intpart++;
1.602 + return intpart;
1.603 +}
1.604 +
1.605 +static void
1.606 +fmtfp(
1.607 + char **sbuffer,
1.608 + char **buffer,
1.609 + size_t *currlen,
1.610 + size_t *maxlen,
1.611 + LDOUBLE fvalue,
1.612 + int min,
1.613 + int max,
1.614 + int flags)
1.615 +{
1.616 + int signvalue = 0;
1.617 + LDOUBLE ufvalue;
1.618 + char iconvert[20];
1.619 + char fconvert[20];
1.620 + int iplace = 0;
1.621 + int fplace = 0;
1.622 + int padlen = 0;
1.623 + int zpadlen = 0;
1.624 + int caps = 0;
1.625 + long intpart;
1.626 + long fracpart;
1.627 + long max10;
1.628 +
1.629 + if (max < 0)
1.630 + max = 6;
1.631 + ufvalue = abs_val(fvalue);
1.632 + if (fvalue < 0)
1.633 + signvalue = '-';
1.634 + else if (flags & DP_F_PLUS)
1.635 + signvalue = '+';
1.636 + else if (flags & DP_F_SPACE)
1.637 + signvalue = ' ';
1.638 +
1.639 + intpart = (long)ufvalue;
1.640 +
1.641 + /* sorry, we only support 9 digits past the decimal because of our
1.642 + conversion method */
1.643 + if (max > 9)
1.644 + max = 9;
1.645 +
1.646 + /* we "cheat" by converting the fractional part to integer by
1.647 + multiplying by a factor of 10 */
1.648 + max10 = roundv(pow_10(max));
1.649 + fracpart = roundv(pow_10(max) * (ufvalue - intpart));
1.650 +
1.651 + if (fracpart >= max10) {
1.652 + intpart++;
1.653 + fracpart -= max10;
1.654 + }
1.655 +
1.656 + /* convert integer part */
1.657 + do {
1.658 + iconvert[iplace++] =
1.659 + (caps ? "0123456789ABCDEF"
1.660 + : "0123456789abcdef")[intpart % 10];
1.661 + intpart = (intpart / 10);
1.662 + } while (intpart && (iplace < (int)sizeof(iconvert)));
1.663 + if (iplace == sizeof iconvert)
1.664 + iplace--;
1.665 + iconvert[iplace] = 0;
1.666 +
1.667 + /* convert fractional part */
1.668 + do {
1.669 + fconvert[fplace++] =
1.670 + (caps ? "0123456789ABCDEF"
1.671 + : "0123456789abcdef")[fracpart % 10];
1.672 + fracpart = (fracpart / 10);
1.673 + } while (fplace < max);
1.674 + if (fplace == sizeof fconvert)
1.675 + fplace--;
1.676 + fconvert[fplace] = 0;
1.677 +
1.678 + /* -1 for decimal point, another -1 if we are printing a sign */
1.679 + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
1.680 + zpadlen = max - fplace;
1.681 + if (zpadlen < 0)
1.682 + zpadlen = 0;
1.683 + if (padlen < 0)
1.684 + padlen = 0;
1.685 + if (flags & DP_F_MINUS)
1.686 + padlen = -padlen;
1.687 +
1.688 + if ((flags & DP_F_ZERO) && (padlen > 0)) {
1.689 + if (signvalue) {
1.690 + doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
1.691 + --padlen;
1.692 + signvalue = 0;
1.693 + }
1.694 + while (padlen > 0) {
1.695 + doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
1.696 + --padlen;
1.697 + }
1.698 + }
1.699 + while (padlen > 0) {
1.700 + doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
1.701 + --padlen;
1.702 + }
1.703 + if (signvalue)
1.704 + doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
1.705 +
1.706 + while (iplace > 0)
1.707 + doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
1.708 +
1.709 + /*
1.710 + * Decimal point. This should probably use locale to find the correct
1.711 + * char to print out.
1.712 + */
1.713 + if (max > 0 || (flags & DP_F_NUM)) {
1.714 + doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
1.715 +
1.716 + while (fplace > 0)
1.717 + doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
1.718 + }
1.719 + while (zpadlen > 0) {
1.720 + doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
1.721 + --zpadlen;
1.722 + }
1.723 +
1.724 + while (padlen < 0) {
1.725 + doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
1.726 + ++padlen;
1.727 + }
1.728 +}
1.729 +
1.730 +static void
1.731 +doapr_outch(
1.732 + char **sbuffer,
1.733 + char **buffer,
1.734 + size_t *currlen,
1.735 + size_t *maxlen,
1.736 + int c)
1.737 +{
1.738 + /* If we haven't at least one buffer, someone has doe a big booboo */
1.739 + assert(*sbuffer != NULL || buffer != NULL);
1.740 +
1.741 + if (buffer) {
1.742 + while (*currlen >= *maxlen) {
1.743 + if (*buffer == NULL) {
1.744 + if (*maxlen == 0)
1.745 + *maxlen = 1024;
1.746 + *buffer = OPENSSL_malloc(*maxlen);
1.747 + if (*currlen > 0) {
1.748 + assert(*sbuffer != NULL);
1.749 + memcpy(*buffer, *sbuffer, *currlen);
1.750 + }
1.751 + *sbuffer = NULL;
1.752 + } else {
1.753 + *maxlen += 1024;
1.754 + *buffer = OPENSSL_realloc(*buffer, *maxlen);
1.755 + }
1.756 + }
1.757 + /* What to do if *buffer is NULL? */
1.758 + assert(*sbuffer != NULL || *buffer != NULL);
1.759 + }
1.760 +
1.761 + if (*currlen < *maxlen) {
1.762 + if (*sbuffer)
1.763 + (*sbuffer)[(*currlen)++] = (char)c;
1.764 + else
1.765 + (*buffer)[(*currlen)++] = (char)c;
1.766 + }
1.767 +
1.768 + return;
1.769 +}
1.770 +
1.771 +/***************************************************************************/
1.772 +
1.773 +EXPORT_C int BIO_printf (BIO *bio, const char *format, ...)
1.774 + {
1.775 + va_list args;
1.776 + int ret;
1.777 +
1.778 + va_start(args, format);
1.779 +
1.780 + ret = BIO_vprintf(bio, format, args);
1.781 +
1.782 + va_end(args);
1.783 + return(ret);
1.784 + }
1.785 +
1.786 +EXPORT_C int BIO_vprintf (BIO *bio, const char *format, va_list args)
1.787 + {
1.788 + int ret;
1.789 + size_t retlen;
1.790 + #ifndef SYMBIAN
1.791 + char hugebuf[1024*2]; /* Was previously 10k, which is unreasonable
1.792 + in small-stack environments, like threads
1.793 + or DOS programs. */
1.794 +#else
1.795 + char hugebuf[512];
1.796 +#endif
1.797 + char *hugebufp = hugebuf;
1.798 + size_t hugebufsize = sizeof(hugebuf);
1.799 + char *dynbuf = NULL;
1.800 + int ignored;
1.801 +
1.802 + dynbuf = NULL;
1.803 + CRYPTO_push_info("doapr()");
1.804 + _dopr(&hugebufp, &dynbuf, &hugebufsize,
1.805 + &retlen, &ignored, format, args);
1.806 + if (dynbuf)
1.807 + {
1.808 + ret=BIO_write(bio, dynbuf, (int)retlen);
1.809 + OPENSSL_free(dynbuf);
1.810 + }
1.811 + else
1.812 + {
1.813 + ret=BIO_write(bio, hugebuf, (int)retlen);
1.814 + }
1.815 + CRYPTO_pop_info();
1.816 + return(ret);
1.817 + }
1.818 +
1.819 +/* As snprintf is not available everywhere, we provide our own implementation.
1.820 + * This function has nothing to do with BIOs, but it's closely related
1.821 + * to BIO_printf, and we need *some* name prefix ...
1.822 + * (XXX the function should be renamed, but to what?) */
1.823 +EXPORT_C int BIO_snprintf(char *buf, size_t n, const char *format, ...)
1.824 + {
1.825 + va_list args;
1.826 + int ret;
1.827 +
1.828 + va_start(args, format);
1.829 +
1.830 + ret = BIO_vsnprintf(buf, n, format, args);
1.831 +
1.832 + va_end(args);
1.833 + return(ret);
1.834 + }
1.835 +
1.836 +EXPORT_C int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
1.837 + {
1.838 + size_t retlen;
1.839 + int truncated;
1.840 +
1.841 + _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
1.842 +
1.843 + if (truncated)
1.844 + /* In case of truncation, return -1 like traditional snprintf.
1.845 + * (Current drafts for ISO/IEC 9899 say snprintf should return
1.846 + * the number of characters that would have been written,
1.847 + * had the buffer been large enough.) */
1.848 + return -1;
1.849 + else
1.850 + return (retlen <= INT_MAX) ? (int)retlen : -1;
1.851 + }