1 //===-- StringExtractor.cpp -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "Utility/StringExtractor.h"
16 // Other libraries and framework includes
20 g_hex_ascii_to_hex_integer[256] = {
22 255, 255, 255, 255, 255, 255, 255, 255,
23 255, 255, 255, 255, 255, 255, 255, 255,
24 255, 255, 255, 255, 255, 255, 255, 255,
25 255, 255, 255, 255, 255, 255, 255, 255,
26 255, 255, 255, 255, 255, 255, 255, 255,
27 255, 255, 255, 255, 255, 255, 255, 255,
28 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
29 0x8, 0x9, 255, 255, 255, 255, 255, 255,
30 255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
31 255, 255, 255, 255, 255, 255, 255, 255,
32 255, 255, 255, 255, 255, 255, 255, 255,
33 255, 255, 255, 255, 255, 255, 255, 255,
34 255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
35 255, 255, 255, 255, 255, 255, 255, 255,
36 255, 255, 255, 255, 255, 255, 255, 255,
37 255, 255, 255, 255, 255, 255, 255, 255,
38 255, 255, 255, 255, 255, 255, 255, 255,
39 255, 255, 255, 255, 255, 255, 255, 255,
40 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255, 255,
44 255, 255, 255, 255, 255, 255, 255, 255,
45 255, 255, 255, 255, 255, 255, 255, 255,
46 255, 255, 255, 255, 255, 255, 255, 255,
47 255, 255, 255, 255, 255, 255, 255, 255,
48 255, 255, 255, 255, 255, 255, 255, 255,
49 255, 255, 255, 255, 255, 255, 255, 255,
50 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 255,
53 255, 255, 255, 255, 255, 255, 255, 255,
57 xdigit_to_sint (char ch)
59 if (ch >= 'a' && ch <= 'f')
61 if (ch >= 'A' && ch <= 'F')
66 static inline unsigned int
67 xdigit_to_uint (uint8_t ch)
69 if (ch >= 'a' && ch <= 'f')
70 return 10u + ch - 'a';
71 if (ch >= 'A' && ch <= 'F')
72 return 10u + ch - 'A';
76 //----------------------------------------------------------------------
77 // StringExtractor constructor
78 //----------------------------------------------------------------------
79 StringExtractor::StringExtractor() :
86 StringExtractor::StringExtractor(const char *packet_cstr) :
91 m_packet.assign (packet_cstr);
95 //----------------------------------------------------------------------
96 // StringExtractor copy constructor
97 //----------------------------------------------------------------------
98 StringExtractor::StringExtractor(const StringExtractor& rhs) :
99 m_packet (rhs.m_packet),
100 m_index (rhs.m_index)
105 //----------------------------------------------------------------------
106 // StringExtractor assignment operator
107 //----------------------------------------------------------------------
108 const StringExtractor&
109 StringExtractor::operator=(const StringExtractor& rhs)
113 m_packet = rhs.m_packet;
114 m_index = rhs.m_index;
120 //----------------------------------------------------------------------
122 //----------------------------------------------------------------------
123 StringExtractor::~StringExtractor()
129 StringExtractor::GetChar (char fail_value)
131 if (m_index < m_packet.size())
133 char ch = m_packet[m_index];
137 m_index = UINT64_MAX;
141 //----------------------------------------------------------------------
142 // Extract an unsigned character from two hex ASCII chars in the packet
144 //----------------------------------------------------------------------
146 StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail)
148 if (GetBytesLeft() >= 2)
150 const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index])];
151 const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index+1])];
152 if (hi_nibble < 16 && lo_nibble < 16)
155 return (hi_nibble << 4) + lo_nibble;
158 if (set_eof_on_fail || m_index >= m_packet.size())
159 m_index = UINT64_MAX;
164 StringExtractor::GetU32 (uint32_t fail_value, int base)
166 if (m_index < m_packet.size())
169 const char *start = m_packet.c_str();
170 const char *cstr = start + m_index;
171 uint32_t result = ::strtoul (cstr, &end, base);
173 if (end && end != cstr)
175 m_index = end - start;
183 StringExtractor::GetS32 (int32_t fail_value, int base)
185 if (m_index < m_packet.size())
188 const char *start = m_packet.c_str();
189 const char *cstr = start + m_index;
190 int32_t result = ::strtol (cstr, &end, base);
192 if (end && end != cstr)
194 m_index = end - start;
203 StringExtractor::GetU64 (uint64_t fail_value, int base)
205 if (m_index < m_packet.size())
208 const char *start = m_packet.c_str();
209 const char *cstr = start + m_index;
210 uint64_t result = ::strtoull (cstr, &end, base);
212 if (end && end != cstr)
214 m_index = end - start;
222 StringExtractor::GetS64 (int64_t fail_value, int base)
224 if (m_index < m_packet.size())
227 const char *start = m_packet.c_str();
228 const char *cstr = start + m_index;
229 int64_t result = ::strtoll (cstr, &end, base);
231 if (end && end != cstr)
233 m_index = end - start;
242 StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
245 uint32_t nibble_count = 0;
249 uint32_t shift_amount = 0;
250 while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
252 // Make sure we don't exceed the size of a uint32_t...
253 if (nibble_count >= (sizeof(uint32_t) * 2))
255 m_index = UINT64_MAX;
260 uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
262 if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
264 nibble_lo = xdigit_to_sint (m_packet[m_index]);
266 result |= ((uint32_t)nibble_hi << (shift_amount + 4));
267 result |= ((uint32_t)nibble_lo << shift_amount);
273 result |= ((uint32_t)nibble_hi << shift_amount);
282 while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
284 // Make sure we don't exceed the size of a uint32_t...
285 if (nibble_count >= (sizeof(uint32_t) * 2))
287 m_index = UINT64_MAX;
291 uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
304 StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
307 uint32_t nibble_count = 0;
311 uint32_t shift_amount = 0;
312 while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
314 // Make sure we don't exceed the size of a uint64_t...
315 if (nibble_count >= (sizeof(uint64_t) * 2))
317 m_index = UINT64_MAX;
322 uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
324 if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
326 nibble_lo = xdigit_to_sint (m_packet[m_index]);
328 result |= ((uint64_t)nibble_hi << (shift_amount + 4));
329 result |= ((uint64_t)nibble_lo << shift_amount);
335 result |= ((uint64_t)nibble_hi << shift_amount);
344 while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
346 // Make sure we don't exceed the size of a uint64_t...
347 if (nibble_count >= (sizeof(uint64_t) * 2))
349 m_index = UINT64_MAX;
353 uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
366 StringExtractor::GetHexBytes (void *dst_void, size_t dst_len, uint8_t fail_fill_value)
368 uint8_t *dst = (uint8_t*)dst_void;
369 size_t bytes_extracted = 0;
370 while (bytes_extracted < dst_len && GetBytesLeft ())
372 dst[bytes_extracted] = GetHexU8 (fail_fill_value);
379 for (size_t i = bytes_extracted; i < dst_len; ++i)
380 dst[i] = fail_fill_value;
382 return bytes_extracted;
386 // Consume ASCII hex nibble character pairs until we have decoded byte_size
390 StringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value)
392 if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2)
399 uint32_t shift_amount;
400 for (i = 0, shift_amount = 0;
401 i < byte_size && IsGood();
402 ++i, shift_amount += 8)
404 result |= ((uint64_t)GetHexU8() << shift_amount);
410 for (i = 0; i < byte_size && IsGood(); ++i)
413 result |= GetHexU8();
417 m_index = UINT64_MAX;
422 StringExtractor::GetHexByteString (std::string &str)
426 while ((ch = GetHexU8()) != '\0')
432 StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
437 while ((ch = GetHexU8(0,false)) != '\0')
439 if (Peek() && *Peek() == terminator)
446 StringExtractor::GetNameColonValue (std::string &name, std::string &value)
448 // Read something in the form of NNNN:VVVV; where NNNN is any character
449 // that is not a colon, followed by a ':' character, then a value (one or
450 // more ';' chars), followed by a ';'
451 if (m_index < m_packet.size())
453 const size_t colon_idx = m_packet.find (':', m_index);
454 if (colon_idx != std::string::npos)
456 const size_t semicolon_idx = m_packet.find (';', colon_idx);
457 if (semicolon_idx != std::string::npos)
459 name.assign (m_packet, m_index, colon_idx - m_index);
460 value.assign (m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1));
461 m_index = semicolon_idx + 1;
466 m_index = UINT64_MAX;