int zlog_buf_vprintf(zlog_buf_t * a_buf, const char *format, va_list args) { va_list ap; size_t size_left; int nwrite; if (!a_buf->start) { zc_error("pre-use of zlog_buf_resize fail, so can't convert"); return -1; } va_copy(ap, args); size_left = a_buf->end_plus_1 - a_buf->tail; nwrite = vsnprintf(a_buf->tail, size_left, format, ap); if (nwrite >= 0 && nwrite < size_left) { a_buf->tail += nwrite; //*(a_buf->tail) = '\0'; return 0; } else if (nwrite < 0) { zc_error("vsnprintf fail, errno[%d]", errno); zc_error("nwrite[%d], size_left[%ld], format[%s]", nwrite, size_left, format); return -1; } else if (nwrite >= size_left) { int rc; //zc_debug("nwrite[%d]>=size_left[%ld],format[%s],resize", nwrite, size_left, format); rc = zlog_buf_resize(a_buf, nwrite - size_left + 1); if (rc > 0) { zc_error("conf limit to %ld, can't extend, so truncate", a_buf->size_max); va_copy(ap, args); size_left = a_buf->end_plus_1 - a_buf->tail; vsnprintf(a_buf->tail, size_left, format, ap); a_buf->tail += size_left - 1; //*(a_buf->tail) = '\0'; zlog_buf_truncate(a_buf); return 1; } else if (rc < 0) { zc_error("zlog_buf_resize fail"); return -1; } else { //zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real); va_copy(ap, args); size_left = a_buf->end_plus_1 - a_buf->tail; nwrite = vsnprintf(a_buf->tail, size_left, format, ap); if (nwrite < 0) { zc_error("vsnprintf fail, errno[%d]", errno); zc_error("nwrite[%d], size_left[%ld], format[%s]", nwrite, size_left, format); return -1; } else { a_buf->tail += nwrite; //*(a_buf->tail) = '\0'; return 0; } } } return 0; }
int zlog_buf_printf_dec64(zlog_buf_t * a_buf, uint64_t ui64, int width) { unsigned char *p; char *q; unsigned char tmp[ZLOG_INT64_LEN + 1]; size_t num_len, zero_len, out_len; uint32_t ui32; if (a_buf->size_real < 0) { zc_error("pre-use of zlog_buf_resize fail, so can't convert"); return -1; } p = tmp + ZLOG_INT64_LEN; if (ui64 <= ZLOG_MAX_UINT32_VALUE) { /* * To divide 64-bit numbers and to find remainders * on the x86 platform gcc and icc call the libc functions * [u]divdi3() and [u]moddi3(), they call another function * in its turn. On FreeBSD it is the qdivrem() function, * its source code is about 170 lines of the code. * The glibc counterpart is about 150 lines of the code. * * For 32-bit numbers and some divisors gcc and icc use * a inlined multiplication and shifts. For example, * unsigned "i32 / 10" is compiled to * * (i32 * 0xCCCCCCCD) >> 35 */ ui32 = (uint32_t) ui64; do { *--p = (unsigned char) (ui32 % 10 + '0'); } while (ui32 /= 10); } else { do { *--p = (unsigned char) (ui64 % 10 + '0'); } while (ui64 /= 10); } /* zero or space padding */ num_len = (tmp + ZLOG_INT64_LEN) - p; if (width > num_len) { zero_len = width - num_len; out_len = width; } else { zero_len = 0; out_len = num_len; } if ((q = a_buf->tail + out_len) > a_buf->end) { int rc; //zc_debug("size_left not enough, resize"); rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail)); if (rc > 0) { size_t len_left; zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max); len_left = a_buf->end - a_buf->tail; if (len_left <= zero_len) { zero_len = len_left; num_len = 0; } else if (len_left > zero_len) { /* zero_len not changed */ num_len = len_left - zero_len; } memset(a_buf->tail, '0', zero_len); memcpy(a_buf->tail + zero_len, p, num_len); a_buf->tail += len_left; //*(a_buf->tail) = '\0'; zlog_buf_truncate(a_buf); return 1; } else if (rc < 0) { zc_error("zlog_buf_resize fail"); return -1; } else { //zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real); q = a_buf->tail + out_len; /* re-calculate p*/ } } memset(a_buf->tail, '0', zero_len); memcpy(a_buf->tail + zero_len, p, num_len); a_buf->tail = q; //*(a_buf->tail) = '\0'; return 0; }
/* if width > num_len, 0 padding, else output num */ int zlog_buf_printf_dec32(zlog_buf_t * a_buf, uint32_t ui32, int width) { unsigned char *p; char *q; unsigned char tmp[ZLOG_INT32_LEN + 1]; size_t num_len, zero_len, out_len; if (a_buf->size_real < 0) { zc_error("pre-use of zlog_buf_resize fail, so can't convert"); return -1; } p = tmp + ZLOG_INT32_LEN; do { *--p = (unsigned char) (ui32 % 10 + '0'); } while (ui32 /= 10); /* zero or space padding */ num_len = (tmp + ZLOG_INT32_LEN) - p; if (width > num_len) { zero_len = width - num_len; out_len = width; } else { zero_len = 0; out_len = num_len; } if ((q = a_buf->tail + out_len) > a_buf->end) { int rc; //zc_debug("size_left not enough, resize"); rc = zlog_buf_resize(a_buf, out_len - (a_buf->end - a_buf->tail)); if (rc > 0) { size_t len_left; zc_error("conf limit to %ld, can't extend, so output", a_buf->size_max); len_left = a_buf->end - a_buf->tail; if (len_left <= zero_len) { zero_len = len_left; num_len = 0; } else if (len_left > zero_len) { /* zero_len not changed */ num_len = len_left - zero_len; } memset(a_buf->tail, '0', zero_len); memcpy(a_buf->tail + zero_len, p, num_len); a_buf->tail += len_left; //*(a_buf->tail) = '\0'; zlog_buf_truncate(a_buf); return 1; } else if (rc < 0) { zc_error("zlog_buf_resize fail"); return -1; } else { //zc_debug("zlog_buf_resize succ, to[%ld]", a_buf->size_real); q = a_buf->tail + out_len; /* re-calculate p*/ } } memset(a_buf->tail, '0', zero_len); memcpy(a_buf->tail + zero_len, p, num_len); a_buf->tail = q; //*(a_buf->tail) = '\0'; return 0; }