1 /*
 2  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
 3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 4  *
 5  * This code is free software; you can redistribute it and/or modify it
 6  * under the terms of the GNU General Public License version 2 only, as
 7  * published by the Free Software Foundation.  Oracle designates this
 8  * particular file as subject to the "Classpath" exception as provided
 9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #include <sstream>
27 #include <iomanip>
28 
29 
30 #include "hex.h"
31 
32 
33 void Hex::ascii(std::ostream &s, char c) {
34     if (::iscntrl(c)) {
35         if (c == '\a') {
36             s << "\\a ";
37         } else if (c == '\r') {
38             s << "\\r ";
39         } else if (c == '\n') {
40             s << "\\n ";
41         } else if (c == '\t') {
42             s << "\\t ";
43         } else {
44             s << "?? ";
45         }
46     } else {
47         s << c << "  ";
48     }
49 }
50 
51 void Hex::hex(std::ostream &s, char c) {
52     s << std::hex << std::setw(2) << std::setfill('0') << std::uppercase << (c & 0xff) << " ";
53 }
54 
55 void Hex::bytes(std::ostream &s, char *p, size_t len, std::function<void(std::ostream &)> prefix) {
56     for (int i = 0; i < len; i++) {
57         if ((i % 16) == 0) {
58             if (i > 0) {
59                 s << "  ";
60                 for (int c = i - 16; c < i; c++) {
61                     ascii(s, p[c]);
62                 }
63             }
64             s << std::endl;
65             prefix(s);
66             s << std::hex << std::setw(6) << std::setfill('0') << i << " ";
67         }
68         hex(s, p[i]);
69     }
70 
71     if ((len % 16) == 0) {
72         s << "  ";
73         for (int c = len - 16; c < len; c++) {
74             ascii(s, p[c]);
75         }
76     } else {
77         for (int v = len % 16; v < 16; v++) {
78             s << "   ";
79         }
80         s << "  ";
81         for (int c = len - (len % 16); c < len; c++) {
82             ascii(s, p[c]);
83         }
84     }
85 }