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 
10f805e190SPavel Labath #include "lldb/Utility/StringExtractor.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1378709173SStephen Wilson #include <stdlib.h>
1478709173SStephen Wilson 
1530fdc8d8SChris Lattner // C++ Includes
1654695a33SZachary Turner #include <tuple>
1730fdc8d8SChris Lattner // Other libraries and framework includes
1830fdc8d8SChris Lattner // Project includes
1930fdc8d8SChris Lattner 
20*b9c1b51eSKate Stone static inline int xdigit_to_sint(char ch) {
2130fdc8d8SChris Lattner   if (ch >= 'a' && ch <= 'f')
2230fdc8d8SChris Lattner     return 10 + ch - 'a';
231e89cd80SBenjamin Kramer   if (ch >= 'A' && ch <= 'F')
241e89cd80SBenjamin Kramer     return 10 + ch - 'A';
256eddf8dfSVince Harron   if (ch >= '0' && ch <= '9')
2630fdc8d8SChris Lattner     return ch - '0';
276eddf8dfSVince Harron   return -1;
2830fdc8d8SChris Lattner }
2930fdc8d8SChris Lattner 
3030fdc8d8SChris Lattner //----------------------------------------------------------------------
3130fdc8d8SChris Lattner // StringExtractor constructor
3230fdc8d8SChris Lattner //----------------------------------------------------------------------
33*b9c1b51eSKate Stone StringExtractor::StringExtractor() : m_packet(), m_index(0) {}
3430fdc8d8SChris Lattner 
35*b9c1b51eSKate Stone StringExtractor::StringExtractor(llvm::StringRef packet_str)
36*b9c1b51eSKate Stone     : m_packet(), m_index(0) {
3754695a33SZachary Turner   m_packet.assign(packet_str.begin(), packet_str.end());
3854695a33SZachary Turner }
3930fdc8d8SChris Lattner 
40*b9c1b51eSKate Stone StringExtractor::StringExtractor(const char *packet_cstr)
41*b9c1b51eSKate Stone     : m_packet(), m_index(0) {
4230fdc8d8SChris Lattner   if (packet_cstr)
4330fdc8d8SChris Lattner     m_packet.assign(packet_cstr);
4430fdc8d8SChris Lattner }
4530fdc8d8SChris Lattner 
4630fdc8d8SChris Lattner //----------------------------------------------------------------------
4730fdc8d8SChris Lattner // StringExtractor copy constructor
4830fdc8d8SChris Lattner //----------------------------------------------------------------------
49*b9c1b51eSKate Stone StringExtractor::StringExtractor(const StringExtractor &rhs)
50*b9c1b51eSKate Stone     : m_packet(rhs.m_packet), m_index(rhs.m_index) {}
5130fdc8d8SChris Lattner 
5230fdc8d8SChris Lattner //----------------------------------------------------------------------
5330fdc8d8SChris Lattner // StringExtractor assignment operator
5430fdc8d8SChris Lattner //----------------------------------------------------------------------
55*b9c1b51eSKate Stone const StringExtractor &StringExtractor::operator=(const StringExtractor &rhs) {
56*b9c1b51eSKate Stone   if (this != &rhs) {
5730fdc8d8SChris Lattner     m_packet = rhs.m_packet;
5830fdc8d8SChris Lattner     m_index = rhs.m_index;
5930fdc8d8SChris Lattner   }
6030fdc8d8SChris Lattner   return *this;
6130fdc8d8SChris Lattner }
6230fdc8d8SChris Lattner 
6330fdc8d8SChris Lattner //----------------------------------------------------------------------
6430fdc8d8SChris Lattner // Destructor
6530fdc8d8SChris Lattner //----------------------------------------------------------------------
66*b9c1b51eSKate Stone StringExtractor::~StringExtractor() {}
6730fdc8d8SChris Lattner 
68*b9c1b51eSKate Stone char StringExtractor::GetChar(char fail_value) {
69*b9c1b51eSKate Stone   if (m_index < m_packet.size()) {
7030fdc8d8SChris Lattner     char ch = m_packet[m_index];
7130fdc8d8SChris Lattner     ++m_index;
7230fdc8d8SChris Lattner     return ch;
7330fdc8d8SChris Lattner   }
74c7bece56SGreg Clayton   m_index = UINT64_MAX;
7530fdc8d8SChris Lattner   return fail_value;
7630fdc8d8SChris Lattner }
7730fdc8d8SChris Lattner 
7830fdc8d8SChris Lattner //----------------------------------------------------------------------
796eddf8dfSVince Harron // If a pair of valid hex digits exist at the head of the
806eddf8dfSVince Harron // StringExtractor they are decoded into an unsigned byte and returned
816eddf8dfSVince Harron // by this function
826eddf8dfSVince Harron //
836eddf8dfSVince Harron // If there is not a pair of valid hex digits at the head of the
846eddf8dfSVince Harron // StringExtractor, it is left unchanged and -1 is returned
856eddf8dfSVince Harron //----------------------------------------------------------------------
86*b9c1b51eSKate Stone int StringExtractor::DecodeHexU8() {
8715a2165dSFrancis Ricci   SkipSpaces();
88*b9c1b51eSKate Stone   if (GetBytesLeft() < 2) {
896eddf8dfSVince Harron     return -1;
90b9739d40SPavel Labath   }
91b9739d40SPavel Labath   const int hi_nibble = xdigit_to_sint(m_packet[m_index]);
92b9739d40SPavel Labath   const int lo_nibble = xdigit_to_sint(m_packet[m_index + 1]);
93*b9c1b51eSKate Stone   if (hi_nibble == -1 || lo_nibble == -1) {
946eddf8dfSVince Harron     return -1;
95b9739d40SPavel Labath   }
966eddf8dfSVince Harron   m_index += 2;
97b9739d40SPavel Labath   return (uint8_t)((hi_nibble << 4) + lo_nibble);
986eddf8dfSVince Harron }
996eddf8dfSVince Harron 
1006eddf8dfSVince Harron //----------------------------------------------------------------------
10130fdc8d8SChris Lattner // Extract an unsigned character from two hex ASCII chars in the packet
1025e8115b3SDawn Perchik // string, or return fail_value on failure
10330fdc8d8SChris Lattner //----------------------------------------------------------------------
104*b9c1b51eSKate Stone uint8_t StringExtractor::GetHexU8(uint8_t fail_value, bool set_eof_on_fail) {
1055e8115b3SDawn Perchik   // On success, fail_value will be overwritten with the next
1065e8115b3SDawn Perchik   // character in the stream
107554a8571SDawn Perchik   GetHexU8Ex(fail_value, set_eof_on_fail);
108554a8571SDawn Perchik   return fail_value;
109554a8571SDawn Perchik }
110554a8571SDawn Perchik 
111*b9c1b51eSKate Stone bool StringExtractor::GetHexU8Ex(uint8_t &ch, bool set_eof_on_fail) {
1126eddf8dfSVince Harron   int byte = DecodeHexU8();
113*b9c1b51eSKate Stone   if (byte == -1) {
1147b70be39SGreg Clayton     if (set_eof_on_fail || m_index >= m_packet.size())
115c7bece56SGreg Clayton       m_index = UINT64_MAX;
116554a8571SDawn Perchik     // ch should not be changed in case of failure
117554a8571SDawn Perchik     return false;
11830fdc8d8SChris Lattner   }
119554a8571SDawn Perchik   ch = (uint8_t)byte;
120554a8571SDawn Perchik   return true;
1216eddf8dfSVince Harron }
12230fdc8d8SChris Lattner 
123*b9c1b51eSKate Stone uint32_t StringExtractor::GetU32(uint32_t fail_value, int base) {
124*b9c1b51eSKate Stone   if (m_index < m_packet.size()) {
125d4612ad0SEd Maste     char *end = nullptr;
12632e0a750SGreg Clayton     const char *start = m_packet.c_str();
127e0f8f574SDaniel Malea     const char *cstr = start + m_index;
128f2d44ca8SEnrico Granata     uint32_t result = static_cast<uint32_t>(::strtoul(cstr, &end, base));
12932e0a750SGreg Clayton 
130*b9c1b51eSKate Stone     if (end && end != cstr) {
131e0f8f574SDaniel Malea       m_index = end - start;
132e0f8f574SDaniel Malea       return result;
133e0f8f574SDaniel Malea     }
134e0f8f574SDaniel Malea   }
135e0f8f574SDaniel Malea   return fail_value;
136e0f8f574SDaniel Malea }
137e0f8f574SDaniel Malea 
138*b9c1b51eSKate Stone int32_t StringExtractor::GetS32(int32_t fail_value, int base) {
139*b9c1b51eSKate Stone   if (m_index < m_packet.size()) {
140d4612ad0SEd Maste     char *end = nullptr;
141e0f8f574SDaniel Malea     const char *start = m_packet.c_str();
142e0f8f574SDaniel Malea     const char *cstr = start + m_index;
143f2d44ca8SEnrico Granata     int32_t result = static_cast<int32_t>(::strtol(cstr, &end, base));
144e0f8f574SDaniel Malea 
145*b9c1b51eSKate Stone     if (end && end != cstr) {
146e0f8f574SDaniel Malea       m_index = end - start;
147e0f8f574SDaniel Malea       return result;
148e0f8f574SDaniel Malea     }
149e0f8f574SDaniel Malea   }
150e0f8f574SDaniel Malea   return fail_value;
151e0f8f574SDaniel Malea }
152e0f8f574SDaniel Malea 
153*b9c1b51eSKate Stone uint64_t StringExtractor::GetU64(uint64_t fail_value, int base) {
154*b9c1b51eSKate Stone   if (m_index < m_packet.size()) {
155d4612ad0SEd Maste     char *end = nullptr;
156e0f8f574SDaniel Malea     const char *start = m_packet.c_str();
157e0f8f574SDaniel Malea     const char *cstr = start + m_index;
158e0f8f574SDaniel Malea     uint64_t result = ::strtoull(cstr, &end, base);
159e0f8f574SDaniel Malea 
160*b9c1b51eSKate Stone     if (end && end != cstr) {
161e0f8f574SDaniel Malea       m_index = end - start;
162e0f8f574SDaniel Malea       return result;
163e0f8f574SDaniel Malea     }
164e0f8f574SDaniel Malea   }
165e0f8f574SDaniel Malea   return fail_value;
166e0f8f574SDaniel Malea }
167e0f8f574SDaniel Malea 
168*b9c1b51eSKate Stone int64_t StringExtractor::GetS64(int64_t fail_value, int base) {
169*b9c1b51eSKate Stone   if (m_index < m_packet.size()) {
170d4612ad0SEd Maste     char *end = nullptr;
171e0f8f574SDaniel Malea     const char *start = m_packet.c_str();
172e0f8f574SDaniel Malea     const char *cstr = start + m_index;
173e0f8f574SDaniel Malea     int64_t result = ::strtoll(cstr, &end, base);
174e0f8f574SDaniel Malea 
175*b9c1b51eSKate Stone     if (end && end != cstr) {
17632e0a750SGreg Clayton       m_index = end - start;
17732e0a750SGreg Clayton       return result;
17832e0a750SGreg Clayton     }
17932e0a750SGreg Clayton   }
18032e0a750SGreg Clayton   return fail_value;
18132e0a750SGreg Clayton }
18232e0a750SGreg Clayton 
183*b9c1b51eSKate Stone uint32_t StringExtractor::GetHexMaxU32(bool little_endian,
184*b9c1b51eSKate Stone                                        uint32_t fail_value) {
185b9739d40SPavel Labath   uint32_t result = 0;
186b9739d40SPavel Labath   uint32_t nibble_count = 0;
187b9739d40SPavel Labath 
18815a2165dSFrancis Ricci   SkipSpaces();
189*b9c1b51eSKate Stone   if (little_endian) {
190b9739d40SPavel Labath     uint32_t shift_amount = 0;
191*b9c1b51eSKate Stone     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
192b9739d40SPavel Labath       // Make sure we don't exceed the size of a uint32_t...
193*b9c1b51eSKate Stone       if (nibble_count >= (sizeof(uint32_t) * 2)) {
194b9739d40SPavel Labath         m_index = UINT64_MAX;
195b9739d40SPavel Labath         return fail_value;
196b9739d40SPavel Labath       }
197b9739d40SPavel Labath 
198b9739d40SPavel Labath       uint8_t nibble_lo;
199b9739d40SPavel Labath       uint8_t nibble_hi = xdigit_to_sint(m_packet[m_index]);
200b9739d40SPavel Labath       ++m_index;
201*b9c1b51eSKate Stone       if (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
202b9739d40SPavel Labath         nibble_lo = xdigit_to_sint(m_packet[m_index]);
203b9739d40SPavel Labath         ++m_index;
204b9739d40SPavel Labath         result |= ((uint32_t)nibble_hi << (shift_amount + 4));
205b9739d40SPavel Labath         result |= ((uint32_t)nibble_lo << shift_amount);
206b9739d40SPavel Labath         nibble_count += 2;
207b9739d40SPavel Labath         shift_amount += 8;
208*b9c1b51eSKate Stone       } else {
209b9739d40SPavel Labath         result |= ((uint32_t)nibble_hi << shift_amount);
210b9739d40SPavel Labath         nibble_count += 1;
211b9739d40SPavel Labath         shift_amount += 4;
21230fdc8d8SChris Lattner       }
213b9739d40SPavel Labath     }
214*b9c1b51eSKate Stone   } else {
215*b9c1b51eSKate Stone     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
216b9739d40SPavel Labath       // Make sure we don't exceed the size of a uint32_t...
217*b9c1b51eSKate Stone       if (nibble_count >= (sizeof(uint32_t) * 2)) {
218b9739d40SPavel Labath         m_index = UINT64_MAX;
219b9739d40SPavel Labath         return fail_value;
220b9739d40SPavel Labath       }
221b9739d40SPavel Labath 
222b9739d40SPavel Labath       uint8_t nibble = xdigit_to_sint(m_packet[m_index]);
223b9739d40SPavel Labath       // Big Endian
224b9739d40SPavel Labath       result <<= 4;
225b9739d40SPavel Labath       result |= nibble;
226b9739d40SPavel Labath 
227b9739d40SPavel Labath       ++m_index;
228b9739d40SPavel Labath       ++nibble_count;
229b9739d40SPavel Labath     }
230b9739d40SPavel Labath   }
231b9739d40SPavel Labath   return result;
23230fdc8d8SChris Lattner }
23330fdc8d8SChris Lattner 
234*b9c1b51eSKate Stone uint64_t StringExtractor::GetHexMaxU64(bool little_endian,
235*b9c1b51eSKate Stone                                        uint64_t fail_value) {
236b9739d40SPavel Labath   uint64_t result = 0;
237b9739d40SPavel Labath   uint32_t nibble_count = 0;
238b9739d40SPavel Labath 
23915a2165dSFrancis Ricci   SkipSpaces();
240*b9c1b51eSKate Stone   if (little_endian) {
241b9739d40SPavel Labath     uint32_t shift_amount = 0;
242*b9c1b51eSKate Stone     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
243b9739d40SPavel Labath       // Make sure we don't exceed the size of a uint64_t...
244*b9c1b51eSKate Stone       if (nibble_count >= (sizeof(uint64_t) * 2)) {
245b9739d40SPavel Labath         m_index = UINT64_MAX;
246b9739d40SPavel Labath         return fail_value;
247b9739d40SPavel Labath       }
248b9739d40SPavel Labath 
249b9739d40SPavel Labath       uint8_t nibble_lo;
250b9739d40SPavel Labath       uint8_t nibble_hi = xdigit_to_sint(m_packet[m_index]);
251b9739d40SPavel Labath       ++m_index;
252*b9c1b51eSKate Stone       if (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
253b9739d40SPavel Labath         nibble_lo = xdigit_to_sint(m_packet[m_index]);
254b9739d40SPavel Labath         ++m_index;
255b9739d40SPavel Labath         result |= ((uint64_t)nibble_hi << (shift_amount + 4));
256b9739d40SPavel Labath         result |= ((uint64_t)nibble_lo << shift_amount);
257b9739d40SPavel Labath         nibble_count += 2;
258b9739d40SPavel Labath         shift_amount += 8;
259*b9c1b51eSKate Stone       } else {
260b9739d40SPavel Labath         result |= ((uint64_t)nibble_hi << shift_amount);
261b9739d40SPavel Labath         nibble_count += 1;
262b9739d40SPavel Labath         shift_amount += 4;
26330fdc8d8SChris Lattner       }
264b9739d40SPavel Labath     }
265*b9c1b51eSKate Stone   } else {
266*b9c1b51eSKate Stone     while (m_index < m_packet.size() && ::isxdigit(m_packet[m_index])) {
267b9739d40SPavel Labath       // Make sure we don't exceed the size of a uint64_t...
268*b9c1b51eSKate Stone       if (nibble_count >= (sizeof(uint64_t) * 2)) {
269b9739d40SPavel Labath         m_index = UINT64_MAX;
270b9739d40SPavel Labath         return fail_value;
271b9739d40SPavel Labath       }
272b9739d40SPavel Labath 
273b9739d40SPavel Labath       uint8_t nibble = xdigit_to_sint(m_packet[m_index]);
274b9739d40SPavel Labath       // Big Endian
275b9739d40SPavel Labath       result <<= 4;
276b9739d40SPavel Labath       result |= nibble;
277b9739d40SPavel Labath 
278b9739d40SPavel Labath       ++m_index;
279b9739d40SPavel Labath       ++nibble_count;
280b9739d40SPavel Labath     }
281b9739d40SPavel Labath   }
282b9739d40SPavel Labath   return result;
28330fdc8d8SChris Lattner }
28430fdc8d8SChris Lattner 
285*b9c1b51eSKate Stone size_t StringExtractor::GetHexBytes(llvm::MutableArrayRef<uint8_t> dest,
286*b9c1b51eSKate Stone                                     uint8_t fail_fill_value) {
28730fdc8d8SChris Lattner   size_t bytes_extracted = 0;
288*b9c1b51eSKate Stone   while (!dest.empty() && GetBytesLeft() > 0) {
289d08f09c1SZachary Turner     dest[0] = GetHexU8(fail_fill_value);
290d08f09c1SZachary Turner     if (!IsGood())
29130fdc8d8SChris Lattner       break;
292d08f09c1SZachary Turner     ++bytes_extracted;
293d08f09c1SZachary Turner     dest = dest.drop_front();
29430fdc8d8SChris Lattner   }
29530fdc8d8SChris Lattner 
296d08f09c1SZachary Turner   if (!dest.empty())
297d08f09c1SZachary Turner     ::memset(dest.data(), fail_fill_value, dest.size());
29830fdc8d8SChris Lattner 
29930fdc8d8SChris Lattner   return bytes_extracted;
30030fdc8d8SChris Lattner }
30130fdc8d8SChris Lattner 
3026eddf8dfSVince Harron //----------------------------------------------------------------------
3036eddf8dfSVince Harron // Decodes all valid hex encoded bytes at the head of the
3046eddf8dfSVince Harron // StringExtractor, limited by dst_len.
3056eddf8dfSVince Harron //
3066eddf8dfSVince Harron // Returns the number of bytes successfully decoded
3076eddf8dfSVince Harron //----------------------------------------------------------------------
308*b9c1b51eSKate Stone size_t StringExtractor::GetHexBytesAvail(llvm::MutableArrayRef<uint8_t> dest) {
3096eddf8dfSVince Harron   size_t bytes_extracted = 0;
310*b9c1b51eSKate Stone   while (!dest.empty()) {
3116eddf8dfSVince Harron     int decode = DecodeHexU8();
3126eddf8dfSVince Harron     if (decode == -1)
3136eddf8dfSVince Harron       break;
314d08f09c1SZachary Turner     dest[0] = (uint8_t)decode;
315d08f09c1SZachary Turner     dest = dest.drop_front();
316d08f09c1SZachary Turner     ++bytes_extracted;
3176eddf8dfSVince Harron   }
3186eddf8dfSVince Harron   return bytes_extracted;
3196eddf8dfSVince Harron }
32030fdc8d8SChris Lattner 
321b9739d40SPavel Labath // Consume ASCII hex nibble character pairs until we have decoded byte_size
322b9739d40SPavel Labath // bytes of data.
323b9739d40SPavel Labath 
324*b9c1b51eSKate Stone uint64_t StringExtractor::GetHexWithFixedSize(uint32_t byte_size,
325*b9c1b51eSKate Stone                                               bool little_endian,
326*b9c1b51eSKate Stone                                               uint64_t fail_value) {
327*b9c1b51eSKate Stone   if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2) {
328b9739d40SPavel Labath     uint64_t result = 0;
329b9739d40SPavel Labath     uint32_t i;
330*b9c1b51eSKate Stone     if (little_endian) {
331b9739d40SPavel Labath       // Little Endian
332b9739d40SPavel Labath       uint32_t shift_amount;
333*b9c1b51eSKate Stone       for (i = 0, shift_amount = 0; i < byte_size && IsGood();
334*b9c1b51eSKate Stone            ++i, shift_amount += 8) {
335b9739d40SPavel Labath         result |= ((uint64_t)GetHexU8() << shift_amount);
336b9739d40SPavel Labath       }
337*b9c1b51eSKate Stone     } else {
338b9739d40SPavel Labath       // Big Endian
339*b9c1b51eSKate Stone       for (i = 0; i < byte_size && IsGood(); ++i) {
340b9739d40SPavel Labath         result <<= 8;
341b9739d40SPavel Labath         result |= GetHexU8();
342b9739d40SPavel Labath       }
343b9739d40SPavel Labath     }
344b9739d40SPavel Labath   }
345b9739d40SPavel Labath   m_index = UINT64_MAX;
346b9739d40SPavel Labath   return fail_value;
347b9739d40SPavel Labath }
348b9739d40SPavel Labath 
349*b9c1b51eSKate Stone size_t StringExtractor::GetHexByteString(std::string &str) {
350de9d0494SGreg Clayton   str.clear();
3518c1b6bd7SPavel Labath   str.reserve(GetBytesLeft() / 2);
352de9d0494SGreg Clayton   char ch;
353de9d0494SGreg Clayton   while ((ch = GetHexU8()) != '\0')
354de9d0494SGreg Clayton     str.append(1, ch);
355de9d0494SGreg Clayton   return str.size();
356de9d0494SGreg Clayton }
357de9d0494SGreg Clayton 
358*b9c1b51eSKate Stone size_t StringExtractor::GetHexByteStringFixedLength(std::string &str,
359*b9c1b51eSKate Stone                                                     uint32_t nibble_length) {
360af245d11STodd Fiala   str.clear();
361b9739d40SPavel Labath 
362b9739d40SPavel Labath   uint32_t nibble_count = 0;
363*b9c1b51eSKate Stone   for (const char *pch = Peek();
364*b9c1b51eSKate Stone        (nibble_count < nibble_length) && (pch != nullptr);
365*b9c1b51eSKate Stone        str.append(1, GetHexU8(0, false)), pch = Peek(), nibble_count += 2) {
366*b9c1b51eSKate Stone   }
367b9739d40SPavel Labath 
368af245d11STodd Fiala   return str.size();
369af245d11STodd Fiala }
370af245d11STodd Fiala 
371*b9c1b51eSKate Stone size_t StringExtractor::GetHexByteStringTerminatedBy(std::string &str,
372*b9c1b51eSKate Stone                                                      char terminator) {
373e0f8f574SDaniel Malea   str.clear();
374e0f8f574SDaniel Malea   char ch;
375e0f8f574SDaniel Malea   while ((ch = GetHexU8(0, false)) != '\0')
376e0f8f574SDaniel Malea     str.append(1, ch);
377b9739d40SPavel Labath   if (Peek() && *Peek() == terminator)
378e0f8f574SDaniel Malea     return str.size();
379af245d11STodd Fiala 
380e0f8f574SDaniel Malea   str.clear();
381e0f8f574SDaniel Malea   return str.size();
382e0f8f574SDaniel Malea }
383e0f8f574SDaniel Malea 
384*b9c1b51eSKate Stone bool StringExtractor::GetNameColonValue(llvm::StringRef &name,
385*b9c1b51eSKate Stone                                         llvm::StringRef &value) {
38630fdc8d8SChris Lattner   // Read something in the form of NNNN:VVVV; where NNNN is any character
38730fdc8d8SChris Lattner   // that is not a colon, followed by a ':' character, then a value (one or
38830fdc8d8SChris Lattner   // more ';' chars), followed by a ';'
38954695a33SZachary Turner   if (m_index >= m_packet.size())
39054695a33SZachary Turner     return fail();
39154695a33SZachary Turner 
39254695a33SZachary Turner   llvm::StringRef view(m_packet);
39354695a33SZachary Turner   if (view.empty())
39454695a33SZachary Turner     return fail();
39554695a33SZachary Turner 
39654695a33SZachary Turner   llvm::StringRef a, b, c, d;
39754695a33SZachary Turner   view = view.substr(m_index);
39854695a33SZachary Turner   std::tie(a, b) = view.split(':');
39954695a33SZachary Turner   if (a.empty() || b.empty())
40054695a33SZachary Turner     return fail();
40154695a33SZachary Turner   std::tie(c, d) = b.split(';');
40254695a33SZachary Turner   if (b == c && d.empty())
40354695a33SZachary Turner     return fail();
40454695a33SZachary Turner 
40554695a33SZachary Turner   name = a;
40654695a33SZachary Turner   value = c;
40754695a33SZachary Turner   if (d.empty())
40854695a33SZachary Turner     m_index = m_packet.size();
409*b9c1b51eSKate Stone   else {
41054695a33SZachary Turner     size_t bytes_consumed = d.data() - view.data();
41154695a33SZachary Turner     m_index += bytes_consumed;
41254695a33SZachary Turner   }
41330fdc8d8SChris Lattner   return true;
41430fdc8d8SChris Lattner }
41598424c44SGreg Clayton 
416*b9c1b51eSKate Stone void StringExtractor::SkipSpaces() {
41798424c44SGreg Clayton   const size_t n = m_packet.size();
41898424c44SGreg Clayton   while (m_index < n && isspace(m_packet[m_index]))
41998424c44SGreg Clayton     ++m_index;
42098424c44SGreg Clayton }
421