OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 #include "debugger/rsp/rsp_info_packets.h" | |
5 | |
6 namespace rsp { | |
7 void QuerySupportedCommand::AddFeature(const std::string& name, | |
8 const std::string& value) { | |
9 features_.push_back(std::pair<std::string, std::string>(name, value)); | |
10 } | |
11 | |
12 /// Example: "qSupported" + "xmlRegisters=i386;qRelocInsn+" | |
13 bool QuerySupportedCommand::FromBlob(const std::string& type, | |
14 debug::Blob* message) { | |
15 // First, split into "name=value" statements. | |
16 std::deque<debug::Blob> statements; | |
17 message->Split(debug::Blob().FromString(";"), &statements); | |
18 | |
19 std::deque<debug::Blob>::iterator it = statements.begin(); | |
20 while (it != statements.end()) { | |
21 std::deque<debug::Blob> tokens; | |
22 // Now, split each "name=value" statement into "name" + "value". | |
23 it->Split(debug::Blob().FromString("="), &tokens); | |
24 it++; | |
25 RemoveSpacesFromBothEnds(&tokens); | |
26 if (tokens.size() == 2) { | |
27 AddFeature(tokens[0].ToString(), tokens[1].ToString()); | |
28 } else if (tokens.size() == 1) { | |
29 // Handles case of "name+" statements. | |
30 debug::Blob& name = tokens[0]; | |
31 if (name.size() > 0) { | |
32 // Pop '+' or '-' | |
33 char last_char = name.PopBack(); | |
34 if (('-' == last_char) || ('+' == last_char)) { | |
35 std::string value; | |
36 value.append(1, last_char); | |
37 AddFeature(name.ToString(), value); | |
38 } else { | |
39 return false; | |
40 } | |
41 } | |
42 } else { | |
43 return false; | |
44 } | |
45 } | |
46 return true; | |
47 } | |
48 | |
49 size_t QuerySupportedCommand::GetFeaturesNum() const { | |
50 return features_.size(); | |
51 } | |
52 | |
53 std::string QuerySupportedCommand::GetFeatureName(size_t pos) const { | |
54 if (pos >= GetFeaturesNum()) | |
55 return ""; | |
56 return features_[pos].first; | |
57 } | |
58 | |
59 std::string QuerySupportedCommand::GetFeature(const std::string& name) const { | |
60 for (size_t i = 0; i < GetFeaturesNum(); i++) { | |
61 if (name == GetFeatureName(i)) | |
62 return features_[i].second; | |
63 } | |
64 return ""; | |
65 } | |
66 | |
67 void QuerySupportedCommand::SaveFeaturesToBlob(debug::Blob* message) const { | |
68 size_t num = features_.size(); | |
69 for (size_t i = 0; i < num; i++) { | |
70 const std::pair<std::string, std::string>& feature = features_[i]; | |
71 if (0 != i) | |
72 message->Append(debug::Blob().FromString(";")); | |
73 message->Append(debug::Blob().FromString(feature.first)); | |
74 if (("+" != feature.second) && | |
75 ("-" != feature.second) && | |
76 ("?" != feature.second)) | |
77 message->Append(debug::Blob().FromString("=")); | |
78 message->Append(debug::Blob().FromString(feature.second)); | |
79 } | |
80 } | |
81 | |
82 void QuerySupportedCommand::ToBlob(debug::Blob* message) const { | |
83 message->Append(debug::Blob().FromString("qSupported:")); | |
84 SaveFeaturesToBlob(message); | |
85 } | |
86 | |
87 void QuerySupportedReply::ToBlob(debug::Blob* message) const { | |
88 SaveFeaturesToBlob(message); | |
89 } | |
90 | |
91 const char* QXferFeaturesReadCommand::kPrefix = "qXfer:features:read:"; | |
92 QXferFeaturesReadCommand::QXferFeaturesReadCommand() | |
93 : offset_(0), | |
94 length_(0) { | |
95 } | |
96 | |
97 bool QXferFeaturesReadCommand::FromBlob(const std::string& type, | |
98 debug::Blob* message) { | |
99 // example: target.xml:0,7ca | |
100 debug::Blob file_name = | |
101 message->PopBlobFromFrontUntilBytes(debug::Blob().FromString(":")); | |
102 debug::Blob offs = | |
103 message->PopBlobFromFrontUntilBytes(debug::Blob().FromString(",")); | |
104 | |
105 file_name_ = file_name.ToString(); | |
106 bool r1 = PopIntFromFront(&offs, &offset_); | |
107 bool r2 = PopIntFromFront(message, &length_); | |
108 return (r1 && r2); | |
109 } | |
110 | |
111 void QXferFeaturesReadCommand::ToBlob(debug::Blob* message) const { | |
112 Format(message, "%s%s:%x,%x", kPrefix, file_name_.c_str(), offset_, length_); | |
113 } | |
114 | |
115 bool QXferReply::FromBlob(const std::string& type, debug::Blob* message) { | |
116 if (message->size() < 2) | |
117 return false; | |
118 uint8_t cmd = message->PopFront(); | |
119 if (('l' != cmd) && ('m' != cmd)) | |
120 return false; | |
121 | |
122 eom_ = ('l' == cmd); | |
123 body_ = message->ToString(); | |
124 return true; | |
125 } | |
126 | |
127 void QXferReply::ToBlob(debug::Blob* message) const { | |
128 Format(message, (eom_ ? "l%s" : "m%s"), body_.c_str()); | |
129 } | |
130 | |
131 bool GetOffsetsReply::FromBlob(const std::string& type, debug::Blob* message) { | |
132 // Example: Text=c00000000;Data=c00000000 | |
133 std::deque<debug::Blob> statements; | |
134 message->Split(debug::Blob().FromString(";"), &statements); | |
135 for (size_t i = 0; i < statements.size(); i++) { | |
136 std::deque<debug::Blob> tokens; | |
137 statements[i].Split(debug::Blob().FromString("="), &tokens); | |
138 if (tokens.size() >= 2) { | |
139 if ("Text" == tokens[0].ToString()) | |
140 rsp::PopIntFromFront(&tokens[1], &text_offset_); | |
141 else if ("Data" == tokens[0].ToString()) | |
142 rsp::PopIntFromFront(&tokens[1], &data_offset_); | |
143 } | |
144 } | |
145 return true; | |
146 } | |
147 | |
148 void GetOffsetsReply::ToBlob(debug::Blob* message) const { | |
149 message->Append(debug::Blob().FromString("Text=")); | |
150 rsp::PushIntToBack(text_offset_, message); | |
151 message->Append(debug::Blob().FromString(";Data=")); | |
152 rsp::PushIntToBack(data_offset_, message); | |
153 } | |
154 | |
155 } // namespace rsp | |
156 | |
OLD | NEW |