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 | |
5 #include "debugger/rsp/rsp_packet_utils.h" | |
6 #include "debugger/rsp/rsp_packetizer.h" | |
7 | |
8 namespace { | |
9 /// Replaces characters '}', '#', '$', '*' and characters > 126 with escape | |
10 /// sequences: '}' + c ^ 0x20, per RSP protocol spec. | |
11 /// @param[in] blob_in blob to be escaped | |
12 /// @param[out] blob_out destination for transformed blob | |
13 void Escape(const debug::Blob& blob_in, debug::Blob* blob_out) { | |
14 blob_out->Clear(); | |
15 unsigned char prev_c = 0; | |
16 for (size_t i = 0; i < blob_in.size(); i++) { | |
17 unsigned char c = blob_in[i]; | |
18 if (((('$' == c) || ('#' == c) || ('*' == c) || ('}' == c) || (3 == c)) && | |
19 (prev_c != '*')) || (c > 126)) { | |
20 // escape it by '}' | |
21 blob_out->PushBack('}'); | |
22 c = c ^ 0x20; | |
23 } | |
24 blob_out->PushBack(c); | |
25 prev_c = blob_in[i]; | |
26 } | |
27 } | |
28 | |
29 class LocalPacketConsumer : public rsp::PacketConsumerInterface { | |
30 public: | |
31 explicit LocalPacketConsumer(debug::Blob* packet) | |
32 : packet_(packet), | |
33 success_(false) { | |
34 } | |
35 virtual void OnPacket(const debug::Blob& body, bool valid_checksum) { | |
36 *packet_ = body; | |
37 success_ = valid_checksum; | |
38 } | |
39 virtual void OnUnexpectedByte(uint8_t unexpected_byte) {} | |
40 virtual void OnBreak() {} | |
41 | |
42 debug::Blob* packet_; | |
43 bool success_; | |
44 }; | |
45 } // namespace | |
46 | |
47 namespace rsp { | |
48 void PacketUtils::AddEnvelope(const debug::Blob& blob_in, | |
49 debug::Blob* blob_out) { | |
50 blob_out->Clear(); | |
51 Escape(blob_in, blob_out); | |
52 unsigned int checksum = 0; | |
53 for (size_t i = 0; i < blob_out->size(); i++) { | |
54 checksum += (*blob_out)[i]; | |
55 checksum %= 256; | |
56 } | |
57 | |
58 blob_out->PushFront('$'); | |
59 blob_out->PushBack('#'); | |
60 blob_out->PushBack(debug::Blob::GetHexDigit(checksum, 1)); | |
61 blob_out->PushBack(debug::Blob::GetHexDigit(checksum, 0)); | |
62 } | |
63 | |
64 bool PacketUtils::RemoveEnvelope(const debug::Blob& blob_in, | |
65 debug::Blob* blob_out) { | |
66 blob_out->Clear(); | |
67 | |
68 // RSP packet consumer, copies received RSP message to |blob_out|. | |
69 LocalPacketConsumer consumer(blob_out); | |
70 | |
71 // Associate |consumer| with packetizer. | |
72 // Packetizer will call consumer->OnPacket when it receives complete | |
73 // RSP packet. | |
74 Packetizer pktz; | |
75 pktz.SetPacketConsumer(&consumer); | |
76 | |
77 // Packetizer removes envelope and calls LocalPacketConsumer::OnPacket, | |
78 // OnPacket copies unpacked message to |blob_out|. | |
79 pktz.OnData(blob_in); | |
80 | |
81 // LocalPacketConsumer::OnPacket sets |consumer.success_| to true | |
82 // if message was successfully unpacked (and checksum is correct). | |
83 return consumer.success_; | |
84 } | |
85 } // namespace rsp | |
86 | |
OLD | NEW |