Yes, there was a thread on lldb dev about it.  After i get all the changes in to the newer one we can move the old one out<br><div class="gmail_quote"><div dir="ltr">On Tue, Aug 30, 2016 at 6:32 AM Pavel Labath <<a href="mailto:labath@google.com">labath@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I think we should move the new file away from source/Utility. If it's<br>
supposed to be used by debugserver only, we probably should move it to<br>
tools/debugserver/source ? Right now, debugservers cmake file contains<br>
a hack to be able to include these, so by doing that we will remove<br>
that as well.<br>
<br>
Thoughts ?<br>
<br>
pl<br>
<br>
PS: judging by the CMakeLists.txt, the other file which is included in<br>
such a funny way is source/Host/common/StringConvert.cpp<br>
<br>
<br>
On 29 August 2016 at 20:46, Zachary Turner via lldb-commits<br>
<<a href="mailto:lldb-commits@lists.llvm.org" target="_blank">lldb-commits@lists.llvm.org</a>> wrote:<br>
> Author: zturner<br>
> Date: Mon Aug 29 14:45:59 2016<br>
> New Revision: 279997<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=279997&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=279997&view=rev</a><br>
> Log:<br>
> Copy StringExtractor to StdStringExtractor.<br>
><br>
> I have some improvements to make to StringExtractor that require<br>
> using LLVM.  debugserver can't take a dependency on LLVM but uses<br>
> this file, so I'm forking it off into StdStringExtractor and<br>
> StringExtractor, so that StringExtractor can take advantage of<br>
> some performance improvements and readability improvements that<br>
> LLVM can provide.<br>
><br>
> Added:<br>
>     lldb/trunk/include/lldb/Utility/StdStringExtractor.h<br>
>     lldb/trunk/source/Utility/StdStringExtractor.cpp<br>
> Modified:<br>
>     lldb/trunk/source/Utility/CMakeLists.txt<br>
>     lldb/trunk/tools/debugserver/source/JSON.cpp<br>
>     lldb/trunk/tools/debugserver/source/JSON.h<br>
>     lldb/trunk/tools/debugserver/source/RNBRemote.cpp<br>
><br>
> Added: lldb/trunk/include/lldb/Utility/StdStringExtractor.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/StdStringExtractor.h?rev=279997&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/StdStringExtractor.h?rev=279997&view=auto</a><br>
> ==============================================================================<br>
> --- lldb/trunk/include/lldb/Utility/StdStringExtractor.h (added)<br>
> +++ lldb/trunk/include/lldb/Utility/StdStringExtractor.h Mon Aug 29 14:45:59 2016<br>
> @@ -0,0 +1,181 @@<br>
> +//===-- StdStringExtractor.h ------------------------------------*- C++ -*-===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef utility_StdStringExtractor_h_<br>
> +#define utility_StdStringExtractor_h_<br>
> +<br>
> +// C Includes<br>
> +// C++ Includes<br>
> +#include <string><br>
> +#include <stdint.h><br>
> +<br>
> +// Other libraries and framework includes<br>
> +// Project includes<br>
> +<br>
> +// Based on StringExtractor, with the added limitation that this file should not<br>
> +// take a dependency on LLVM, as it is used from debugserver.<br>
> +class StdStringExtractor<br>
> +{<br>
> +public:<br>
> +<br>
> +    enum {<br>
> +        BigEndian = 0,<br>
> +        LittleEndian = 1<br>
> +    };<br>
> +    //------------------------------------------------------------------<br>
> +    // Constructors and Destructors<br>
> +    //------------------------------------------------------------------<br>
> +    StdStringExtractor();<br>
> +    StdStringExtractor(const char *packet_cstr);<br>
> +    StdStringExtractor(const StdStringExtractor& rhs);<br>
> +    virtual ~StdStringExtractor();<br>
> +<br>
> +    //------------------------------------------------------------------<br>
> +    // Operators<br>
> +    //------------------------------------------------------------------<br>
> +    const StdStringExtractor&<br>
> +    operator=(const StdStringExtractor& rhs);<br>
> +<br>
> +    // Returns true if the file position is still valid for the data<br>
> +    // contained in this string extractor object.<br>
> +    bool<br>
> +    IsGood() const<br>
> +    {<br>
> +        return m_index != UINT64_MAX;<br>
> +    }<br>
> +<br>
> +    uint64_t<br>
> +    GetFilePos () const<br>
> +    {<br>
> +        return m_index;<br>
> +    }<br>
> +<br>
> +    void<br>
> +    SetFilePos (uint32_t idx)<br>
> +    {<br>
> +        m_index = idx;<br>
> +    }<br>
> +<br>
> +    void<br>
> +    Clear ()<br>
> +    {<br>
> +        m_packet.clear();<br>
> +        m_index = 0;<br>
> +    }<br>
> +<br>
> +    void<br>
> +    SkipSpaces ();<br>
> +<br>
> +    std::string &<br>
> +    GetStringRef ()<br>
> +    {<br>
> +        return m_packet;<br>
> +    }<br>
> +<br>
> +    const std::string &<br>
> +    GetStringRef () const<br>
> +    {<br>
> +        return m_packet;<br>
> +    }<br>
> +<br>
> +    bool<br>
> +    Empty()<br>
> +    {<br>
> +        return m_packet.empty();<br>
> +    }<br>
> +<br>
> +    size_t<br>
> +    GetBytesLeft ()<br>
> +    {<br>
> +        if (m_index < m_packet.size())<br>
> +            return m_packet.size() - m_index;<br>
> +        return 0;<br>
> +    }<br>
> +<br>
> +    char<br>
> +    GetChar (char fail_value = '\0');<br>
> +<br>
> +    char<br>
> +    PeekChar (char fail_value = '\0')<br>
> +    {<br>
> +        const char *cstr = Peek();<br>
> +        if (cstr)<br>
> +            return cstr[0];<br>
> +        return fail_value;<br>
> +    }<br>
> +<br>
> +    int<br>
> +    DecodeHexU8();<br>
> +<br>
> +    uint8_t<br>
> +    GetHexU8 (uint8_t fail_value = 0, bool set_eof_on_fail = true);<br>
> +<br>
> +    bool<br>
> +    GetHexU8Ex (uint8_t& ch, bool set_eof_on_fail = true);<br>
> +<br>
> +    bool<br>
> +    GetNameColonValue (std::string &name, std::string &value);<br>
> +<br>
> +    int32_t<br>
> +    GetS32 (int32_t fail_value, int base = 0);<br>
> +<br>
> +    uint32_t<br>
> +    GetU32 (uint32_t fail_value, int base = 0);<br>
> +<br>
> +    int64_t<br>
> +    GetS64 (int64_t fail_value, int base = 0);<br>
> +<br>
> +    uint64_t<br>
> +    GetU64 (uint64_t fail_value, int base = 0);<br>
> +<br>
> +    uint32_t<br>
> +    GetHexMaxU32 (bool little_endian, uint32_t fail_value);<br>
> +<br>
> +    uint64_t<br>
> +    GetHexMaxU64 (bool little_endian, uint64_t fail_value);<br>
> +<br>
> +    size_t<br>
> +    GetHexBytes (void *dst, size_t dst_len, uint8_t fail_fill_value);<br>
> +<br>
> +    size_t<br>
> +    GetHexBytesAvail (void *dst, size_t dst_len);<br>
> +<br>
> +    uint64_t<br>
> +    GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value);<br>
> +<br>
> +    size_t<br>
> +    GetHexByteString (std::string &str);<br>
> +<br>
> +    size_t<br>
> +    GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length);<br>
> +<br>
> +    size_t<br>
> +    GetHexByteStringTerminatedBy (std::string &str,<br>
> +                                  char terminator);<br>
> +<br>
> +    const char *<br>
> +    Peek ()<br>
> +    {<br>
> +        if (m_index < m_packet.size())<br>
> +            return m_packet.c_str() + m_index;<br>
> +        return nullptr;<br>
> +    }<br>
> +<br>
> +protected:<br>
> +    //------------------------------------------------------------------<br>
> +    // For StdStringExtractor only<br>
> +    //------------------------------------------------------------------<br>
> +    std::string m_packet;   // The string in which to extract data.<br>
> +    uint64_t m_index;       // When extracting data from a packet, this index<br>
> +                            // will march along as things get extracted. If set<br>
> +                            // to UINT64_MAX the end of the packet data was<br>
> +                            // reached when decoding information<br>
> +};<br>
> +<br>
> +#endif  // utility_StringExtractor_h_<br>
><br>
> Modified: lldb/trunk/source/Utility/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/CMakeLists.txt?rev=279997&r1=279996&r2=279997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/CMakeLists.txt?rev=279997&r1=279996&r2=279997&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Utility/CMakeLists.txt (original)<br>
> +++ lldb/trunk/source/Utility/CMakeLists.txt Mon Aug 29 14:45:59 2016<br>
> @@ -12,6 +12,7 @@ add_lldb_library(lldbUtility<br>
>    RegisterNumber.cpp<br>
>    SelectHelper.cpp<br>
>    SharingPtr.cpp<br>
> +  StdStringExtractor.cpp<br>
>    StringExtractor.cpp<br>
>    StringExtractorGDBRemote.cpp<br>
>    StringLexer.cpp<br>
><br>
> Added: lldb/trunk/source/Utility/StdStringExtractor.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StdStringExtractor.cpp?rev=279997&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StdStringExtractor.cpp?rev=279997&view=auto</a><br>
> ==============================================================================<br>
> --- lldb/trunk/source/Utility/StdStringExtractor.cpp (added)<br>
> +++ lldb/trunk/source/Utility/StdStringExtractor.cpp Mon Aug 29 14:45:59 2016<br>
> @@ -0,0 +1,502 @@<br>
> +//===-- StdStringExtractor.cpp ----------------------------------*- C++ -*-===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#include "lldb/Utility/StdStringExtractor.h"<br>
> +<br>
> +// C Includes<br>
> +#include <stdlib.h><br>
> +<br>
> +// C++ Includes<br>
> +// Other libraries and framework includes<br>
> +// Project includes<br>
> +<br>
> +static inline int<br>
> +xdigit_to_sint (char ch)<br>
> +{<br>
> +    if (ch >= 'a' && ch <= 'f')<br>
> +        return 10 + ch - 'a';<br>
> +    if (ch >= 'A' && ch <= 'F')<br>
> +        return 10 + ch - 'A';<br>
> +    if (ch >= '0' && ch <= '9')<br>
> +        return ch - '0';<br>
> +    return -1;<br>
> +}<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// StdStringExtractor constructor<br>
> +//----------------------------------------------------------------------<br>
> +StdStringExtractor::StdStringExtractor() :<br>
> +    m_packet(),<br>
> +    m_index (0)<br>
> +{<br>
> +}<br>
> +<br>
> +<br>
> +StdStringExtractor::StdStringExtractor(const char *packet_cstr) :<br>
> +    m_packet(),<br>
> +    m_index (0)<br>
> +{<br>
> +    if (packet_cstr)<br>
> +        m_packet.assign (packet_cstr);<br>
> +}<br>
> +<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// StdStringExtractor copy constructor<br>
> +//----------------------------------------------------------------------<br>
> +StdStringExtractor::StdStringExtractor(const StdStringExtractor& rhs) :<br>
> +    m_packet (rhs.m_packet),<br>
> +    m_index (rhs.m_index)<br>
> +{<br>
> +<br>
> +}<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// StdStringExtractor assignment operator<br>
> +//----------------------------------------------------------------------<br>
> +const StdStringExtractor&<br>
> +StdStringExtractor::operator=(const StdStringExtractor& rhs)<br>
> +{<br>
> +    if (this != &rhs)<br>
> +    {<br>
> +        m_packet = rhs.m_packet;<br>
> +        m_index = rhs.m_index;<br>
> +<br>
> +    }<br>
> +    return *this;<br>
> +}<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// Destructor<br>
> +//----------------------------------------------------------------------<br>
> +StdStringExtractor::~StdStringExtractor()<br>
> +{<br>
> +}<br>
> +<br>
> +<br>
> +char<br>
> +StdStringExtractor::GetChar (char fail_value)<br>
> +{<br>
> +    if (m_index < m_packet.size())<br>
> +    {<br>
> +        char ch = m_packet[m_index];<br>
> +        ++m_index;<br>
> +        return ch;<br>
> +    }<br>
> +    m_index = UINT64_MAX;<br>
> +    return fail_value;<br>
> +}<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// If a pair of valid hex digits exist at the head of the<br>
> +// StdStringExtractor they are decoded into an unsigned byte and returned<br>
> +// by this function<br>
> +//<br>
> +// If there is not a pair of valid hex digits at the head of the<br>
> +// StdStringExtractor, it is left unchanged and -1 is returned<br>
> +//----------------------------------------------------------------------<br>
> +int<br>
> +StdStringExtractor::DecodeHexU8()<br>
> +{<br>
> +    SkipSpaces();<br>
> +    if (GetBytesLeft() < 2)<br>
> +    {<br>
> +        return -1;<br>
> +    }<br>
> +    const int hi_nibble = xdigit_to_sint(m_packet[m_index]);<br>
> +    const int lo_nibble = xdigit_to_sint(m_packet[m_index+1]);<br>
> +    if (hi_nibble == -1 || lo_nibble == -1)<br>
> +    {<br>
> +        return -1;<br>
> +    }<br>
> +    m_index += 2;<br>
> +    return (uint8_t)((hi_nibble << 4) + lo_nibble);<br>
> +}<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// Extract an unsigned character from two hex ASCII chars in the packet<br>
> +// string, or return fail_value on failure<br>
> +//----------------------------------------------------------------------<br>
> +uint8_t<br>
> +StdStringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail)<br>
> +{<br>
> +    // On success, fail_value will be overwritten with the next<br>
> +    // character in the stream<br>
> +    GetHexU8Ex(fail_value, set_eof_on_fail);<br>
> +    return fail_value;<br>
> +}<br>
> +<br>
> +bool<br>
> +StdStringExtractor::GetHexU8Ex (uint8_t& ch, bool set_eof_on_fail)<br>
> +{<br>
> +    int byte = DecodeHexU8();<br>
> +    if (byte == -1)<br>
> +    {<br>
> +        if (set_eof_on_fail || m_index >= m_packet.size())<br>
> +            m_index = UINT64_MAX;<br>
> +        // ch should not be changed in case of failure<br>
> +        return false;<br>
> +    }<br>
> +    ch = (uint8_t)byte;<br>
> +    return true;<br>
> +}<br>
> +<br>
> +uint32_t<br>
> +StdStringExtractor::GetU32 (uint32_t fail_value, int base)<br>
> +{<br>
> +    if (m_index < m_packet.size())<br>
> +    {<br>
> +        char *end = nullptr;<br>
> +        const char *start = m_packet.c_str();<br>
> +        const char *cstr = start + m_index;<br>
> +        uint32_t result = static_cast<uint32_t>(::strtoul (cstr, &end, base));<br>
> +<br>
> +        if (end && end != cstr)<br>
> +        {<br>
> +            m_index = end - start;<br>
> +            return result;<br>
> +        }<br>
> +    }<br>
> +    return fail_value;<br>
> +}<br>
> +<br>
> +int32_t<br>
> +StdStringExtractor::GetS32 (int32_t fail_value, int base)<br>
> +{<br>
> +    if (m_index < m_packet.size())<br>
> +    {<br>
> +        char *end = nullptr;<br>
> +        const char *start = m_packet.c_str();<br>
> +        const char *cstr = start + m_index;<br>
> +        int32_t result = static_cast<int32_t>(::strtol (cstr, &end, base));<br>
> +<br>
> +        if (end && end != cstr)<br>
> +        {<br>
> +            m_index = end - start;<br>
> +            return result;<br>
> +        }<br>
> +    }<br>
> +    return fail_value;<br>
> +}<br>
> +<br>
> +<br>
> +uint64_t<br>
> +StdStringExtractor::GetU64 (uint64_t fail_value, int base)<br>
> +{<br>
> +    if (m_index < m_packet.size())<br>
> +    {<br>
> +        char *end = nullptr;<br>
> +        const char *start = m_packet.c_str();<br>
> +        const char *cstr = start + m_index;<br>
> +        uint64_t result = ::strtoull (cstr, &end, base);<br>
> +<br>
> +        if (end && end != cstr)<br>
> +        {<br>
> +            m_index = end - start;<br>
> +            return result;<br>
> +        }<br>
> +    }<br>
> +    return fail_value;<br>
> +}<br>
> +<br>
> +int64_t<br>
> +StdStringExtractor::GetS64 (int64_t fail_value, int base)<br>
> +{<br>
> +    if (m_index < m_packet.size())<br>
> +    {<br>
> +        char *end = nullptr;<br>
> +        const char *start = m_packet.c_str();<br>
> +        const char *cstr = start + m_index;<br>
> +        int64_t result = ::strtoll (cstr, &end, base);<br>
> +<br>
> +        if (end && end != cstr)<br>
> +        {<br>
> +            m_index = end - start;<br>
> +            return result;<br>
> +        }<br>
> +    }<br>
> +    return fail_value;<br>
> +}<br>
> +<br>
> +<br>
> +uint32_t<br>
> +StdStringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)<br>
> +{<br>
> +    uint32_t result = 0;<br>
> +    uint32_t nibble_count = 0;<br>
> +<br>
> +    SkipSpaces();<br>
> +    if (little_endian)<br>
> +    {<br>
> +        uint32_t shift_amount = 0;<br>
> +        while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))<br>
> +        {<br>
> +            // Make sure we don't exceed the size of a uint32_t...<br>
> +            if (nibble_count >= (sizeof(uint32_t) * 2))<br>
> +            {<br>
> +                m_index = UINT64_MAX;<br>
> +                return fail_value;<br>
> +            }<br>
> +<br>
> +            uint8_t nibble_lo;<br>
> +            uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);<br>
> +            ++m_index;<br>
> +            if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))<br>
> +            {<br>
> +                nibble_lo = xdigit_to_sint (m_packet[m_index]);<br>
> +                ++m_index;<br>
> +                result |= ((uint32_t)nibble_hi << (shift_amount + 4));<br>
> +                result |= ((uint32_t)nibble_lo << shift_amount);<br>
> +                nibble_count += 2;<br>
> +                shift_amount += 8;<br>
> +            }<br>
> +            else<br>
> +            {<br>
> +                result |= ((uint32_t)nibble_hi << shift_amount);<br>
> +                nibble_count += 1;<br>
> +                shift_amount += 4;<br>
> +            }<br>
> +<br>
> +        }<br>
> +    }<br>
> +    else<br>
> +    {<br>
> +        while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))<br>
> +        {<br>
> +            // Make sure we don't exceed the size of a uint32_t...<br>
> +            if (nibble_count >= (sizeof(uint32_t) * 2))<br>
> +            {<br>
> +                m_index = UINT64_MAX;<br>
> +                return fail_value;<br>
> +            }<br>
> +<br>
> +            uint8_t nibble = xdigit_to_sint (m_packet[m_index]);<br>
> +            // Big Endian<br>
> +            result <<= 4;<br>
> +            result |= nibble;<br>
> +<br>
> +            ++m_index;<br>
> +            ++nibble_count;<br>
> +        }<br>
> +    }<br>
> +    return result;<br>
> +}<br>
> +<br>
> +uint64_t<br>
> +StdStringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)<br>
> +{<br>
> +    uint64_t result = 0;<br>
> +    uint32_t nibble_count = 0;<br>
> +<br>
> +    SkipSpaces();<br>
> +    if (little_endian)<br>
> +    {<br>
> +        uint32_t shift_amount = 0;<br>
> +        while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))<br>
> +        {<br>
> +            // Make sure we don't exceed the size of a uint64_t...<br>
> +            if (nibble_count >= (sizeof(uint64_t) * 2))<br>
> +            {<br>
> +                m_index = UINT64_MAX;<br>
> +                return fail_value;<br>
> +            }<br>
> +<br>
> +            uint8_t nibble_lo;<br>
> +            uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);<br>
> +            ++m_index;<br>
> +            if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))<br>
> +            {<br>
> +                nibble_lo = xdigit_to_sint (m_packet[m_index]);<br>
> +                ++m_index;<br>
> +                result |= ((uint64_t)nibble_hi << (shift_amount + 4));<br>
> +                result |= ((uint64_t)nibble_lo << shift_amount);<br>
> +                nibble_count += 2;<br>
> +                shift_amount += 8;<br>
> +            }<br>
> +            else<br>
> +            {<br>
> +                result |= ((uint64_t)nibble_hi << shift_amount);<br>
> +                nibble_count += 1;<br>
> +                shift_amount += 4;<br>
> +            }<br>
> +<br>
> +        }<br>
> +    }<br>
> +    else<br>
> +    {<br>
> +        while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))<br>
> +        {<br>
> +            // Make sure we don't exceed the size of a uint64_t...<br>
> +            if (nibble_count >= (sizeof(uint64_t) * 2))<br>
> +            {<br>
> +                m_index = UINT64_MAX;<br>
> +                return fail_value;<br>
> +            }<br>
> +<br>
> +            uint8_t nibble = xdigit_to_sint (m_packet[m_index]);<br>
> +            // Big Endian<br>
> +            result <<= 4;<br>
> +            result |= nibble;<br>
> +<br>
> +            ++m_index;<br>
> +            ++nibble_count;<br>
> +        }<br>
> +    }<br>
> +    return result;<br>
> +}<br>
> +<br>
> +size_t<br>
> +StdStringExtractor::GetHexBytes (void *dst_void, size_t dst_len, uint8_t fail_fill_value)<br>
> +{<br>
> +    uint8_t *dst = (uint8_t*)dst_void;<br>
> +    size_t bytes_extracted = 0;<br>
> +    while (bytes_extracted < dst_len && GetBytesLeft ())<br>
> +    {<br>
> +        dst[bytes_extracted] = GetHexU8 (fail_fill_value);<br>
> +        if (IsGood())<br>
> +            ++bytes_extracted;<br>
> +        else<br>
> +            break;<br>
> +    }<br>
> +<br>
> +    for (size_t i = bytes_extracted; i < dst_len; ++i)<br>
> +        dst[i] = fail_fill_value;<br>
> +<br>
> +    return bytes_extracted;<br>
> +}<br>
> +<br>
> +//----------------------------------------------------------------------<br>
> +// Decodes all valid hex encoded bytes at the head of the<br>
> +// StdStringExtractor, limited by dst_len.<br>
> +//<br>
> +// Returns the number of bytes successfully decoded<br>
> +//----------------------------------------------------------------------<br>
> +size_t<br>
> +StdStringExtractor::GetHexBytesAvail (void *dst_void, size_t dst_len)<br>
> +{<br>
> +    uint8_t *dst = (uint8_t*)dst_void;<br>
> +    size_t bytes_extracted = 0;<br>
> +    while (bytes_extracted < dst_len)<br>
> +    {<br>
> +        int decode = DecodeHexU8();<br>
> +        if (decode == -1)<br>
> +        {<br>
> +            break;<br>
> +        }<br>
> +        dst[bytes_extracted++] = (uint8_t)decode;<br>
> +    }<br>
> +    return bytes_extracted;<br>
> +}<br>
> +<br>
> +// Consume ASCII hex nibble character pairs until we have decoded byte_size<br>
> +// bytes of data.<br>
> +<br>
> +uint64_t<br>
> +StdStringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value)<br>
> +{<br>
> +    if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2)<br>
> +    {<br>
> +        uint64_t result = 0;<br>
> +        uint32_t i;<br>
> +        if (little_endian)<br>
> +        {<br>
> +            // Little Endian<br>
> +            uint32_t shift_amount;<br>
> +            for (i = 0, shift_amount = 0;<br>
> +                 i < byte_size && IsGood();<br>
> +                 ++i, shift_amount += 8)<br>
> +            {<br>
> +                result |= ((uint64_t)GetHexU8() << shift_amount);<br>
> +            }<br>
> +        }<br>
> +        else<br>
> +        {<br>
> +            // Big Endian<br>
> +            for (i = 0; i < byte_size && IsGood(); ++i)<br>
> +            {<br>
> +                result <<= 8;<br>
> +                result |= GetHexU8();<br>
> +            }<br>
> +        }<br>
> +    }<br>
> +    m_index = UINT64_MAX;<br>
> +    return fail_value;<br>
> +}<br>
> +<br>
> +size_t<br>
> +StdStringExtractor::GetHexByteString (std::string &str)<br>
> +{<br>
> +    str.clear();<br>
> +    str.reserve(GetBytesLeft() / 2);<br>
> +    char ch;<br>
> +    while ((ch = GetHexU8()) != '\0')<br>
> +        str.append(1, ch);<br>
> +    return str.size();<br>
> +}<br>
> +<br>
> +size_t<br>
> +StdStringExtractor::GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length)<br>
> +{<br>
> +    str.clear();<br>
> +<br>
> +    uint32_t nibble_count = 0;<br>
> +    for (const char *pch = Peek(); (nibble_count < nibble_length) && (pch != nullptr); str.append(1, GetHexU8(0, false)), pch = Peek (), nibble_count += 2)<br>
> +    {}<br>
> +<br>
> +    return str.size();<br>
> +}<br>
> +<br>
> +size_t<br>
> +StdStringExtractor::GetHexByteStringTerminatedBy (std::string &str,<br>
> +                                               char terminator)<br>
> +{<br>
> +    str.clear();<br>
> +    char ch;<br>
> +    while ((ch = GetHexU8(0,false)) != '\0')<br>
> +        str.append(1, ch);<br>
> +    if (Peek() && *Peek() == terminator)<br>
> +        return str.size();<br>
> +<br>
> +    str.clear();<br>
> +    return str.size();<br>
> +}<br>
> +<br>
> +bool<br>
> +StdStringExtractor::GetNameColonValue (std::string &name, std::string &value)<br>
> +{<br>
> +    // Read something in the form of NNNN:VVVV; where NNNN is any character<br>
> +    // that is not a colon, followed by a ':' character, then a value (one or<br>
> +    // more ';' chars), followed by a ';'<br>
> +    if (m_index < m_packet.size())<br>
> +    {<br>
> +        const size_t colon_idx = m_packet.find (':', m_index);<br>
> +        if (colon_idx != std::string::npos)<br>
> +        {<br>
> +            const size_t semicolon_idx = m_packet.find (';', colon_idx);<br>
> +            if (semicolon_idx != std::string::npos)<br>
> +            {<br>
> +                name.assign (m_packet, m_index, colon_idx - m_index);<br>
> +                value.assign (m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1));<br>
> +                m_index = semicolon_idx + 1;<br>
> +                return true;<br>
> +            }<br>
> +        }<br>
> +    }<br>
> +    m_index = UINT64_MAX;<br>
> +    return false;<br>
> +}<br>
> +<br>
> +void<br>
> +StdStringExtractor::SkipSpaces ()<br>
> +{<br>
> +    const size_t n = m_packet.size();<br>
> +    while (m_index < n && isspace(m_packet[m_index]))<br>
> +        ++m_index;<br>
> +}<br>
> +<br>
><br>
> Modified: lldb/trunk/tools/debugserver/source/JSON.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/JSON.cpp?rev=279997&r1=279996&r2=279997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/JSON.cpp?rev=279997&r1=279996&r2=279997&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/tools/debugserver/source/JSON.cpp (original)<br>
> +++ lldb/trunk/tools/debugserver/source/JSON.cpp Mon Aug 29 14:45:59 2016<br>
> @@ -319,7 +319,7 @@ JSONArray::GetNumElements ()<br>
><br>
><br>
>  JSONParser::JSONParser (const char *cstr) :<br>
> -    StringExtractor(cstr)<br>
> +    StdStringExtractor(cstr)<br>
>  {<br>
>  }<br>
><br>
><br>
> Modified: lldb/trunk/tools/debugserver/source/JSON.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/JSON.h?rev=279997&r1=279996&r2=279997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/JSON.h?rev=279997&r1=279996&r2=279997&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/tools/debugserver/source/JSON.h (original)<br>
> +++ lldb/trunk/tools/debugserver/source/JSON.h Mon Aug 29 14:45:59 2016<br>
> @@ -10,9 +10,9 @@<br>
>  #ifndef utility_JSON_h_<br>
>  #define utility_JSON_h_<br>
><br>
> -// This cross-project usage is fine as StringExtractor.h is entirely<br>
> +// This cross-project usage is fine as StdStringExtractor.h is entirely<br>
>  // self-contained.<br>
> -#include "lldb/Utility/StringExtractor.h"<br>
> +#include "lldb/Utility/StdStringExtractor.h"<br>
><br>
>  // C includes<br>
>  #include <inttypes.h><br>
> @@ -338,7 +338,7 @@ public:<br>
>      Vector m_elements;<br>
>  };<br>
><br>
> -class JSONParser : public StringExtractor<br>
> +class JSONParser : public StdStringExtractor<br>
>  {<br>
>  public:<br>
>      enum Token<br>
><br>
> Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=279997&r1=279996&r2=279997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=279997&r1=279996&r2=279997&view=diff</a><br>
> ==============================================================================<br>
> --- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)<br>
> +++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Mon Aug 29 14:45:59 2016<br>
> @@ -38,7 +38,7 @@<br>
>  #include "RNBServices.h"<br>
>  #include "RNBSocket.h"<br>
>  #include "JSON.h"<br>
> -#include "lldb/Utility/StringExtractor.h"<br>
> +#include "lldb/Utility/StdStringExtractor.h"<br>
>  #include "MacOSX/Genealogy.h"<br>
>  #include "JSONGenerator.h"<br>
><br>
> @@ -2329,7 +2329,7 @@ RNBRemote::HandlePacket_QSetSTDIO (const<br>
>          // QSetSTDIN<br>
>          // QSetSTDOUT<br>
>          // QSetSTDERR<br>
> -        StringExtractor packet(p);<br>
> +        StdStringExtractor packet(p);<br>
>          packet.SetFilePos (7);<br>
>          char ch = packet.GetChar();<br>
>          while (packet.GetChar() != ':')<br>
> @@ -2368,7 +2368,7 @@ RNBRemote::HandlePacket_QSetWorkingDir (<br>
>      // Only set the working directory if we don't already have a process<br>
>      if (!m_ctx.HasValidProcessID())<br>
>      {<br>
> -        StringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1);<br>
> +        StdStringExtractor packet(p += sizeof ("QSetWorkingDir:") - 1);<br>
>          if (packet.GetHexByteString (m_ctx.GetWorkingDir()))<br>
>          {<br>
>              struct stat working_dir_stat;<br>
> @@ -3473,7 +3473,7 @@ RNBRemote::HandlePacket_G (const char *p<br>
>      if (g_num_reg_entries == 0)<br>
>          InitializeRegisters ();<br>
><br>
> -    StringExtractor packet(p);<br>
> +    StdStringExtractor packet(p);<br>
>      packet.SetFilePos(1); // Skip the 'G'<br>
><br>
>      nub_process_t pid = m_ctx.ProcessID();<br>
> @@ -3540,10 +3540,10 @@ RNBRemoteShouldCancelCallback (void *not<br>
>  rnb_err_t<br>
>  RNBRemote::HandlePacket_AllocateMemory (const char *p)<br>
>  {<br>
> -    StringExtractor packet (p);<br>
> +    StdStringExtractor packet (p);<br>
>      packet.SetFilePos(2); // Skip the "_M"<br>
><br>
> -    nub_addr_t size = packet.GetHexMaxU64 (StringExtractor::BigEndian, 0);<br>
> +    nub_addr_t size = packet.GetHexMaxU64 (StdStringExtractor::BigEndian, 0);<br>
>      if (size != 0)<br>
>      {<br>
>          if (packet.GetChar() == ',')<br>
> @@ -3590,9 +3590,9 @@ RNBRemote::HandlePacket_AllocateMemory (<br>
>  rnb_err_t<br>
>  RNBRemote::HandlePacket_DeallocateMemory (const char *p)<br>
>  {<br>
> -    StringExtractor packet (p);<br>
> +    StdStringExtractor packet (p);<br>
>      packet.SetFilePos(2); // Skip the "_m"<br>
> -    nub_addr_t addr = packet.GetHexMaxU64 (StringExtractor::BigEndian, INVALID_NUB_ADDRESS);<br>
> +    nub_addr_t addr = packet.GetHexMaxU64 (StdStringExtractor::BigEndian, INVALID_NUB_ADDRESS);<br>
><br>
>      if (addr != INVALID_NUB_ADDRESS)<br>
>      {<br>
> @@ -3669,7 +3669,7 @@ RNBRemote::HandlePacket_RestoreRegisterS<br>
>              return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "No thread was is set with the Hg packet");<br>
>      }<br>
><br>
> -    StringExtractor packet (p);<br>
> +    StdStringExtractor packet (p);<br>
>      packet.SetFilePos(strlen("QRestoreRegisterState:")); // Skip the "QRestoreRegisterState:"<br>
>      const uint32_t save_id = packet.GetU32(0);<br>
><br>
> @@ -4222,7 +4222,7 @@ RNBRemote::HandlePacket_P (const char *p<br>
><br>
>      nub_process_t pid = m_ctx.ProcessID();<br>
><br>
> -    StringExtractor packet (p);<br>
> +    StdStringExtractor packet (p);<br>
><br>
>      const char cmd_char = packet.GetChar();<br>
>      // Register ID is always in big endian<br>
> @@ -4372,7 +4372,7 @@ RNBRemote::HandlePacket_GetProfileData (<br>
>      if (pid == INVALID_NUB_PROCESS)<br>
>          return SendPacket ("OK");<br>
><br>
> -    StringExtractor packet(p += sizeof ("qGetProfileData"));<br>
> +    StdStringExtractor packet(p += sizeof ("qGetProfileData"));<br>
>      DNBProfileDataScanType scan_type = eProfileAll;<br>
>      std::string name;<br>
>      std::string value;<br>
> @@ -4408,7 +4408,7 @@ RNBRemote::HandlePacket_SetEnableAsyncPr<br>
>      if (pid == INVALID_NUB_PROCESS)<br>
>          return SendPacket ("OK");<br>
><br>
> -    StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling"));<br>
> +    StdStringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling"));<br>
>      bool enable = false;<br>
>      uint64_t interval_usec = 0;<br>
>      DNBProfileDataScanType scan_type = eProfileAll;<br>
><br>
><br>
> _______________________________________________<br>
> lldb-commits mailing list<br>
> <a href="mailto:lldb-commits@lists.llvm.org" target="_blank">lldb-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits</a><br>
</blockquote></div>