blob: 8de91be0b02538fc9a932c961e936eccaddfc00a [file] [log] [blame]
Matt Spinler711d51d2019-11-06 09:36:51 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Aatir186ce8c2019-10-20 15:13:39 -050016#include "hexdump.hpp"
17
18#include <stdio.h>
19
20#include <cstring>
21#include <sstream>
22#include <string>
23
24namespace openpower
25{
26namespace pels
27{
28
29std::string escapeJSON(const std::string& input)
30{
31 std::string output;
32 output.reserve(input.length());
33
34 for (const auto c : input)
35 {
36 switch (c)
37 {
38 case '"':
39 output += "\\\"";
40 break;
41 case '/':
42 output += "\\/";
43 break;
44 case '\b':
45 output += "\\b";
46 break;
47 case '\f':
48 output += "\\f";
49 break;
50 case '\n':
51 output += "\\n";
52 break;
53 case '\r':
54 output += "\\r";
55 break;
56 case '\t':
57 output += "\\t";
58 break;
59 case '\\':
60 output += "\\\\";
61 break;
62 default:
63 output += c;
64 break;
65 }
66 }
67
68 return output;
69}
70char* dumpHex(const void* data, size_t size)
71{
72 const int symbolSize = 100;
73 char* buffer = (char*)calloc(10 * size, sizeof(char));
74 char* symbol = (char*)calloc(symbolSize, sizeof(char));
75 char ascii[17];
76 size_t i, j;
77 ascii[16] = '\0';
78 for (i = 0; i < size; ++i)
79 {
80 if (i % 16 == 0)
81 {
82 strcat(buffer, "\"");
83 }
84 snprintf(symbol, symbolSize, "%02X ", ((unsigned char*)data)[i]);
85 strcat(buffer, symbol);
86 memset(symbol, 0, strlen(symbol));
87 if (((unsigned char*)data)[i] >= ' ' &&
88 ((unsigned char*)data)[i] <= '~')
89 {
90 ascii[i % 16] = ((unsigned char*)data)[i];
91 }
92 else
93 {
94 ascii[i % 16] = '.';
95 }
96 if ((i + 1) % 8 == 0 || i + 1 == size)
97 {
98 std::string asciiString(ascii);
99 asciiString = escapeJSON(asciiString);
100 const char* asciiToPrint = asciiString.c_str();
101 strcat(buffer, " ");
102 if ((i + 1) % 16 == 0)
103 {
104 if (i + 1 != size)
105 {
106 snprintf(symbol, symbolSize, "| %s\", \n ", asciiToPrint);
107 }
108 else
109 {
110 snprintf(symbol, symbolSize, "| %s\" \n ", asciiToPrint);
111 }
112 strcat(buffer, symbol);
113 memset(symbol, 0, strlen(symbol));
114 }
115 else if (i + 1 == size)
116 {
117 ascii[(i + 1) % 16] = '\0';
118 if ((i + 1) % 16 <= 8)
119 {
120 strcat(buffer, " ");
121 }
122 for (j = (i + 1) % 16; j < 16; ++j)
123 {
124 strcat(buffer, " ");
125 }
126 snprintf(symbol, symbolSize, "| %s\" \n ", asciiToPrint);
127 strcat(buffer, symbol);
128 memset(symbol, 0, strlen(symbol));
129 }
130 }
131 }
132 free(symbol);
133 return buffer;
134}
135} // namespace pels
136} // namespace openpower