1 //===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // C Includes
11 #include <string.h>
12 
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "Utility/StringExtractorGDBRemote.h"
17 
18 
19 
20 StringExtractorGDBRemote::ResponseType
21 StringExtractorGDBRemote::GetResponseType () const
22 {
23     if (m_packet.empty())
24         return eUnsupported;
25 
26     switch (m_packet[0])
27     {
28     case 'E':
29         if (m_packet.size() == 3 &&
30             isxdigit(m_packet[1]) &&
31             isxdigit(m_packet[2]))
32             return eError;
33         break;
34 
35     case 'O':
36         if (m_packet.size() == 2 && m_packet[1] == 'K')
37             return eOK;
38         break;
39 
40     case '+':
41         if (m_packet.size() == 1)
42             return eAck;
43         break;
44 
45     case '-':
46         if (m_packet.size() == 1)
47             return eNack;
48         break;
49     }
50     return eResponse;
51 }
52 
53 StringExtractorGDBRemote::ServerPacketType
54 StringExtractorGDBRemote::GetServerPacketType () const
55 {
56     // Empty is not a supported packet...
57     if (m_packet.empty())
58         return eServerPacketType_invalid;
59 
60     const char *packet_cstr = m_packet.c_str();
61     switch (m_packet[0])
62     {
63     case '\x03':
64         if (m_packet.size() == 1)
65             return eServerPacketType_interrupt;
66         break;
67 
68     case '-':
69         if (m_packet.size() == 1)
70             return eServerPacketType_nack;
71         break;
72 
73     case '+':
74         if (m_packet.size() == 1)
75             return eServerPacketType_ack;
76         break;
77 
78     case 'Q':
79         if (strcmp (packet_cstr, "QStartNoAckMode") == 0)
80             return eServerPacketType_QStartNoAckMode;
81         break;
82 
83     case 'q':
84         if (packet_cstr[1] == 'H' && 0 == ::strcmp (packet_cstr, "qHostInfo"))
85             return eServerPacketType_qHostInfo;
86         else if (packet_cstr[1] == 'P' && 0 == ::strncmp(packet_cstr, "qProcessInfoPID:", strlen("qProcessInfoPID:")))
87             return eServerPacketType_qProcessInfoPID;
88         else if (packet_cstr[1] == 'f' && 0 == ::strncmp(packet_cstr, "qfProcessInfo", strlen("qfProcessInfo")))
89             return eServerPacketType_qfProcessInfo;
90         else if (packet_cstr[1] == 'U' && 0 == ::strncmp(packet_cstr, "qUserName:", strlen("qUserName:")))
91             return eServerPacketType_qUserName;
92         else if (packet_cstr[1] == 'G' && 0 == ::strncmp(packet_cstr, "qGroupName:", strlen("qGroupName:")))
93             return eServerPacketType_qGroupName;
94         else if (packet_cstr[1] == 's' && 0 == ::strcmp (packet_cstr, "qsProcessInfo"))
95             return eServerPacketType_qsProcessInfo;
96         break;
97     }
98     return eServerPacketType_unimplemented;
99 }
100 
101 bool
102 StringExtractorGDBRemote::IsOKResponse() const
103 {
104     return GetResponseType () == eOK;
105 }
106 
107 
108 bool
109 StringExtractorGDBRemote::IsUnsupportedResponse() const
110 {
111     return GetResponseType () == eUnsupported;
112 }
113 
114 bool
115 StringExtractorGDBRemote::IsNormalResponse() const
116 {
117     return GetResponseType () == eResponse;
118 }
119 
120 bool
121 StringExtractorGDBRemote::IsErrorResponse() const
122 {
123     return GetResponseType () == eError &&
124            m_packet.size() == 3 &&
125            isxdigit(m_packet[1]) &&
126            isxdigit(m_packet[2]);
127 }
128 
129 uint8_t
130 StringExtractorGDBRemote::GetError ()
131 {
132     if (GetResponseType() == eError)
133     {
134         SetFilePos(1);
135         return GetHexU8(255);
136     }
137     return 0;
138 }
139