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