lsquic_util.c revision 50aadb33
1/* Copyright (c) 2017 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * Utility functions
4 */
5
6#include <ctype.h>
7#include <stdint.h>
8#include <stdio.h>
9#include <string.h>
10#include <sys/time.h>
11
12#include "lsquic_int_types.h"
13#include "lsquic_util.h"
14
15
16lsquic_time_t
17lsquic_time_now (void)
18{
19    struct timeval tv;
20    (void) gettimeofday(&tv, NULL);
21    return (lsquic_time_t) tv.tv_sec * 1000000 + tv.tv_usec;
22}
23
24
25int
26lsquic_is_zero (const void *pbuf, size_t bufsz)
27{
28    const unsigned char *buf, *end;
29    const unsigned long *buf_ul;
30    unsigned n_ul;
31    unsigned long n_non_zero;
32
33    buf = pbuf;
34    end = buf + bufsz;
35    buf_ul = (unsigned long *) buf;
36    n_ul = bufsz / sizeof(buf_ul[0]);
37    buf += n_ul * sizeof(buf_ul[0]);
38    n_non_zero = 0;
39
40    while (n_ul--)
41        n_non_zero |= buf_ul[n_ul];
42
43    while (buf < end)
44        n_non_zero |= *buf++;
45
46    return n_non_zero == 0;
47}
48
49
50/* XXX this function uses static buffer.  Replace it with hexdump() if possible */
51char *get_bin_str(const void *s, size_t len, size_t max_display_len)
52{
53    const unsigned char *p, *pEnd;
54    char *pOutput;
55    size_t lenOrg = len;
56    static char str[512 * 2 + 40] = {0};
57
58    /**
59     * We alloc fixed size buffer, at most max_display_len is 512
60     */
61    size_t fit_display_len = (max_display_len > 512 ? 512 : max_display_len);
62    if (len > fit_display_len)
63        len = fit_display_len;
64
65    pOutput = &str[0] + sprintf(str, "(%zd/%zd)=0x", len, lenOrg);
66
67    for(p = s, pEnd = s + len; p < pEnd; ++p)
68    {
69        sprintf(pOutput, "%02X", *p);
70        pOutput += 2;
71    }
72    if (lenOrg > len)
73    {
74        sprintf(pOutput, "...");
75        pOutput += 3;
76    }
77    return str;
78}
79
80
81size_t
82hexdump (const void *src_void, size_t src_sz, char *out, size_t out_sz)
83{
84/* Ruler:
85 *
86      6                       31                        57              73
87      |                        |                         |               |
880000  00 01 02 03 04 05 06 07  08 09 0A 0B 0C 0D 0E 0F  |................|
89 *
90 */
91#define LINE_SIZE (74 + 1 /* newline */)
92    const unsigned char       *src     = src_void;
93    const unsigned char *const src_end = src + src_sz;
94    char *const                out_end = out + out_sz;
95    unsigned line = 0;
96
97    while (src < src_end && out_end - out >= LINE_SIZE)
98    {
99        const unsigned char *limit = src + 16;
100        if (limit > src_end)
101            limit = src_end;
102        unsigned hex_off   = 6;
103        unsigned alpha_off = 57;
104        sprintf(out, "%04x", line++);
105        out[4] = ' ';
106        out[5] = ' ';
107        while (src < limit)
108        {
109            sprintf(out + hex_off, "%02X ", *src);
110            sprintf(out + alpha_off, "%c", isprint(*src) ? *src : '.');
111            hex_off += 3;
112            out[hex_off] = ' ';
113            hex_off += 30 == hex_off;
114            out[hex_off] = ' ';
115            ++alpha_off;
116            out[alpha_off] = ' ';
117            ++src;
118        }
119        memset(out + hex_off,   ' ', 56 - hex_off);
120        memset(out + alpha_off, '.', 73 - alpha_off);
121        out[56] = '|';
122        out[73] = '|';
123        out[74] = '\n';
124        out += LINE_SIZE;
125    }
126
127    if (out < out_end)
128        *out = '\0';
129    else
130        out_end[-1] = '\0';
131
132    return out + out_sz - out_end;
133}
134