OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 #include "debugger/base/debug_blob.h" | |
5 #include <ctype.h> | |
6 #include <algorithm> | |
7 #include <string> | |
8 | |
9 namespace debug { | |
10 Blob::Blob() { | |
11 } | |
12 | |
13 Blob::Blob(const Blob& other) { | |
14 value_ = other.value_; | |
15 } | |
16 | |
17 Blob::Blob(const void* buff, size_t buff_sz) { | |
18 const uint8_t* char_buff = static_cast<const uint8_t*>(buff); | |
19 for (size_t i = 0; i < buff_sz; i++ ) | |
20 PushBack(*char_buff++); | |
21 } | |
22 | |
23 Blob& Blob::FromString(const std::string& str) { | |
24 Clear(); | |
25 for (size_t i = 0; i < str.size(); i++ ) | |
26 PushBack(str[i]); | |
27 return *this; | |
28 } | |
29 | |
30 Blob::~Blob() { | |
31 } | |
32 | |
33 Blob& Blob::operator = (const Blob& other) { | |
34 value_ = other.value_; | |
35 return *this; | |
36 } | |
37 | |
38 bool Blob::operator == (const Blob& other) const { | |
39 return value_ == other.value_; | |
40 } | |
41 | |
42 uint8_t Blob::operator[] (size_t position) const { | |
43 return value_[position]; | |
44 } | |
45 | |
46 uint8_t& Blob::operator[] (size_t position) { | |
47 return value_[position]; | |
48 } | |
49 | |
50 uint8_t Blob::GetAt(size_t position) const { | |
51 return value_[position]; | |
52 } | |
53 | |
54 uint8_t Blob::Front() const { | |
55 return value_.front(); | |
56 } | |
57 | |
58 uint8_t Blob::Back() const { | |
59 return value_.back(); | |
60 } | |
61 | |
62 uint8_t Blob::PopFront() { | |
63 uint8_t c = value_.front(); | |
64 value_.pop_front(); | |
65 return c; | |
66 } | |
67 | |
68 uint8_t Blob::PopBack() { | |
69 uint8_t c = value_.back(); | |
70 value_.pop_back(); | |
71 return c; | |
72 } | |
73 | |
74 void Blob::PushFront(uint8_t c) { | |
75 value_.push_front(c); | |
76 } | |
77 | |
78 void Blob::PushBack(uint8_t c) { | |
79 value_.push_back(c); | |
80 } | |
81 | |
82 void Blob::Clear() { | |
83 value_.clear(); | |
84 } | |
85 | |
86 std::string Blob::ToString() const { | |
87 std::string result; | |
88 for (size_t i = 0; i < size(); i++) | |
89 result.append(1, value_[i]); | |
90 return result; | |
91 } | |
92 | |
93 std::string Blob::ToHexString() const { | |
94 std::string result; | |
95 size_t num = size(); | |
96 for (size_t i = 0; i < num; i++) { | |
97 char c = GetHexDigit(value_[i], 1); | |
98 result.append(1, c); | |
99 c = GetHexDigit(value_[i], 0); | |
100 result.append(1, c); | |
101 } | |
102 return result; | |
103 } | |
104 | |
105 std::string Blob::ToHexStringNoLeadingZeroes() const { | |
106 std::string result = ToHexString(); | |
107 while (result[0] == '0') | |
108 result.erase(0, 1); | |
109 return result; | |
110 } | |
111 | |
112 size_t Blob::Peek(size_t offset, void* buff, size_t buff_sz) const { | |
113 uint8_t* out = static_cast<uint8_t*>(buff); | |
114 size_t copied_bytes_ts = 0; | |
115 for (size_t i = 0; i < buff_sz; i++) { | |
116 size_t pos = offset + i; | |
117 if (pos >= size()) | |
118 break; | |
119 out[i] = GetAt(pos); | |
120 copied_bytes_ts++; | |
121 } | |
122 return copied_bytes_ts; | |
123 } | |
124 | |
125 bool Blob::FromHexString(const std::string& hex_str) { | |
126 Clear(); | |
127 size_t num = hex_str.size(); | |
128 for (size_t i = num; i > 0; i -= 2) { | |
129 if (isspace(hex_str[i - 1])) { | |
130 i++; | |
131 } else if (i >= 2) { | |
132 unsigned int c1 = 0; | |
133 unsigned int c2 = 0; | |
134 if (!HexCharToInt(hex_str[i - 1], &c1)) return false; | |
135 if (!HexCharToInt(hex_str[i - 2], &c2)) return false; | |
136 unsigned int c = c1 + (c2 << 4); | |
137 PushFront(c); | |
138 } else { | |
139 unsigned int c = 0; | |
140 if (!HexCharToInt(hex_str[i - 1], &c)) return false; | |
141 PushFront(c); | |
142 break; | |
143 } | |
144 } | |
145 return true; | |
146 } | |
147 | |
148 void Blob::Append(const Blob& blob) { | |
149 for (size_t i = 0; i < blob.size(); i++) | |
150 PushBack(blob[i]); | |
151 } | |
152 | |
153 void Blob::Reverse() { | |
154 std::reverse(value_.begin(), value_.end()); | |
155 } | |
156 | |
157 void Blob::Split(const Blob& delimiters, std::deque<Blob>* tokens) const { | |
158 tokens->clear(); | |
159 Blob token; | |
160 std::deque<uint8_t>::const_iterator it = value_.begin(); | |
161 while (value_.end() != it) { | |
162 uint8_t c = *it++; | |
163 if (delimiters.HasByte(c)) { | |
164 tokens->push_back(token); | |
165 token.Clear(); | |
166 } else { | |
167 token.PushBack(c); | |
168 } | |
169 } | |
170 if (0 != token.size()) | |
171 tokens->push_back(token); | |
172 } | |
173 | |
174 void Blob::PopMatchingBytesFromFront(const Blob& bytes) { | |
175 while (size()) { | |
176 char c = Front(); | |
177 if (!bytes.HasByte(c)) | |
178 break; | |
179 else | |
180 PopFront(); | |
181 } | |
182 } | |
183 | |
184 debug::Blob Blob::PopBlobFromFrontUntilBytes(const Blob& bytes) { | |
185 debug::Blob result; | |
186 while (size()) { | |
187 char c = PopFront(); | |
188 if (bytes.HasByte(c)) | |
189 break; | |
190 else | |
191 result.PushBack(c); | |
192 } | |
193 return result; | |
194 } | |
195 | |
196 bool Blob::HasByte(char c) const { | |
197 for (size_t i = 0; i < size(); i++) | |
198 if (c == value_[i]) | |
199 return true; | |
200 return false; | |
201 } | |
202 | |
203 bool Blob::HexCharToInt(unsigned char c, unsigned int* result) { | |
204 if (('0' <= c) && ('9' >= c)) { | |
205 *result = c - '0'; | |
206 } else if (('A' <= c) && ('F' >= c)) { | |
207 *result = c - 'A' + 10; | |
208 } else if (('a' <= c) && ('f' >= c)) { | |
209 *result = c - 'a' + 10; | |
210 } else { | |
211 return false; | |
212 } | |
213 return true; | |
214 } | |
215 | |
216 char Blob::GetHexDigit(unsigned int value, int digit_position) { | |
217 const char* kDigitStrings = "0123456789abcdef"; | |
218 unsigned int digit = (value >> (4 * digit_position)) & 0xF; | |
219 return kDigitStrings[digit]; | |
220 } | |
221 } // namespace debug | |
222 | |
OLD | NEW |