blob: 08c816c1d77b0d623ad67573e8b01956fcdae489 [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 */
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +080016#include "json_utils.hpp"
Aatir186ce8c2019-10-20 15:13:39 -050017
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}
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +080070char* dumpHex(const void* data, size_t size, size_t indentCount, bool toJson)
Aatir186ce8c2019-10-20 15:13:39 -050071{
72 const int symbolSize = 100;
Matt Spinler4220a152020-03-26 10:18:09 -050073 std::string jsonIndent(indentLevel * indentCount, 0x20);
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +080074 if (toJson)
75 {
76 jsonIndent.append("\"");
77 }
Harisuddin Mohamed Isa097ad122020-06-11 21:19:41 +080078 char* buffer = (char*)calloc(std::max(70, 10 * (int)size), sizeof(char));
Aatir186ce8c2019-10-20 15:13:39 -050079 char* symbol = (char*)calloc(symbolSize, sizeof(char));
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +080080 char* byteCount = (char*)calloc(11, sizeof(char));
Aatir186ce8c2019-10-20 15:13:39 -050081 char ascii[17];
82 size_t i, j;
83 ascii[16] = '\0';
84 for (i = 0; i < size; ++i)
85 {
86 if (i % 16 == 0)
87 {
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +080088 if (!toJson)
89 {
90 snprintf(byteCount, 11, "%08X ", static_cast<uint32_t>(i));
91 strcat(buffer, byteCount);
92 }
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +080093 strcat(buffer, jsonIndent.c_str());
Aatir186ce8c2019-10-20 15:13:39 -050094 }
95 snprintf(symbol, symbolSize, "%02X ", ((unsigned char*)data)[i]);
96 strcat(buffer, symbol);
97 memset(symbol, 0, strlen(symbol));
98 if (((unsigned char*)data)[i] >= ' ' &&
99 ((unsigned char*)data)[i] <= '~')
100 {
101 ascii[i % 16] = ((unsigned char*)data)[i];
102 }
103 else
104 {
105 ascii[i % 16] = '.';
106 }
107 if ((i + 1) % 8 == 0 || i + 1 == size)
108 {
109 std::string asciiString(ascii);
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800110 if (toJson)
111 {
112 asciiString = escapeJSON(asciiString);
113 }
Aatir186ce8c2019-10-20 15:13:39 -0500114 strcat(buffer, " ");
115 if ((i + 1) % 16 == 0)
116 {
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800117 if (i + 1 != size && toJson)
Aatir186ce8c2019-10-20 15:13:39 -0500118 {
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800119 snprintf(symbol, symbolSize, "| %s\",\n",
120 asciiString.c_str());
121 }
122 else if (toJson)
123 {
124 snprintf(symbol, symbolSize, "| %s\"\n",
125 asciiString.c_str());
Aatir186ce8c2019-10-20 15:13:39 -0500126 }
127 else
128 {
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800129 snprintf(symbol, symbolSize, "| %s\n",
130 asciiString.c_str());
Aatir186ce8c2019-10-20 15:13:39 -0500131 }
132 strcat(buffer, symbol);
133 memset(symbol, 0, strlen(symbol));
134 }
135 else if (i + 1 == size)
136 {
137 ascii[(i + 1) % 16] = '\0';
138 if ((i + 1) % 16 <= 8)
139 {
140 strcat(buffer, " ");
141 }
142 for (j = (i + 1) % 16; j < 16; ++j)
143 {
144 strcat(buffer, " ");
145 }
Aatir6a538622019-11-11 13:13:42 -0600146 std::string asciiString2(ascii);
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800147 if (toJson)
148 {
149 asciiString2 = escapeJSON(asciiString2);
150 snprintf(symbol, symbolSize, "| %s\"\n",
151 asciiString2.c_str());
152 }
153 else
154 {
155 snprintf(symbol, symbolSize, "| %s\n",
156 asciiString2.c_str());
157 }
158
Aatir186ce8c2019-10-20 15:13:39 -0500159 strcat(buffer, symbol);
160 memset(symbol, 0, strlen(symbol));
161 }
162 }
163 }
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800164 free(byteCount);
Aatir186ce8c2019-10-20 15:13:39 -0500165 free(symbol);
166 return buffer;
167}
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +0800168
169void jsonInsert(std::string& jsonStr, const std::string& fieldName,
Matt Spinler45796e82022-07-01 11:25:27 -0500170 const std::string& fieldValue, uint8_t indentCount)
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +0800171{
Patrick Williams2544b412022-10-04 08:41:06 -0500172 const int8_t spacesToAppend = colAlign - (indentCount * indentLevel) -
173 fieldName.length() - 3;
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +0800174 const std::string jsonIndent(indentCount * indentLevel, 0x20);
175 jsonStr.append(jsonIndent + "\"" + fieldName + "\":");
Harisuddin Mohamed Isac32e5512020-02-06 18:05:21 +0800176 if (spacesToAppend >= 0)
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +0800177 {
178 jsonStr.append(spacesToAppend, 0x20);
179 }
180 else
181 {
182 jsonStr.append(1, 0x20);
183 }
184 jsonStr.append("\"" + fieldValue + "\",\n");
185}
186
187void jsonInsertArray(std::string& jsonStr, const std::string& fieldName,
Matt Spinler45796e82022-07-01 11:25:27 -0500188 const std::vector<std::string>& values,
189 uint8_t indentCount)
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +0800190{
191 const std::string jsonIndent(indentCount * indentLevel, 0x20);
192 if (!values.empty())
193 {
194 jsonStr.append(jsonIndent + "\"" + fieldName + "\": [\n");
195 for (size_t i = 0; i < values.size(); i++)
196 {
197 jsonStr.append(colAlign, 0x20);
198 if (i == values.size() - 1)
199 {
200 jsonStr.append("\"" + values[i] + "\"\n");
201 }
202 else
203 {
204 jsonStr.append("\"" + values[i] + "\",\n");
205 }
206 }
207 jsonStr.append(jsonIndent + "],\n");
208 }
209 else
210 {
Patrick Williams2544b412022-10-04 08:41:06 -0500211 const int8_t spacesToAppend = colAlign - (indentCount * indentLevel) -
212 fieldName.length() - 3;
Harisuddin Mohamed Isa600d15a2019-12-20 12:42:26 +0800213 jsonStr.append(jsonIndent + "\"" + fieldName + "\":");
214 if (spacesToAppend > 0)
215 {
216 jsonStr.append(spacesToAppend, 0x20);
217 }
218 else
219 {
220 jsonStr.append(1, 0x20);
221 }
222 jsonStr.append("[],\n");
223 }
224}
Harisuddin Mohamed Isae2d1bf32020-02-06 17:32:38 +0800225
226std::string trimEnd(std::string s)
227{
228 const char* t = " \t\n\r\f\v";
229 if (s.find_last_not_of(t) != std::string::npos)
230 {
231 s.erase(s.find_last_not_of(t) + 1);
232 }
233 return s;
234}
Aatir186ce8c2019-10-20 15:13:39 -0500235} // namespace pels
236} // namespace openpower