OLD | NEW |
| (Empty) |
1 // Copyright 2011 The Native Client SDK Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can | |
3 // be found in the LICENSE file. | |
4 | |
5 #include "debugger/rsp/rsp_packet_util.h" | |
6 #include "debugger/rsp/rsp_packetizer.h" | |
7 | |
8 // Description of GDB RSP protocol: | |
9 // http://sources.redhat.com/gdb/current/onlinedocs/gdb.html#Remote-Protocol | |
10 | |
11 namespace { | |
12 class LocalPacketConsumer : public rsp::PacketConsumer { | |
13 public: | |
14 explicit LocalPacketConsumer(debug::Blob* packet) | |
15 : packet_(packet), success_(false) {} | |
16 virtual void OnPacket(const debug::Blob& body, bool valid_checksum) { | |
17 *packet_ = body; | |
18 success_ = true; | |
19 } | |
20 virtual void OnUnexpectedChar(char unexpected_char) {} | |
21 virtual void OnBreak() {} | |
22 | |
23 debug::Blob* packet_; | |
24 bool success_; | |
25 }; | |
26 | |
27 void Escape(const debug::Blob& blob_in, debug::Blob* blob_out); | |
28 } // namespace | |
29 | |
30 namespace rsp { | |
31 void PacketUtil::AddEnvelope(const debug::Blob& blob_in, | |
32 debug::Blob* blob_out) { | |
33 blob_out->Clear(); | |
34 Escape(blob_in, blob_out); | |
35 unsigned int checksum = 0; | |
36 for (size_t i = 0; i < blob_out->size(); i++) { | |
37 checksum += (*blob_out)[i]; | |
38 checksum %= 256; | |
39 } | |
40 | |
41 blob_out->PushFront('$'); | |
42 blob_out->PushBack('#'); | |
43 blob_out->PushBack(debug::Blob::GetHexDigit(checksum, 1)); | |
44 blob_out->PushBack(debug::Blob::GetHexDigit(checksum, 0)); | |
45 } | |
46 | |
47 bool PacketUtil::RemoveEnvelope(const debug::Blob& blob_in, | |
48 debug::Blob* blob_out) { | |
49 blob_out->Clear(); | |
50 Packetizer pktz; | |
51 LocalPacketConsumer consumer(blob_out); | |
52 pktz.SetPacketConsumer(&consumer); | |
53 pktz.OnData(blob_in); | |
54 return consumer.success_; | |
55 } | |
56 } // namespace rsp | |
57 | |
58 namespace { | |
59 void Escape(const debug::Blob& blob_in, debug::Blob* blob_out) { | |
60 blob_out->Clear(); | |
61 unsigned char prev_c = 0; | |
62 for (size_t i = 0; i < blob_in.size(); i++) { | |
63 unsigned char c = blob_in[i]; | |
64 if (((('$' == c) || ('#' == c) || ('*' == c) || ('}' == c) || (3 == c)) && | |
65 (prev_c != '*')) || (c > 126)) { | |
66 // escape it by '}' | |
67 blob_out->PushBack('}'); | |
68 c = c ^ 0x20; | |
69 } | |
70 blob_out->PushBack(c); | |
71 prev_c = blob_in[i]; | |
72 } | |
73 } | |
74 } // namespace | |
75 | |
OLD | NEW |