1*72090c21SPavel Labath //===-- StdStringExtractor.cpp ----------------------------------*- C++ -*-===//
2*72090c21SPavel Labath //
3*72090c21SPavel Labath //                     The LLVM Compiler Infrastructure
4*72090c21SPavel Labath //
5*72090c21SPavel Labath // This file is distributed under the University of Illinois Open Source
6*72090c21SPavel Labath // License. See LICENSE.TXT for details.
7*72090c21SPavel Labath //
8*72090c21SPavel Labath //===----------------------------------------------------------------------===//
9*72090c21SPavel Labath 
10*72090c21SPavel Labath #include "StdStringExtractor.h"
11*72090c21SPavel Labath 
12*72090c21SPavel Labath // C Includes
13*72090c21SPavel Labath #include <stdlib.h>
14*72090c21SPavel Labath 
15*72090c21SPavel Labath // C++ Includes
16*72090c21SPavel Labath // Other libraries and framework includes
17*72090c21SPavel Labath // Project includes
18*72090c21SPavel Labath 
19*72090c21SPavel Labath static inline int xdigit_to_sint(char ch) {
20*72090c21SPavel Labath   if (ch >= 'a' && ch <= 'f')
21*72090c21SPavel Labath     return 10 + ch - 'a';
22*72090c21SPavel Labath   if (ch >= 'A' && ch <= 'F')
23*72090c21SPavel Labath     return 10 + ch - 'A';
24*72090c21SPavel Labath   if (ch >= '0' && ch <= '9')
25*72090c21SPavel Labath     return ch - '0';
26*72090c21SPavel Labath   return -1;
27*72090c21SPavel Labath }
28*72090c21SPavel Labath 
29*72090c21SPavel Labath //----------------------------------------------------------------------
30*72090c21SPavel Labath // StdStringExtractor constructor
31*72090c21SPavel Labath //----------------------------------------------------------------------
32*72090c21SPavel Labath StdStringExtractor::StdStringExtractor() : m_packet(), m_index(0) {}
33*72090c21SPavel Labath 
34*72090c21SPavel Labath StdStringExtractor::StdStringExtractor(const char *packet_cstr)
35*72090c21SPavel Labath     : m_packet(), m_index(0) {
36*72090c21SPavel Labath   if (packet_cstr)
37*72090c21SPavel Labath     m_packet.assign(packet_cstr);
38*72090c21SPavel Labath }
39*72090c21SPavel Labath 
40*72090c21SPavel Labath //----------------------------------------------------------------------
41*72090c21SPavel Labath // StdStringExtractor copy constructor
42*72090c21SPavel Labath //----------------------------------------------------------------------
43*72090c21SPavel Labath StdStringExtractor::StdStringExtractor(const StdStringExtractor &rhs)
44*72090c21SPavel Labath     : m_packet(rhs.m_packet), m_index(rhs.m_index) {}
45*72090c21SPavel Labath 
46*72090c21SPavel Labath //----------------------------------------------------------------------
47*72090c21SPavel Labath // StdStringExtractor assignment operator
48*72090c21SPavel Labath //----------------------------------------------------------------------
49*72090c21SPavel Labath const StdStringExtractor &StdStringExtractor::
50*72090c21SPavel Labath operator=(const StdStringExtractor &rhs) {
51*72090c21SPavel Labath   if (this != &rhs) {
52*72090c21SPavel Labath     m_packet = rhs.m_packet;
53*72090c21SPavel Labath     m_index = rhs.m_index;
54*72090c21SPavel Labath   }
55*72090c21SPavel Labath   return *this;
56*72090c21SPavel Labath }
57*72090c21SPavel Labath 
58*72090c21SPavel Labath //----------------------------------------------------------------------
59*72090c21SPavel Labath // Destructor
60*72090c21SPavel Labath //----------------------------------------------------------------------
61*72090c21SPavel Labath StdStringExtractor::~StdStringExtractor() {}
62*72090c21SPavel Labath 
63*72090c21SPavel Labath char StdStringExtractor::GetChar(char fail_value) {
64*72090c21SPavel Labath   if (m_index < m_packet.size()) {
65*72090c21SPavel Labath     char ch = m_packet[m_index];
66*72090c21SPavel Labath     ++m_index;
67*72090c21SPavel Labath     return ch;
68*72090c21SPavel Labath   }
69*72090c21SPavel Labath   m_index = UINT64_MAX;
70*72090c21SPavel Labath   return fail_value;
71*72090c21SPavel Labath }
72*72090c21SPavel Labath 
73*72090c21SPavel Labath //----------------------------------------------------------------------
74*72090c21SPavel Labath // If a pair of valid hex digits exist at the head of the
75*72090c21SPavel Labath // StdStringExtractor they are decoded into an unsigned byte and returned
76*72090c21SPavel Labath // by this function
77*72090c21SPavel Labath //
78*72090c21SPavel Labath // If there is not a pair of valid hex digits at the head of the
79*72090c21SPavel Labath // StdStringExtractor, it is left unchanged and -1 is returned
80*72090c21SPavel Labath //----------------------------------------------------------------------
81*72090c21SPavel Labath int StdStringExtractor::DecodeHexU8() {
82*72090c21SPavel Labath   SkipSpaces();
83*72090c21SPavel Labath   if (GetBytesLeft() < 2) {
84*72090c21SPavel Labath     return -1;
85*72090c21SPavel Labath   }
86*72090c21SPavel Labath   const int hi_nibble = xdigit_to_sint(m_packet[m_index]);
87*72090c21SPavel Labath   const int lo_nibble = xdigit_to_sint(m_packet[m_index + 1]);
88*72090c21SPavel Labath   if (hi_nibble == -1 || lo_nibble == -1) {
89*72090c21SPavel Labath     return -1;
90*72090c21SPavel Labath   }
91*72090c21SPavel Labath   m_index += 2;
92*72090c21SPavel Labath   return (uint8_t)((hi_nibble << 4) + lo_nibble);
93*72090c21SPavel Labath }
94*72090c21SPavel Labath 
95*72090c21SPavel Labath //----------------------------------------------------------------------
96*72090c21SPavel Labath // Extract an unsigned character from two hex ASCII chars in the packet
97*72090c21SPavel Labath // string, or return fail_value on failure
98*72090c21SPavel Labath //----------------------------------------------------------------------
99*72090c21SPavel Labath uint8_t StdStringExtractor::GetHexU8(uint8_t fail_value, bool set_eof_on_fail) {
100*72090c21SPavel Labath   // On success, fail_value will be overwritten with the next
101*72090c21SPavel Labath   // character in the stream
102*72090c21SPavel Labath   GetHexU8Ex(fail_value, set_eof_on_fail);
103*72090c21SPavel Labath   return fail_value;
104*72090c21SPavel Labath }
105*72090c21SPavel Labath 
106*72090c21SPavel Labath bool StdStringExtractor::GetHexU8Ex(uint8_t &ch, bool set_eof_on_fail) {
107*72090c21SPavel Labath   int byte = DecodeHexU8();
108*72090c21SPavel Labath   if (byte == -1) {
109*72090c21SPavel Labath     if (set_eof_on_fail || m_index >= m_packet.size())
110*72090c21SPavel Labath       m_index = UINT64_MAX;
111*72090c21SPavel Labath     // ch should not be changed in case of failure
112*72090c21SPavel Labath     return false;
113*72090c21SPavel Labath   }
114*72090c21SPavel Labath   ch = (uint8_t)byte;
115*72090c21SPavel Labath   return true;
116*72090c21SPavel Labath }
117*72090c21SPavel Labath 
118*72090c21SPavel Labath uint32_t StdStringExtractor::GetU32(uint32_t fail_value, int base) {
119*72090c21SPavel Labath   if (m_index < m_packet.size()) {
120*72090c21SPavel Labath     char *end = nullptr;
121*72090c21SPavel Labath     const char *start = m_packet.c_str();
122*72090c21SPavel Labath     const char *cstr = start + m_index;
123*72090c21SPavel Labath     uint32_t result = static_cast<uint32_t>(::strtoul(cstr, &end, base));
124*72090c21SPavel Labath 
125*72090c21SPavel Labath     if (end && end != cstr) {
126*72090c21SPavel Labath       m_index = end - start;
127*72090c21SPavel Labath       return result;
128*72090c21SPavel Labath     }
129*72090c21SPavel Labath   }
130*72090c21SPavel Labath   return fail_value;
131*72090c21SPavel Labath }
132*72090c21SPavel Labath 
133*72090c21SPavel Labath int32_t StdStringExtractor::GetS32(int32_t fail_value, int base) {
134*72090c21SPavel Labath   if (m_index < m_packet.size()) {
135*72090c21SPavel Labath     char *end = nullptr;
136*72090c21SPavel Labath     const char *start = m_packet.c_str();
137*72090c21SPavel Labath     const char *cstr = start + m_index;
138*72090c21SPavel Labath     int32_t result = static_cast<int32_t>(::strtol(cstr, &end, base));
139*72090c21SPavel Labath 
140*72090c21SPavel Labath     if (end && end != cstr) {
141*72090c21SPavel Labath       m_index = end - start;
142*72090c21SPavel Labath       return result;
143*72090c21SPavel Labath     }
144*72090c21SPavel Labath   }
145*72090c21SPavel Labath   return fail_value;
146*72090c21SPavel Labath }
147*72090c21SPavel Labath 
148*72090c21SPavel Labath uint64_t StdStringExtractor::GetU64(uint64_t fail_value, int base) {
149*72090c21SPavel Labath   if (m_index < m_packet.size()) {
150*72090c21SPavel Labath     char *end = nullptr;
151*72090c21SPavel Labath     const char *start = m_packet.c_str();
152*72090c21SPavel Labath     const char *cstr = start + m_index;
153*72090c21SPavel Labath     uint64_t result = ::strtoull(cstr, &end, base);
154*72090c21SPavel Labath 
155*72090c21SPavel Labath     if (end && end != cstr) {
156*72090c21SPavel Labath       m_index = end - start;
157*72090c21SPavel Labath       return result;
158*72090c21SPavel Labath     }
159*72090c21SPavel Labath   }
160*72090c21SPavel Labath   return fail_value;
161*72090c21SPavel Labath }
162*72090c21SPavel Labath 
163*72090c21SPavel Labath int64_t StdStringExtractor::GetS64(int64_t fail_value, int base) {
164*72090c21SPavel Labath   if (m_index < m_packet.size()) {
165*72090c21SPavel Labath     char *end = nullptr;
166*72090c21SPavel Labath     const char *start = m_packet.c_str();
167*72090c21SPavel Labath     const char *cstr = start + m_index;
168*72090c21SPavel Labath     int64_t result = ::strtoll(cstr, &end, base);
169*72090c21SPavel Labath 
170*72090c21SPavel Labath     if (end && end != cstr) {
171*72090c21SPavel Labath       m_index = end - start;
172*72090c21SPavel Labath       return result;
173*72090c21SPavel Labath     }
174*72090c21SPavel Labath   }
175*72090c21SPavel Labath   return fail_value;
176*72090c21SPavel Labath }
177*72090c21SPavel Labath 
178*72090c21SPavel Labath uint32_t StdStringExtractor::GetHexMaxU32(bool little_endian,
179*72090c21SPavel Labath                                           uint32_t fail_value) {
180*72090c21SPavel Labath   uint32_t result = 0;
181*72090c21SPavel Labath   uint32_t nibble_count = 0;
182*72090c21SPavel Labath 
183*72090c21SPavel Labath   SkipSpaces();
184*72090c21SPavel Labath   if (little_endian) {
185*72090c21SPavel Labath     uint32_t shift_amount = 0;
186*72090c21SPavel Labath     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
187*72090c21SPavel Labath       // Make sure we don't exceed the size of a uint32_t...
188*72090c21SPavel Labath       if (nibble_count >= (sizeof(uint32_t) * 2)) {
189*72090c21SPavel Labath         m_index = UINT64_MAX;
190*72090c21SPavel Labath         return fail_value;
191*72090c21SPavel Labath       }
192*72090c21SPavel Labath 
193*72090c21SPavel Labath       uint8_t nibble_lo;
194*72090c21SPavel Labath       uint8_t nibble_hi = xdigit_to_sint(m_packet[m_index]);
195*72090c21SPavel Labath       ++m_index;
196*72090c21SPavel Labath       if (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
197*72090c21SPavel Labath         nibble_lo = xdigit_to_sint(m_packet[m_index]);
198*72090c21SPavel Labath         ++m_index;
199*72090c21SPavel Labath         result |= ((uint32_t)nibble_hi << (shift_amount + 4));
200*72090c21SPavel Labath         result |= ((uint32_t)nibble_lo << shift_amount);
201*72090c21SPavel Labath         nibble_count += 2;
202*72090c21SPavel Labath         shift_amount += 8;
203*72090c21SPavel Labath       } else {
204*72090c21SPavel Labath         result |= ((uint32_t)nibble_hi << shift_amount);
205*72090c21SPavel Labath         nibble_count += 1;
206*72090c21SPavel Labath         shift_amount += 4;
207*72090c21SPavel Labath       }
208*72090c21SPavel Labath     }
209*72090c21SPavel Labath   } else {
210*72090c21SPavel Labath     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
211*72090c21SPavel Labath       // Make sure we don't exceed the size of a uint32_t...
212*72090c21SPavel Labath       if (nibble_count >= (sizeof(uint32_t) * 2)) {
213*72090c21SPavel Labath         m_index = UINT64_MAX;
214*72090c21SPavel Labath         return fail_value;
215*72090c21SPavel Labath       }
216*72090c21SPavel Labath 
217*72090c21SPavel Labath       uint8_t nibble = xdigit_to_sint(m_packet[m_index]);
218*72090c21SPavel Labath       // Big Endian
219*72090c21SPavel Labath       result <<= 4;
220*72090c21SPavel Labath       result |= nibble;
221*72090c21SPavel Labath 
222*72090c21SPavel Labath       ++m_index;
223*72090c21SPavel Labath       ++nibble_count;
224*72090c21SPavel Labath     }
225*72090c21SPavel Labath   }
226*72090c21SPavel Labath   return result;
227*72090c21SPavel Labath }
228*72090c21SPavel Labath 
229*72090c21SPavel Labath uint64_t StdStringExtractor::GetHexMaxU64(bool little_endian,
230*72090c21SPavel Labath                                           uint64_t fail_value) {
231*72090c21SPavel Labath   uint64_t result = 0;
232*72090c21SPavel Labath   uint32_t nibble_count = 0;
233*72090c21SPavel Labath 
234*72090c21SPavel Labath   SkipSpaces();
235*72090c21SPavel Labath   if (little_endian) {
236*72090c21SPavel Labath     uint32_t shift_amount = 0;
237*72090c21SPavel Labath     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
238*72090c21SPavel Labath       // Make sure we don't exceed the size of a uint64_t...
239*72090c21SPavel Labath       if (nibble_count >= (sizeof(uint64_t) * 2)) {
240*72090c21SPavel Labath         m_index = UINT64_MAX;
241*72090c21SPavel Labath         return fail_value;
242*72090c21SPavel Labath       }
243*72090c21SPavel Labath 
244*72090c21SPavel Labath       uint8_t nibble_lo;
245*72090c21SPavel Labath       uint8_t nibble_hi = xdigit_to_sint(m_packet[m_index]);
246*72090c21SPavel Labath       ++m_index;
247*72090c21SPavel Labath       if (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
248*72090c21SPavel Labath         nibble_lo = xdigit_to_sint(m_packet[m_index]);
249*72090c21SPavel Labath         ++m_index;
250*72090c21SPavel Labath         result |= ((uint64_t)nibble_hi << (shift_amount + 4));
251*72090c21SPavel Labath         result |= ((uint64_t)nibble_lo << shift_amount);
252*72090c21SPavel Labath         nibble_count += 2;
253*72090c21SPavel Labath         shift_amount += 8;
254*72090c21SPavel Labath       } else {
255*72090c21SPavel Labath         result |= ((uint64_t)nibble_hi << shift_amount);
256*72090c21SPavel Labath         nibble_count += 1;
257*72090c21SPavel Labath         shift_amount += 4;
258*72090c21SPavel Labath       }
259*72090c21SPavel Labath     }
260*72090c21SPavel Labath   } else {
261*72090c21SPavel Labath     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
262*72090c21SPavel Labath       // Make sure we don't exceed the size of a uint64_t...
263*72090c21SPavel Labath       if (nibble_count >= (sizeof(uint64_t) * 2)) {
264*72090c21SPavel Labath         m_index = UINT64_MAX;
265*72090c21SPavel Labath         return fail_value;
266*72090c21SPavel Labath       }
267*72090c21SPavel Labath 
268*72090c21SPavel Labath       uint8_t nibble = xdigit_to_sint(m_packet[m_index]);
269*72090c21SPavel Labath       // Big Endian
270*72090c21SPavel Labath       result <<= 4;
271*72090c21SPavel Labath       result |= nibble;
272*72090c21SPavel Labath 
273*72090c21SPavel Labath       ++m_index;
274*72090c21SPavel Labath       ++nibble_count;
275*72090c21SPavel Labath     }
276*72090c21SPavel Labath   }
277*72090c21SPavel Labath   return result;
278*72090c21SPavel Labath }
279*72090c21SPavel Labath 
280*72090c21SPavel Labath size_t StdStringExtractor::GetHexBytes(void *dst_void, size_t dst_len,
281*72090c21SPavel Labath                                        uint8_t fail_fill_value) {
282*72090c21SPavel Labath   uint8_t *dst = (uint8_t *)dst_void;
283*72090c21SPavel Labath   size_t bytes_extracted = 0;
284*72090c21SPavel Labath   while (bytes_extracted < dst_len && GetBytesLeft()) {
285*72090c21SPavel Labath     dst[bytes_extracted] = GetHexU8(fail_fill_value);
286*72090c21SPavel Labath     if (IsGood())
287*72090c21SPavel Labath       ++bytes_extracted;
288*72090c21SPavel Labath     else
289*72090c21SPavel Labath       break;
290*72090c21SPavel Labath   }
291*72090c21SPavel Labath 
292*72090c21SPavel Labath   for (size_t i = bytes_extracted; i < dst_len; ++i)
293*72090c21SPavel Labath     dst[i] = fail_fill_value;
294*72090c21SPavel Labath 
295*72090c21SPavel Labath   return bytes_extracted;
296*72090c21SPavel Labath }
297*72090c21SPavel Labath 
298*72090c21SPavel Labath //----------------------------------------------------------------------
299*72090c21SPavel Labath // Decodes all valid hex encoded bytes at the head of the
300*72090c21SPavel Labath // StdStringExtractor, limited by dst_len.
301*72090c21SPavel Labath //
302*72090c21SPavel Labath // Returns the number of bytes successfully decoded
303*72090c21SPavel Labath //----------------------------------------------------------------------
304*72090c21SPavel Labath size_t StdStringExtractor::GetHexBytesAvail(void *dst_void, size_t dst_len) {
305*72090c21SPavel Labath   uint8_t *dst = (uint8_t *)dst_void;
306*72090c21SPavel Labath   size_t bytes_extracted = 0;
307*72090c21SPavel Labath   while (bytes_extracted < dst_len) {
308*72090c21SPavel Labath     int decode = DecodeHexU8();
309*72090c21SPavel Labath     if (decode == -1) {
310*72090c21SPavel Labath       break;
311*72090c21SPavel Labath     }
312*72090c21SPavel Labath     dst[bytes_extracted++] = (uint8_t)decode;
313*72090c21SPavel Labath   }
314*72090c21SPavel Labath   return bytes_extracted;
315*72090c21SPavel Labath }
316*72090c21SPavel Labath 
317*72090c21SPavel Labath // Consume ASCII hex nibble character pairs until we have decoded byte_size
318*72090c21SPavel Labath // bytes of data.
319*72090c21SPavel Labath 
320*72090c21SPavel Labath uint64_t StdStringExtractor::GetHexWithFixedSize(uint32_t byte_size,
321*72090c21SPavel Labath                                                  bool little_endian,
322*72090c21SPavel Labath                                                  uint64_t fail_value) {
323*72090c21SPavel Labath   if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2) {
324*72090c21SPavel Labath     uint64_t result = 0;
325*72090c21SPavel Labath     uint32_t i;
326*72090c21SPavel Labath     if (little_endian) {
327*72090c21SPavel Labath       // Little Endian
328*72090c21SPavel Labath       uint32_t shift_amount;
329*72090c21SPavel Labath       for (i = 0, shift_amount = 0; i < byte_size && IsGood();
330*72090c21SPavel Labath            ++i, shift_amount += 8) {
331*72090c21SPavel Labath         result |= ((uint64_t)GetHexU8() << shift_amount);
332*72090c21SPavel Labath       }
333*72090c21SPavel Labath     } else {
334*72090c21SPavel Labath       // Big Endian
335*72090c21SPavel Labath       for (i = 0; i < byte_size && IsGood(); ++i) {
336*72090c21SPavel Labath         result <<= 8;
337*72090c21SPavel Labath         result |= GetHexU8();
338*72090c21SPavel Labath       }
339*72090c21SPavel Labath     }
340*72090c21SPavel Labath   }
341*72090c21SPavel Labath   m_index = UINT64_MAX;
342*72090c21SPavel Labath   return fail_value;
343*72090c21SPavel Labath }
344*72090c21SPavel Labath 
345*72090c21SPavel Labath size_t StdStringExtractor::GetHexByteString(std::string &str) {
346*72090c21SPavel Labath   str.clear();
347*72090c21SPavel Labath   str.reserve(GetBytesLeft() / 2);
348*72090c21SPavel Labath   char ch;
349*72090c21SPavel Labath   while ((ch = GetHexU8()) != '\0')
350*72090c21SPavel Labath     str.append(1, ch);
351*72090c21SPavel Labath   return str.size();
352*72090c21SPavel Labath }
353*72090c21SPavel Labath 
354*72090c21SPavel Labath size_t StdStringExtractor::GetHexByteStringFixedLength(std::string &str,
355*72090c21SPavel Labath                                                        uint32_t nibble_length) {
356*72090c21SPavel Labath   str.clear();
357*72090c21SPavel Labath 
358*72090c21SPavel Labath   uint32_t nibble_count = 0;
359*72090c21SPavel Labath   for (const char *pch = Peek();
360*72090c21SPavel Labath        (nibble_count < nibble_length) && (pch != nullptr);
361*72090c21SPavel Labath        str.append(1, GetHexU8(0, false)), pch = Peek(), nibble_count += 2) {
362*72090c21SPavel Labath   }
363*72090c21SPavel Labath 
364*72090c21SPavel Labath   return str.size();
365*72090c21SPavel Labath }
366*72090c21SPavel Labath 
367*72090c21SPavel Labath size_t StdStringExtractor::GetHexByteStringTerminatedBy(std::string &str,
368*72090c21SPavel Labath                                                         char terminator) {
369*72090c21SPavel Labath   str.clear();
370*72090c21SPavel Labath   char ch;
371*72090c21SPavel Labath   while ((ch = GetHexU8(0, false)) != '\0')
372*72090c21SPavel Labath     str.append(1, ch);
373*72090c21SPavel Labath   if (Peek() && *Peek() == terminator)
374*72090c21SPavel Labath     return str.size();
375*72090c21SPavel Labath 
376*72090c21SPavel Labath   str.clear();
377*72090c21SPavel Labath   return str.size();
378*72090c21SPavel Labath }
379*72090c21SPavel Labath 
380*72090c21SPavel Labath bool StdStringExtractor::GetNameColonValue(std::string &name,
381*72090c21SPavel Labath                                            std::string &value) {
382*72090c21SPavel Labath   // Read something in the form of NNNN:VVVV; where NNNN is any character
383*72090c21SPavel Labath   // that is not a colon, followed by a ':' character, then a value (one or
384*72090c21SPavel Labath   // more ';' chars), followed by a ';'
385*72090c21SPavel Labath   if (m_index < m_packet.size()) {
386*72090c21SPavel Labath     const size_t colon_idx = m_packet.find(':', m_index);
387*72090c21SPavel Labath     if (colon_idx != std::string::npos) {
388*72090c21SPavel Labath       const size_t semicolon_idx = m_packet.find(';', colon_idx);
389*72090c21SPavel Labath       if (semicolon_idx != std::string::npos) {
390*72090c21SPavel Labath         name.assign(m_packet, m_index, colon_idx - m_index);
391*72090c21SPavel Labath         value.assign(m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1));
392*72090c21SPavel Labath         m_index = semicolon_idx + 1;
393*72090c21SPavel Labath         return true;
394*72090c21SPavel Labath       }
395*72090c21SPavel Labath     }
396*72090c21SPavel Labath   }
397*72090c21SPavel Labath   m_index = UINT64_MAX;
398*72090c21SPavel Labath   return false;
399*72090c21SPavel Labath }
400*72090c21SPavel Labath 
401*72090c21SPavel Labath void StdStringExtractor::SkipSpaces() {
402*72090c21SPavel Labath   const size_t n = m_packet.size();
403*72090c21SPavel Labath   while (m_index < n && isspace(m_packet[m_index]))
404*72090c21SPavel Labath     ++m_index;
405*72090c21SPavel Labath }
406