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 static inline unsigned int
6730fdc8d8SChris Lattner xdigit_to_uint (uint8_t ch)
6830fdc8d8SChris Lattner {
6930fdc8d8SChris Lattner     if (ch >= 'a' && ch <= 'f')
7030fdc8d8SChris Lattner         return 10u + ch - 'a';
711e89cd80SBenjamin Kramer     if (ch >= 'A' && ch <= 'F')
721e89cd80SBenjamin Kramer         return 10u + ch - 'A';
7330fdc8d8SChris Lattner     return ch - '0';
7430fdc8d8SChris Lattner }
7530fdc8d8SChris Lattner 
7630fdc8d8SChris Lattner //----------------------------------------------------------------------
7730fdc8d8SChris Lattner // StringExtractor constructor
7830fdc8d8SChris Lattner //----------------------------------------------------------------------
7930fdc8d8SChris Lattner StringExtractor::StringExtractor() :
8030fdc8d8SChris Lattner     m_packet(),
8130fdc8d8SChris Lattner     m_index (0)
8230fdc8d8SChris Lattner {
8330fdc8d8SChris Lattner }
8430fdc8d8SChris Lattner 
8530fdc8d8SChris Lattner 
8630fdc8d8SChris Lattner StringExtractor::StringExtractor(const char *packet_cstr) :
8730fdc8d8SChris Lattner     m_packet(),
8830fdc8d8SChris Lattner     m_index (0)
8930fdc8d8SChris Lattner {
9030fdc8d8SChris Lattner     if (packet_cstr)
9130fdc8d8SChris Lattner         m_packet.assign (packet_cstr);
9230fdc8d8SChris Lattner }
9330fdc8d8SChris Lattner 
9430fdc8d8SChris Lattner 
9530fdc8d8SChris Lattner //----------------------------------------------------------------------
9630fdc8d8SChris Lattner // StringExtractor copy constructor
9730fdc8d8SChris Lattner //----------------------------------------------------------------------
9830fdc8d8SChris Lattner StringExtractor::StringExtractor(const StringExtractor& rhs) :
9930fdc8d8SChris Lattner     m_packet (rhs.m_packet),
10030fdc8d8SChris Lattner     m_index (rhs.m_index)
10130fdc8d8SChris Lattner {
10230fdc8d8SChris Lattner 
10330fdc8d8SChris Lattner }
10430fdc8d8SChris Lattner 
10530fdc8d8SChris Lattner //----------------------------------------------------------------------
10630fdc8d8SChris Lattner // StringExtractor assignment operator
10730fdc8d8SChris Lattner //----------------------------------------------------------------------
10830fdc8d8SChris Lattner const StringExtractor&
10930fdc8d8SChris Lattner StringExtractor::operator=(const StringExtractor& rhs)
11030fdc8d8SChris Lattner {
11130fdc8d8SChris Lattner     if (this != &rhs)
11230fdc8d8SChris Lattner     {
11330fdc8d8SChris Lattner         m_packet = rhs.m_packet;
11430fdc8d8SChris Lattner         m_index = rhs.m_index;
11530fdc8d8SChris Lattner 
11630fdc8d8SChris Lattner     }
11730fdc8d8SChris Lattner     return *this;
11830fdc8d8SChris Lattner }
11930fdc8d8SChris Lattner 
12030fdc8d8SChris Lattner //----------------------------------------------------------------------
12130fdc8d8SChris Lattner // Destructor
12230fdc8d8SChris Lattner //----------------------------------------------------------------------
12330fdc8d8SChris Lattner StringExtractor::~StringExtractor()
12430fdc8d8SChris Lattner {
12530fdc8d8SChris Lattner }
12630fdc8d8SChris Lattner 
12730fdc8d8SChris Lattner 
12830fdc8d8SChris Lattner char
12930fdc8d8SChris Lattner StringExtractor::GetChar (char fail_value)
13030fdc8d8SChris Lattner {
13130fdc8d8SChris Lattner     if (m_index < m_packet.size())
13230fdc8d8SChris Lattner     {
13330fdc8d8SChris Lattner         char ch = m_packet[m_index];
13430fdc8d8SChris Lattner         ++m_index;
13530fdc8d8SChris Lattner         return ch;
13630fdc8d8SChris Lattner     }
137c7bece56SGreg Clayton     m_index = UINT64_MAX;
13830fdc8d8SChris Lattner     return fail_value;
13930fdc8d8SChris Lattner }
14030fdc8d8SChris Lattner 
14130fdc8d8SChris Lattner //----------------------------------------------------------------------
14230fdc8d8SChris Lattner // Extract an unsigned character from two hex ASCII chars in the packet
14330fdc8d8SChris Lattner // string
14430fdc8d8SChris Lattner //----------------------------------------------------------------------
14530fdc8d8SChris Lattner uint8_t
1467b70be39SGreg Clayton StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail)
14730fdc8d8SChris Lattner {
1483852b3e1SGreg Clayton     uint32_t i = m_index;
1493852b3e1SGreg Clayton     if ((i + 2) <= m_packet.size())
15030fdc8d8SChris Lattner     {
151a85e6b6cSDaniel Malea         const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i])];
152a85e6b6cSDaniel Malea         const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i+1])];
1533852b3e1SGreg Clayton         if (hi_nibble < 16 && lo_nibble < 16)
1543852b3e1SGreg Clayton         {
15530fdc8d8SChris Lattner             m_index += 2;
15630fdc8d8SChris Lattner             return (hi_nibble << 4) + lo_nibble;
15730fdc8d8SChris Lattner         }
1583852b3e1SGreg Clayton     }
1597b70be39SGreg Clayton     if (set_eof_on_fail || m_index >= m_packet.size())
160c7bece56SGreg Clayton         m_index = UINT64_MAX;
16130fdc8d8SChris Lattner     return fail_value;
16230fdc8d8SChris Lattner }
16330fdc8d8SChris Lattner 
16430fdc8d8SChris Lattner uint32_t
16532e0a750SGreg Clayton StringExtractor::GetU32 (uint32_t fail_value, int base)
16632e0a750SGreg Clayton {
16732e0a750SGreg Clayton     if (m_index < m_packet.size())
16832e0a750SGreg Clayton     {
16932e0a750SGreg Clayton         char *end = NULL;
17032e0a750SGreg Clayton         const char *start = m_packet.c_str();
171*e0f8f574SDaniel Malea         const char *cstr = start + m_index;
172*e0f8f574SDaniel Malea         uint32_t result = ::strtoul (cstr, &end, base);
17332e0a750SGreg Clayton 
174*e0f8f574SDaniel Malea         if (end && end != cstr)
175*e0f8f574SDaniel Malea         {
176*e0f8f574SDaniel Malea             m_index = end - start;
177*e0f8f574SDaniel Malea             return result;
178*e0f8f574SDaniel Malea         }
179*e0f8f574SDaniel Malea     }
180*e0f8f574SDaniel Malea     return fail_value;
181*e0f8f574SDaniel Malea }
182*e0f8f574SDaniel Malea 
183*e0f8f574SDaniel Malea int32_t
184*e0f8f574SDaniel Malea StringExtractor::GetS32 (int32_t fail_value, int base)
185*e0f8f574SDaniel Malea {
186*e0f8f574SDaniel Malea     if (m_index < m_packet.size())
187*e0f8f574SDaniel Malea     {
188*e0f8f574SDaniel Malea         char *end = NULL;
189*e0f8f574SDaniel Malea         const char *start = m_packet.c_str();
190*e0f8f574SDaniel Malea         const char *cstr = start + m_index;
191*e0f8f574SDaniel Malea         int32_t result = ::strtol (cstr, &end, base);
192*e0f8f574SDaniel Malea 
193*e0f8f574SDaniel Malea         if (end && end != cstr)
194*e0f8f574SDaniel Malea         {
195*e0f8f574SDaniel Malea             m_index = end - start;
196*e0f8f574SDaniel Malea             return result;
197*e0f8f574SDaniel Malea         }
198*e0f8f574SDaniel Malea     }
199*e0f8f574SDaniel Malea     return fail_value;
200*e0f8f574SDaniel Malea }
201*e0f8f574SDaniel Malea 
202*e0f8f574SDaniel Malea 
203*e0f8f574SDaniel Malea uint64_t
204*e0f8f574SDaniel Malea StringExtractor::GetU64 (uint64_t fail_value, int base)
205*e0f8f574SDaniel Malea {
206*e0f8f574SDaniel Malea     if (m_index < m_packet.size())
207*e0f8f574SDaniel Malea     {
208*e0f8f574SDaniel Malea         char *end = NULL;
209*e0f8f574SDaniel Malea         const char *start = m_packet.c_str();
210*e0f8f574SDaniel Malea         const char *cstr = start + m_index;
211*e0f8f574SDaniel Malea         uint64_t result = ::strtoull (cstr, &end, base);
212*e0f8f574SDaniel Malea 
213*e0f8f574SDaniel Malea         if (end && end != cstr)
214*e0f8f574SDaniel Malea         {
215*e0f8f574SDaniel Malea             m_index = end - start;
216*e0f8f574SDaniel Malea             return result;
217*e0f8f574SDaniel Malea         }
218*e0f8f574SDaniel Malea     }
219*e0f8f574SDaniel Malea     return fail_value;
220*e0f8f574SDaniel Malea }
221*e0f8f574SDaniel Malea 
222*e0f8f574SDaniel Malea int64_t
223*e0f8f574SDaniel Malea StringExtractor::GetS64 (int64_t fail_value, int base)
224*e0f8f574SDaniel Malea {
225*e0f8f574SDaniel Malea     if (m_index < m_packet.size())
226*e0f8f574SDaniel Malea     {
227*e0f8f574SDaniel Malea         char *end = NULL;
228*e0f8f574SDaniel Malea         const char *start = m_packet.c_str();
229*e0f8f574SDaniel Malea         const char *cstr = start + m_index;
230*e0f8f574SDaniel Malea         int64_t result = ::strtoll (cstr, &end, base);
231*e0f8f574SDaniel Malea 
232*e0f8f574SDaniel Malea         if (end && end != cstr)
23332e0a750SGreg Clayton         {
23432e0a750SGreg Clayton             m_index = end - start;
23532e0a750SGreg Clayton             return result;
23632e0a750SGreg Clayton         }
23732e0a750SGreg Clayton     }
23832e0a750SGreg Clayton     return fail_value;
23932e0a750SGreg Clayton }
24032e0a750SGreg Clayton 
24132e0a750SGreg Clayton 
24232e0a750SGreg Clayton uint32_t
24330fdc8d8SChris Lattner StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
24430fdc8d8SChris Lattner {
24530fdc8d8SChris Lattner     uint32_t result = 0;
24630fdc8d8SChris Lattner     uint32_t nibble_count = 0;
24730fdc8d8SChris Lattner 
24830fdc8d8SChris Lattner     if (little_endian)
24930fdc8d8SChris Lattner     {
25030fdc8d8SChris Lattner         uint32_t shift_amount = 0;
25130fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
25230fdc8d8SChris Lattner         {
25330fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint32_t...
25430fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint32_t) * 2))
25530fdc8d8SChris Lattner             {
256c7bece56SGreg Clayton                 m_index = UINT64_MAX;
25730fdc8d8SChris Lattner                 return fail_value;
25830fdc8d8SChris Lattner             }
25930fdc8d8SChris Lattner 
26030fdc8d8SChris Lattner             uint8_t nibble_lo;
26130fdc8d8SChris Lattner             uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
26230fdc8d8SChris Lattner             ++m_index;
26330fdc8d8SChris Lattner             if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
26430fdc8d8SChris Lattner             {
26530fdc8d8SChris Lattner                 nibble_lo = xdigit_to_sint (m_packet[m_index]);
26630fdc8d8SChris Lattner                 ++m_index;
26730fdc8d8SChris Lattner                 result |= ((uint32_t)nibble_hi << (shift_amount + 4));
26830fdc8d8SChris Lattner                 result |= ((uint32_t)nibble_lo << shift_amount);
26930fdc8d8SChris Lattner                 nibble_count += 2;
27030fdc8d8SChris Lattner                 shift_amount += 8;
27130fdc8d8SChris Lattner             }
27230fdc8d8SChris Lattner             else
27330fdc8d8SChris Lattner             {
27430fdc8d8SChris Lattner                 result |= ((uint32_t)nibble_hi << shift_amount);
27530fdc8d8SChris Lattner                 nibble_count += 1;
27630fdc8d8SChris Lattner                 shift_amount += 4;
27730fdc8d8SChris Lattner             }
27830fdc8d8SChris Lattner 
27930fdc8d8SChris Lattner         }
28030fdc8d8SChris Lattner     }
28130fdc8d8SChris Lattner     else
28230fdc8d8SChris Lattner     {
28330fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
28430fdc8d8SChris Lattner         {
28530fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint32_t...
28630fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint32_t) * 2))
28730fdc8d8SChris Lattner             {
288c7bece56SGreg Clayton                 m_index = UINT64_MAX;
28930fdc8d8SChris Lattner                 return fail_value;
29030fdc8d8SChris Lattner             }
29130fdc8d8SChris Lattner 
29230fdc8d8SChris Lattner             uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
29330fdc8d8SChris Lattner             // Big Endian
29430fdc8d8SChris Lattner             result <<= 4;
29530fdc8d8SChris Lattner             result |= nibble;
29630fdc8d8SChris Lattner 
29730fdc8d8SChris Lattner             ++m_index;
29830fdc8d8SChris Lattner             ++nibble_count;
29930fdc8d8SChris Lattner         }
30030fdc8d8SChris Lattner     }
30130fdc8d8SChris Lattner     return result;
30230fdc8d8SChris Lattner }
30330fdc8d8SChris Lattner 
30430fdc8d8SChris Lattner uint64_t
30530fdc8d8SChris Lattner StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
30630fdc8d8SChris Lattner {
30730fdc8d8SChris Lattner     uint64_t result = 0;
30830fdc8d8SChris Lattner     uint32_t nibble_count = 0;
30930fdc8d8SChris Lattner 
31030fdc8d8SChris Lattner     if (little_endian)
31130fdc8d8SChris Lattner     {
31230fdc8d8SChris Lattner         uint32_t shift_amount = 0;
31330fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
31430fdc8d8SChris Lattner         {
31530fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint64_t...
31630fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint64_t) * 2))
31730fdc8d8SChris Lattner             {
318c7bece56SGreg Clayton                 m_index = UINT64_MAX;
31930fdc8d8SChris Lattner                 return fail_value;
32030fdc8d8SChris Lattner             }
32130fdc8d8SChris Lattner 
32230fdc8d8SChris Lattner             uint8_t nibble_lo;
32330fdc8d8SChris Lattner             uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
32430fdc8d8SChris Lattner             ++m_index;
32530fdc8d8SChris Lattner             if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
32630fdc8d8SChris Lattner             {
32730fdc8d8SChris Lattner                 nibble_lo = xdigit_to_sint (m_packet[m_index]);
32830fdc8d8SChris Lattner                 ++m_index;
32930fdc8d8SChris Lattner                 result |= ((uint64_t)nibble_hi << (shift_amount + 4));
33030fdc8d8SChris Lattner                 result |= ((uint64_t)nibble_lo << shift_amount);
33130fdc8d8SChris Lattner                 nibble_count += 2;
33230fdc8d8SChris Lattner                 shift_amount += 8;
33330fdc8d8SChris Lattner             }
33430fdc8d8SChris Lattner             else
33530fdc8d8SChris Lattner             {
33630fdc8d8SChris Lattner                 result |= ((uint64_t)nibble_hi << shift_amount);
33730fdc8d8SChris Lattner                 nibble_count += 1;
33830fdc8d8SChris Lattner                 shift_amount += 4;
33930fdc8d8SChris Lattner             }
34030fdc8d8SChris Lattner 
34130fdc8d8SChris Lattner         }
34230fdc8d8SChris Lattner     }
34330fdc8d8SChris Lattner     else
34430fdc8d8SChris Lattner     {
34530fdc8d8SChris Lattner         while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
34630fdc8d8SChris Lattner         {
34730fdc8d8SChris Lattner             // Make sure we don't exceed the size of a uint64_t...
34830fdc8d8SChris Lattner             if (nibble_count >= (sizeof(uint64_t) * 2))
34930fdc8d8SChris Lattner             {
350c7bece56SGreg Clayton                 m_index = UINT64_MAX;
35130fdc8d8SChris Lattner                 return fail_value;
35230fdc8d8SChris Lattner             }
35330fdc8d8SChris Lattner 
35430fdc8d8SChris Lattner             uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
35530fdc8d8SChris Lattner             // Big Endian
35630fdc8d8SChris Lattner             result <<= 4;
35730fdc8d8SChris Lattner             result |= nibble;
35830fdc8d8SChris Lattner 
35930fdc8d8SChris Lattner             ++m_index;
36030fdc8d8SChris Lattner             ++nibble_count;
36130fdc8d8SChris Lattner         }
36230fdc8d8SChris Lattner     }
36330fdc8d8SChris Lattner     return result;
36430fdc8d8SChris Lattner }
36530fdc8d8SChris Lattner 
36630fdc8d8SChris Lattner size_t
36730fdc8d8SChris Lattner StringExtractor::GetHexBytes (void *dst_void, size_t dst_len, uint8_t fail_fill_value)
36830fdc8d8SChris Lattner {
36930fdc8d8SChris Lattner     uint8_t *dst = (uint8_t*)dst_void;
37030fdc8d8SChris Lattner     size_t bytes_extracted = 0;
37130fdc8d8SChris Lattner     while (bytes_extracted < dst_len && GetBytesLeft ())
37230fdc8d8SChris Lattner     {
37330fdc8d8SChris Lattner         dst[bytes_extracted] = GetHexU8 (fail_fill_value);
37430fdc8d8SChris Lattner         if (IsGood())
37530fdc8d8SChris Lattner             ++bytes_extracted;
37630fdc8d8SChris Lattner         else
37730fdc8d8SChris Lattner             break;
37830fdc8d8SChris Lattner     }
37930fdc8d8SChris Lattner 
38030fdc8d8SChris Lattner     for (size_t i = bytes_extracted; i < dst_len; ++i)
38130fdc8d8SChris Lattner         dst[i] = fail_fill_value;
38230fdc8d8SChris Lattner 
38330fdc8d8SChris Lattner     return bytes_extracted;
38430fdc8d8SChris Lattner }
38530fdc8d8SChris Lattner 
38630fdc8d8SChris Lattner 
38730fdc8d8SChris Lattner // Consume ASCII hex nibble character pairs until we have decoded byte_size
38830fdc8d8SChris Lattner // bytes of data.
38930fdc8d8SChris Lattner 
39030fdc8d8SChris Lattner uint64_t
39130fdc8d8SChris Lattner StringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value)
39230fdc8d8SChris Lattner {
39330fdc8d8SChris Lattner     if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2)
39430fdc8d8SChris Lattner     {
39530fdc8d8SChris Lattner         uint64_t result = 0;
39630fdc8d8SChris Lattner         uint32_t i;
39730fdc8d8SChris Lattner         if (little_endian)
39830fdc8d8SChris Lattner         {
39930fdc8d8SChris Lattner             // Little Endian
40030fdc8d8SChris Lattner             uint32_t shift_amount;
40130fdc8d8SChris Lattner             for (i = 0, shift_amount = 0;
402c7bece56SGreg Clayton                  i < byte_size && IsGood();
40330fdc8d8SChris Lattner                  ++i, shift_amount += 8)
40430fdc8d8SChris Lattner             {
40530fdc8d8SChris Lattner                 result |= ((uint64_t)GetHexU8() << shift_amount);
40630fdc8d8SChris Lattner             }
40730fdc8d8SChris Lattner         }
40830fdc8d8SChris Lattner         else
40930fdc8d8SChris Lattner         {
41030fdc8d8SChris Lattner             // Big Endian
411c7bece56SGreg Clayton             for (i = 0; i < byte_size && IsGood(); ++i)
41230fdc8d8SChris Lattner             {
41330fdc8d8SChris Lattner                 result <<= 8;
41430fdc8d8SChris Lattner                 result |= GetHexU8();
41530fdc8d8SChris Lattner             }
41630fdc8d8SChris Lattner         }
41730fdc8d8SChris Lattner     }
418c7bece56SGreg Clayton     m_index = UINT64_MAX;
41930fdc8d8SChris Lattner     return fail_value;
42030fdc8d8SChris Lattner }
42130fdc8d8SChris Lattner 
422de9d0494SGreg Clayton size_t
423de9d0494SGreg Clayton StringExtractor::GetHexByteString (std::string &str)
424de9d0494SGreg Clayton {
425de9d0494SGreg Clayton     str.clear();
426de9d0494SGreg Clayton     char ch;
427de9d0494SGreg Clayton     while ((ch = GetHexU8()) != '\0')
428de9d0494SGreg Clayton         str.append(1, ch);
429de9d0494SGreg Clayton     return str.size();
430de9d0494SGreg Clayton }
431de9d0494SGreg Clayton 
432*e0f8f574SDaniel Malea size_t
433*e0f8f574SDaniel Malea StringExtractor::GetHexByteStringTerminatedBy (std::string &str,
434*e0f8f574SDaniel Malea                                                char terminator)
435*e0f8f574SDaniel Malea {
436*e0f8f574SDaniel Malea     str.clear();
437*e0f8f574SDaniel Malea     char ch;
438*e0f8f574SDaniel Malea     while ((ch = GetHexU8(0,false)) != '\0')
439*e0f8f574SDaniel Malea         str.append(1, ch);
440*e0f8f574SDaniel Malea     if (Peek() && *Peek() == terminator)
441*e0f8f574SDaniel Malea         return str.size();
442*e0f8f574SDaniel Malea     str.clear();
443*e0f8f574SDaniel Malea     return str.size();
444*e0f8f574SDaniel Malea }
445*e0f8f574SDaniel Malea 
44630fdc8d8SChris Lattner bool
44730fdc8d8SChris Lattner StringExtractor::GetNameColonValue (std::string &name, std::string &value)
44830fdc8d8SChris Lattner {
44930fdc8d8SChris Lattner     // Read something in the form of NNNN:VVVV; where NNNN is any character
45030fdc8d8SChris Lattner     // that is not a colon, followed by a ':' character, then a value (one or
45130fdc8d8SChris Lattner     // more ';' chars), followed by a ';'
45230fdc8d8SChris Lattner     if (m_index < m_packet.size())
45330fdc8d8SChris Lattner     {
45430fdc8d8SChris Lattner         const size_t colon_idx = m_packet.find (':', m_index);
45530fdc8d8SChris Lattner         if (colon_idx != std::string::npos)
45630fdc8d8SChris Lattner         {
45730fdc8d8SChris Lattner             const size_t semicolon_idx = m_packet.find (';', colon_idx);
45830fdc8d8SChris Lattner             if (semicolon_idx != std::string::npos)
45930fdc8d8SChris Lattner             {
46030fdc8d8SChris Lattner                 name.assign (m_packet, m_index, colon_idx - m_index);
46130fdc8d8SChris Lattner                 value.assign (m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1));
46230fdc8d8SChris Lattner                 m_index = semicolon_idx + 1;
46330fdc8d8SChris Lattner                 return true;
46430fdc8d8SChris Lattner             }
46530fdc8d8SChris Lattner         }
46630fdc8d8SChris Lattner     }
467c7bece56SGreg Clayton     m_index = UINT64_MAX;
46830fdc8d8SChris Lattner     return false;
46930fdc8d8SChris Lattner }
470