130fdc8d8SChris Lattner //===-- StringExtractor.cpp -------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
10c982c768SGreg Clayton #include "Utility/StringExtractor.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1378709173SStephen Wilson #include <stdlib.h>
1478709173SStephen Wilson 
1530fdc8d8SChris Lattner // C++ Includes
1630fdc8d8SChris Lattner // Other libraries and framework includes
1730fdc8d8SChris Lattner // Project includes
1830fdc8d8SChris Lattner 
193852b3e1SGreg Clayton static const uint8_t
203852b3e1SGreg Clayton g_hex_ascii_to_hex_integer[256] = {
213852b3e1SGreg Clayton 
223852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
233852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
243852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
253852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
263852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
273852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
283852b3e1SGreg Clayton     0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
293852b3e1SGreg Clayton     0x8, 0x9, 255, 255, 255, 255, 255, 255,
303852b3e1SGreg Clayton     255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
313852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
323852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
333852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
343852b3e1SGreg Clayton     255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
353852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
363852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
373852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
383852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
393852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
403852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
413852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
423852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
433852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
443852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
453852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
463852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
473852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
483852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
493852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
503852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
513852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
523852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
533852b3e1SGreg Clayton     255, 255, 255, 255, 255, 255, 255, 255,
543852b3e1SGreg Clayton };
553852b3e1SGreg Clayton 
5630fdc8d8SChris Lattner static inline int
5730fdc8d8SChris Lattner xdigit_to_sint (char ch)
5830fdc8d8SChris Lattner {
5930fdc8d8SChris Lattner     if (ch >= 'a' && ch <= 'f')
6030fdc8d8SChris Lattner         return 10 + ch - 'a';
611e89cd80SBenjamin Kramer     if (ch >= 'A' && ch <= 'F')
621e89cd80SBenjamin Kramer         return 10 + ch - 'A';
6330fdc8d8SChris Lattner     return ch - '0';
6430fdc8d8SChris Lattner }
6530fdc8d8SChris Lattner 
6630fdc8d8SChris Lattner //----------------------------------------------------------------------
6730fdc8d8SChris Lattner // StringExtractor constructor
6830fdc8d8SChris Lattner //----------------------------------------------------------------------
6930fdc8d8SChris Lattner StringExtractor::StringExtractor() :
7030fdc8d8SChris Lattner     m_packet(),
7130fdc8d8SChris Lattner     m_index (0)
7230fdc8d8SChris Lattner {
7330fdc8d8SChris Lattner }
7430fdc8d8SChris Lattner 
7530fdc8d8SChris Lattner 
7630fdc8d8SChris Lattner StringExtractor::StringExtractor(const char *packet_cstr) :
7730fdc8d8SChris Lattner     m_packet(),
7830fdc8d8SChris Lattner     m_index (0)
7930fdc8d8SChris Lattner {
8030fdc8d8SChris Lattner     if (packet_cstr)
8130fdc8d8SChris Lattner         m_packet.assign (packet_cstr);
8230fdc8d8SChris Lattner }
8330fdc8d8SChris Lattner 
8430fdc8d8SChris Lattner 
8530fdc8d8SChris Lattner //----------------------------------------------------------------------
8630fdc8d8SChris Lattner // StringExtractor copy constructor
8730fdc8d8SChris Lattner //----------------------------------------------------------------------
8830fdc8d8SChris Lattner StringExtractor::StringExtractor(const StringExtractor& rhs) :
8930fdc8d8SChris Lattner     m_packet (rhs.m_packet),
9030fdc8d8SChris Lattner     m_index (rhs.m_index)
9130fdc8d8SChris Lattner {
9230fdc8d8SChris Lattner 
9330fdc8d8SChris Lattner }
9430fdc8d8SChris Lattner 
9530fdc8d8SChris Lattner //----------------------------------------------------------------------
9630fdc8d8SChris Lattner // StringExtractor assignment operator
9730fdc8d8SChris Lattner //----------------------------------------------------------------------
9830fdc8d8SChris Lattner const StringExtractor&
9930fdc8d8SChris Lattner StringExtractor::operator=(const StringExtractor& rhs)
10030fdc8d8SChris Lattner {
10130fdc8d8SChris Lattner     if (this != &rhs)
10230fdc8d8SChris Lattner     {
10330fdc8d8SChris Lattner         m_packet = rhs.m_packet;
10430fdc8d8SChris Lattner         m_index = rhs.m_index;
10530fdc8d8SChris Lattner 
10630fdc8d8SChris Lattner     }
10730fdc8d8SChris Lattner     return *this;
10830fdc8d8SChris Lattner }
10930fdc8d8SChris Lattner 
11030fdc8d8SChris Lattner //----------------------------------------------------------------------
11130fdc8d8SChris Lattner // Destructor
11230fdc8d8SChris Lattner //----------------------------------------------------------------------
11330fdc8d8SChris Lattner StringExtractor::~StringExtractor()
11430fdc8d8SChris Lattner {
11530fdc8d8SChris Lattner }
11630fdc8d8SChris Lattner 
11730fdc8d8SChris Lattner 
11830fdc8d8SChris Lattner char
11930fdc8d8SChris Lattner StringExtractor::GetChar (char fail_value)
12030fdc8d8SChris Lattner {
12130fdc8d8SChris Lattner     if (m_index < m_packet.size())
12230fdc8d8SChris Lattner     {
12330fdc8d8SChris Lattner         char ch = m_packet[m_index];
12430fdc8d8SChris Lattner         ++m_index;
12530fdc8d8SChris Lattner         return ch;
12630fdc8d8SChris Lattner     }
127c7bece56SGreg Clayton     m_index = UINT64_MAX;
12830fdc8d8SChris Lattner     return fail_value;
12930fdc8d8SChris Lattner }
13030fdc8d8SChris Lattner 
13130fdc8d8SChris Lattner //----------------------------------------------------------------------
13230fdc8d8SChris Lattner // Extract an unsigned character from two hex ASCII chars in the packet
13330fdc8d8SChris Lattner // string
13430fdc8d8SChris Lattner //----------------------------------------------------------------------
13530fdc8d8SChris Lattner uint8_t
1367b70be39SGreg Clayton StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail)
13730fdc8d8SChris Lattner {
138fbb76349SGreg Clayton     if (GetBytesLeft() >= 2)
13930fdc8d8SChris Lattner     {
140fbb76349SGreg Clayton         const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index])];
141fbb76349SGreg Clayton         const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index+1])];
1423852b3e1SGreg Clayton         if (hi_nibble < 16 && lo_nibble < 16)
1433852b3e1SGreg Clayton         {
14430fdc8d8SChris Lattner             m_index += 2;
14530fdc8d8SChris Lattner             return (hi_nibble << 4) + lo_nibble;
14630fdc8d8SChris Lattner         }
1473852b3e1SGreg Clayton     }
1487b70be39SGreg Clayton     if (set_eof_on_fail || m_index >= m_packet.size())
149c7bece56SGreg Clayton         m_index = UINT64_MAX;
15030fdc8d8SChris Lattner     return fail_value;
15130fdc8d8SChris Lattner }
15230fdc8d8SChris Lattner 
15330fdc8d8SChris Lattner uint32_t
15432e0a750SGreg Clayton StringExtractor::GetU32 (uint32_t fail_value, int base)
15532e0a750SGreg Clayton {
15632e0a750SGreg Clayton     if (m_index < m_packet.size())
15732e0a750SGreg Clayton     {
158d4612ad0SEd Maste         char *end = nullptr;
15932e0a750SGreg Clayton         const char *start = m_packet.c_str();
160e0f8f574SDaniel Malea         const char *cstr = start + m_index;
161e0f8f574SDaniel Malea         uint32_t result = ::strtoul (cstr, &end, base);
16232e0a750SGreg Clayton 
163e0f8f574SDaniel Malea         if (end && end != cstr)
164e0f8f574SDaniel Malea         {
165e0f8f574SDaniel Malea             m_index = end - start;
166e0f8f574SDaniel Malea             return result;
167e0f8f574SDaniel Malea         }
168e0f8f574SDaniel Malea     }
169e0f8f574SDaniel Malea     return fail_value;
170e0f8f574SDaniel Malea }
171e0f8f574SDaniel Malea 
172e0f8f574SDaniel Malea int32_t
173e0f8f574SDaniel Malea StringExtractor::GetS32 (int32_t fail_value, int base)
174e0f8f574SDaniel Malea {
175e0f8f574SDaniel Malea     if (m_index < m_packet.size())
176e0f8f574SDaniel Malea     {
177d4612ad0SEd Maste         char *end = nullptr;
178e0f8f574SDaniel Malea         const char *start = m_packet.c_str();
179e0f8f574SDaniel Malea         const char *cstr = start + m_index;
180e0f8f574SDaniel Malea         int32_t result = ::strtol (cstr, &end, base);
181e0f8f574SDaniel Malea 
182e0f8f574SDaniel Malea         if (end && end != cstr)
183e0f8f574SDaniel Malea         {
184e0f8f574SDaniel Malea             m_index = end - start;
185e0f8f574SDaniel Malea             return result;
186e0f8f574SDaniel Malea         }
187e0f8f574SDaniel Malea     }
188e0f8f574SDaniel Malea     return fail_value;
189e0f8f574SDaniel Malea }
190e0f8f574SDaniel Malea 
191e0f8f574SDaniel Malea 
192e0f8f574SDaniel Malea uint64_t
193e0f8f574SDaniel Malea StringExtractor::GetU64 (uint64_t fail_value, int base)
194e0f8f574SDaniel Malea {
195e0f8f574SDaniel Malea     if (m_index < m_packet.size())
196e0f8f574SDaniel Malea     {
197d4612ad0SEd Maste         char *end = nullptr;
198e0f8f574SDaniel Malea         const char *start = m_packet.c_str();
199e0f8f574SDaniel Malea         const char *cstr = start + m_index;
200e0f8f574SDaniel Malea         uint64_t result = ::strtoull (cstr, &end, base);
201e0f8f574SDaniel Malea 
202e0f8f574SDaniel Malea         if (end && end != cstr)
203e0f8f574SDaniel Malea         {
204e0f8f574SDaniel Malea             m_index = end - start;
205e0f8f574SDaniel Malea             return result;
206e0f8f574SDaniel Malea         }
207e0f8f574SDaniel Malea     }
208e0f8f574SDaniel Malea     return fail_value;
209e0f8f574SDaniel Malea }
210e0f8f574SDaniel Malea 
211e0f8f574SDaniel Malea int64_t
212e0f8f574SDaniel Malea StringExtractor::GetS64 (int64_t fail_value, int base)
213e0f8f574SDaniel Malea {
214e0f8f574SDaniel Malea     if (m_index < m_packet.size())
215e0f8f574SDaniel Malea     {
216d4612ad0SEd Maste         char *end = nullptr;
217e0f8f574SDaniel Malea         const char *start = m_packet.c_str();
218e0f8f574SDaniel Malea         const char *cstr = start + m_index;
219e0f8f574SDaniel Malea         int64_t result = ::strtoll (cstr, &end, base);
220e0f8f574SDaniel Malea 
221e0f8f574SDaniel Malea         if (end && end != cstr)
22232e0a750SGreg Clayton         {
22332e0a750SGreg Clayton             m_index = end - start;
22432e0a750SGreg Clayton             return result;
22532e0a750SGreg Clayton         }
22632e0a750SGreg Clayton     }
22732e0a750SGreg Clayton     return fail_value;
22832e0a750SGreg Clayton }
22932e0a750SGreg Clayton 
23032e0a750SGreg Clayton 
23132e0a750SGreg Clayton uint32_t
23230fdc8d8SChris Lattner StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
23330fdc8d8SChris Lattner {
23430fdc8d8SChris Lattner     uint32_t result = 0;
23530fdc8d8SChris Lattner     uint32_t nibble_count = 0;
23630fdc8d8SChris Lattner 
23730fdc8d8SChris Lattner     if (little_endian)
23830fdc8d8SChris Lattner     {
23930fdc8d8SChris Lattner         uint32_t shift_amount = 0;
24030fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
24130fdc8d8SChris Lattner         {
24230fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint32_t...
24330fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint32_t) * 2))
24430fdc8d8SChris Lattner             {
245c7bece56SGreg Clayton                 m_index = UINT64_MAX;
24630fdc8d8SChris Lattner                 return fail_value;
24730fdc8d8SChris Lattner             }
24830fdc8d8SChris Lattner 
24930fdc8d8SChris Lattner             uint8_t nibble_lo;
25030fdc8d8SChris Lattner             uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
25130fdc8d8SChris Lattner             ++m_index;
25230fdc8d8SChris Lattner             if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
25330fdc8d8SChris Lattner             {
25430fdc8d8SChris Lattner                 nibble_lo = xdigit_to_sint (m_packet[m_index]);
25530fdc8d8SChris Lattner                 ++m_index;
25630fdc8d8SChris Lattner                 result |= ((uint32_t)nibble_hi << (shift_amount + 4));
25730fdc8d8SChris Lattner                 result |= ((uint32_t)nibble_lo << shift_amount);
25830fdc8d8SChris Lattner                 nibble_count += 2;
25930fdc8d8SChris Lattner                 shift_amount += 8;
26030fdc8d8SChris Lattner             }
26130fdc8d8SChris Lattner             else
26230fdc8d8SChris Lattner             {
26330fdc8d8SChris Lattner                 result |= ((uint32_t)nibble_hi << shift_amount);
26430fdc8d8SChris Lattner                 nibble_count += 1;
26530fdc8d8SChris Lattner                 shift_amount += 4;
26630fdc8d8SChris Lattner             }
26730fdc8d8SChris Lattner 
26830fdc8d8SChris Lattner         }
26930fdc8d8SChris Lattner     }
27030fdc8d8SChris Lattner     else
27130fdc8d8SChris Lattner     {
27230fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
27330fdc8d8SChris Lattner         {
27430fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint32_t...
27530fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint32_t) * 2))
27630fdc8d8SChris Lattner             {
277c7bece56SGreg Clayton                 m_index = UINT64_MAX;
27830fdc8d8SChris Lattner                 return fail_value;
27930fdc8d8SChris Lattner             }
28030fdc8d8SChris Lattner 
28130fdc8d8SChris Lattner             uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
28230fdc8d8SChris Lattner             // Big Endian
28330fdc8d8SChris Lattner             result <<= 4;
28430fdc8d8SChris Lattner             result |= nibble;
28530fdc8d8SChris Lattner 
28630fdc8d8SChris Lattner             ++m_index;
28730fdc8d8SChris Lattner             ++nibble_count;
28830fdc8d8SChris Lattner         }
28930fdc8d8SChris Lattner     }
29030fdc8d8SChris Lattner     return result;
29130fdc8d8SChris Lattner }
29230fdc8d8SChris Lattner 
29330fdc8d8SChris Lattner uint64_t
29430fdc8d8SChris Lattner StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
29530fdc8d8SChris Lattner {
29630fdc8d8SChris Lattner     uint64_t result = 0;
29730fdc8d8SChris Lattner     uint32_t nibble_count = 0;
29830fdc8d8SChris Lattner 
29930fdc8d8SChris Lattner     if (little_endian)
30030fdc8d8SChris Lattner     {
30130fdc8d8SChris Lattner         uint32_t shift_amount = 0;
30230fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
30330fdc8d8SChris Lattner         {
30430fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint64_t...
30530fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint64_t) * 2))
30630fdc8d8SChris Lattner             {
307c7bece56SGreg Clayton                 m_index = UINT64_MAX;
30830fdc8d8SChris Lattner                 return fail_value;
30930fdc8d8SChris Lattner             }
31030fdc8d8SChris Lattner 
31130fdc8d8SChris Lattner             uint8_t nibble_lo;
31230fdc8d8SChris Lattner             uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
31330fdc8d8SChris Lattner             ++m_index;
31430fdc8d8SChris Lattner             if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
31530fdc8d8SChris Lattner             {
31630fdc8d8SChris Lattner                 nibble_lo = xdigit_to_sint (m_packet[m_index]);
31730fdc8d8SChris Lattner                 ++m_index;
31830fdc8d8SChris Lattner                 result |= ((uint64_t)nibble_hi << (shift_amount + 4));
31930fdc8d8SChris Lattner                 result |= ((uint64_t)nibble_lo << shift_amount);
32030fdc8d8SChris Lattner                 nibble_count += 2;
32130fdc8d8SChris Lattner                 shift_amount += 8;
32230fdc8d8SChris Lattner             }
32330fdc8d8SChris Lattner             else
32430fdc8d8SChris Lattner             {
32530fdc8d8SChris Lattner                 result |= ((uint64_t)nibble_hi << shift_amount);
32630fdc8d8SChris Lattner                 nibble_count += 1;
32730fdc8d8SChris Lattner                 shift_amount += 4;
32830fdc8d8SChris Lattner             }
32930fdc8d8SChris Lattner 
33030fdc8d8SChris Lattner         }
33130fdc8d8SChris Lattner     }
33230fdc8d8SChris Lattner     else
33330fdc8d8SChris Lattner     {
33430fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
33530fdc8d8SChris Lattner         {
33630fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint64_t...
33730fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint64_t) * 2))
33830fdc8d8SChris Lattner             {
339c7bece56SGreg Clayton                 m_index = UINT64_MAX;
34030fdc8d8SChris Lattner                 return fail_value;
34130fdc8d8SChris Lattner             }
34230fdc8d8SChris Lattner 
34330fdc8d8SChris Lattner             uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
34430fdc8d8SChris Lattner             // Big Endian
34530fdc8d8SChris Lattner             result <<= 4;
34630fdc8d8SChris Lattner             result |= nibble;
34730fdc8d8SChris Lattner 
34830fdc8d8SChris Lattner             ++m_index;
34930fdc8d8SChris Lattner             ++nibble_count;
35030fdc8d8SChris Lattner         }
35130fdc8d8SChris Lattner     }
35230fdc8d8SChris Lattner     return result;
35330fdc8d8SChris Lattner }
35430fdc8d8SChris Lattner 
35530fdc8d8SChris Lattner size_t
35630fdc8d8SChris Lattner StringExtractor::GetHexBytes (void *dst_void, size_t dst_len, uint8_t fail_fill_value)
35730fdc8d8SChris Lattner {
35830fdc8d8SChris Lattner     uint8_t *dst = (uint8_t*)dst_void;
35930fdc8d8SChris Lattner     size_t bytes_extracted = 0;
36030fdc8d8SChris Lattner     while (bytes_extracted < dst_len && GetBytesLeft ())
36130fdc8d8SChris Lattner     {
36230fdc8d8SChris Lattner         dst[bytes_extracted] = GetHexU8 (fail_fill_value);
36330fdc8d8SChris Lattner         if (IsGood())
36430fdc8d8SChris Lattner             ++bytes_extracted;
36530fdc8d8SChris Lattner         else
36630fdc8d8SChris Lattner             break;
36730fdc8d8SChris Lattner     }
36830fdc8d8SChris Lattner 
36930fdc8d8SChris Lattner     for (size_t i = bytes_extracted; i < dst_len; ++i)
37030fdc8d8SChris Lattner         dst[i] = fail_fill_value;
37130fdc8d8SChris Lattner 
37230fdc8d8SChris Lattner     return bytes_extracted;
37330fdc8d8SChris Lattner }
37430fdc8d8SChris Lattner 
37530fdc8d8SChris Lattner 
37630fdc8d8SChris Lattner // Consume ASCII hex nibble character pairs until we have decoded byte_size
37730fdc8d8SChris Lattner // bytes of data.
37830fdc8d8SChris Lattner 
37930fdc8d8SChris Lattner uint64_t
38030fdc8d8SChris Lattner StringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value)
38130fdc8d8SChris Lattner {
38230fdc8d8SChris Lattner     if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2)
38330fdc8d8SChris Lattner     {
38430fdc8d8SChris Lattner         uint64_t result = 0;
38530fdc8d8SChris Lattner         uint32_t i;
38630fdc8d8SChris Lattner         if (little_endian)
38730fdc8d8SChris Lattner         {
38830fdc8d8SChris Lattner             // Little Endian
38930fdc8d8SChris Lattner             uint32_t shift_amount;
39030fdc8d8SChris Lattner             for (i = 0, shift_amount = 0;
391c7bece56SGreg Clayton                  i < byte_size && IsGood();
39230fdc8d8SChris Lattner                  ++i, shift_amount += 8)
39330fdc8d8SChris Lattner             {
39430fdc8d8SChris Lattner                 result |= ((uint64_t)GetHexU8() << shift_amount);
39530fdc8d8SChris Lattner             }
39630fdc8d8SChris Lattner         }
39730fdc8d8SChris Lattner         else
39830fdc8d8SChris Lattner         {
39930fdc8d8SChris Lattner             // Big Endian
400c7bece56SGreg Clayton             for (i = 0; i < byte_size && IsGood(); ++i)
40130fdc8d8SChris Lattner             {
40230fdc8d8SChris Lattner                 result <<= 8;
40330fdc8d8SChris Lattner                 result |= GetHexU8();
40430fdc8d8SChris Lattner             }
40530fdc8d8SChris Lattner         }
40630fdc8d8SChris Lattner     }
407c7bece56SGreg Clayton     m_index = UINT64_MAX;
40830fdc8d8SChris Lattner     return fail_value;
40930fdc8d8SChris Lattner }
41030fdc8d8SChris Lattner 
411de9d0494SGreg Clayton size_t
412de9d0494SGreg Clayton StringExtractor::GetHexByteString (std::string &str)
413de9d0494SGreg Clayton {
414de9d0494SGreg Clayton     str.clear();
415de9d0494SGreg Clayton     char ch;
416de9d0494SGreg Clayton     while ((ch = GetHexU8()) != '\0')
417de9d0494SGreg Clayton         str.append(1, ch);
418de9d0494SGreg Clayton     return str.size();
419de9d0494SGreg Clayton }
420de9d0494SGreg Clayton 
421e0f8f574SDaniel Malea size_t
422*af245d11STodd Fiala StringExtractor::GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length)
423*af245d11STodd Fiala {
424*af245d11STodd Fiala     str.clear();
425*af245d11STodd Fiala 
426*af245d11STodd Fiala     uint32_t nibble_count = 0;
427*af245d11STodd Fiala     for (const char *pch = Peek(); (nibble_count < nibble_length) && (pch != nullptr); str.append(1, GetHexU8(0, false)), pch = Peek (), nibble_count += 2)
428*af245d11STodd Fiala     {}
429*af245d11STodd Fiala 
430*af245d11STodd Fiala     return str.size();
431*af245d11STodd Fiala }
432*af245d11STodd Fiala 
433*af245d11STodd Fiala size_t
434e0f8f574SDaniel Malea StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
435e0f8f574SDaniel Malea                                                char terminator)
436e0f8f574SDaniel Malea {
437e0f8f574SDaniel Malea     str.clear();
438e0f8f574SDaniel Malea     char ch;
439e0f8f574SDaniel Malea     while ((ch = GetHexU8(0,false)) != '\0')
440e0f8f574SDaniel Malea         str.append(1, ch);
441e0f8f574SDaniel Malea     if (Peek() && *Peek() == terminator)
442e0f8f574SDaniel Malea         return str.size();
443*af245d11STodd Fiala 
444e0f8f574SDaniel Malea     str.clear();
445e0f8f574SDaniel Malea     return str.size();
446e0f8f574SDaniel Malea }
447e0f8f574SDaniel Malea 
44830fdc8d8SChris Lattner bool
44930fdc8d8SChris Lattner StringExtractor::GetNameColonValue (std::string &name, std::string &value)
45030fdc8d8SChris Lattner {
45130fdc8d8SChris Lattner     // Read something in the form of NNNN:VVVV; where NNNN is any character
45230fdc8d8SChris Lattner     // that is not a colon, followed by a ':' character, then a value (one or
45330fdc8d8SChris Lattner     // more ';' chars), followed by a ';'
45430fdc8d8SChris Lattner     if (m_index < m_packet.size())
45530fdc8d8SChris Lattner     {
45630fdc8d8SChris Lattner         const size_t colon_idx = m_packet.find (':', m_index);
45730fdc8d8SChris Lattner         if (colon_idx != std::string::npos)
45830fdc8d8SChris Lattner         {
45930fdc8d8SChris Lattner             const size_t semicolon_idx = m_packet.find (';', colon_idx);
46030fdc8d8SChris Lattner             if (semicolon_idx != std::string::npos)
46130fdc8d8SChris Lattner             {
46230fdc8d8SChris Lattner                 name.assign (m_packet, m_index, colon_idx - m_index);
46330fdc8d8SChris Lattner                 value.assign (m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1));
46430fdc8d8SChris Lattner                 m_index = semicolon_idx + 1;
46530fdc8d8SChris Lattner                 return true;
46630fdc8d8SChris Lattner             }
46730fdc8d8SChris Lattner         }
46830fdc8d8SChris Lattner     }
469c7bece56SGreg Clayton     m_index = UINT64_MAX;
47030fdc8d8SChris Lattner     return false;
47130fdc8d8SChris Lattner }
472