blob: d58b0fb6ec2d3aac59be6fff4c3e123e011a6dfe (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include "pretty_binary.h"
#include <stdexcept>
#include <sstream>
std::string pretty_binary_string_reverse(const std::string& pretty)
{
size_t i = 0;
auto raise = [&](size_t failpos) {
std::ostringstream ss;
ss << "invalid char at pos " << failpos << " of " << pretty;
throw std::invalid_argument(ss.str());
};
auto hexdigit = [&](unsigned char c) -> int32_t {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
return -1;
};
auto require = [&](unsigned char c) {
if (i >= pretty.length() || pretty[i] != c) {
raise(i);
}
++i;
};
std::string bin;
if (pretty.empty())
return bin;
bin.reserve(pretty.length());
bool strmode;
switch (pretty[0]) {
case '\'':
++i;
strmode = true;
break;
case '0':
++i;
require('x');
if (i == pretty.length()) {
raise(i);
}
strmode = false;
break;
default:
raise(0);
}
for (; i < pretty.length();) {
if (strmode) {
if (pretty[i] == '\'') {
if (i + 1 < pretty.length() && pretty[i + 1] == '\'') {
bin.push_back('\'');
i += 2;
} else {
++i;
strmode = false;
if (i + 1 < pretty.length()) {
require('0');
require('x');
if (i == pretty.length()) {
raise(i);
}
}
}
} else {
bin.push_back(pretty[i]);
++i;
}
} else {
if (pretty[i] != '\'') {
int32_t hex0 = hexdigit(pretty[i]);
if (hex0 < 0) {
raise(i);
}
++i;
if (i >= pretty.length()) {
raise(i);
}
int32_t hex1 = hexdigit(pretty[i]);
if (hex1 < 0) {
raise(i);
}
bin.push_back(hex0 * 0x10 + hex1);
++i;
} else {
strmode = true;
++i;
}
}
}
if (strmode)
raise(i);
return bin;
}
|