| Index: build_tools/debug_server/debug_server/common/rsp_packet_utils.cc
|
| ===================================================================
|
| --- build_tools/debug_server/debug_server/common/rsp_packet_utils.cc (revision 0)
|
| +++ build_tools/debug_server/debug_server/common/rsp_packet_utils.cc (revision 0)
|
| @@ -0,0 +1,78 @@
|
| +#include "rsp_packet_utils.h"
|
| +#include "rsp_packetizer.h"
|
| +
|
| +// Description of GDB RSP protocol:
|
| +// http://sources.redhat.com/gdb/current/onlinedocs/gdb.html#Remote-Protocol
|
| +
|
| +namespace {
|
| +class LocalPacketConsumer : public rsp::PacketConsumer {
|
| + public:
|
| + LocalPacketConsumer(debug::Blob* packet)
|
| + : packet_(packet), success_(false) {}
|
| + virtual void OnPacket(debug::Blob& body, bool valid_checksum) {
|
| + *packet_ = body;
|
| + success_ = true;
|
| + }
|
| + virtual void OnUnexpectedChar(char unexpected_char) {}
|
| + virtual void OnBreak() {}
|
| +
|
| + debug::Blob* packet_;
|
| + bool success_;
|
| +};
|
| +
|
| +void Escape(const debug::Blob& blob_in, debug::Blob* blob_out);
|
| +char GetHexDigit(unsigned int value, int digit_position);
|
| +} // namespace
|
| +
|
| +namespace rsp {
|
| +void PacketUtils::AddEnvelope(const debug::Blob& blob_in,
|
| + debug::Blob* blob_out) {
|
| + blob_out->Clear();
|
| + Escape(blob_in, blob_out);
|
| + unsigned long checksum = 0;
|
| + for (size_t i = 0; i < blob_out->Size(); i++) {
|
| + checksum += (*blob_out)[i];
|
| + checksum %= 256;
|
| + }
|
| +
|
| + blob_out->PushFront('$');
|
| + blob_out->PushBack('#');
|
| + blob_out->PushBack(GetHexDigit(checksum, 1));
|
| + blob_out->PushBack(GetHexDigit(checksum, 0));
|
| +}
|
| +
|
| +bool PacketUtils::RemoveEnvelope(const debug::Blob& blob_in,
|
| + debug::Blob* blob_out) {
|
| + blob_out->Clear();
|
| + Packetizer pktz;
|
| + LocalPacketConsumer consumer(blob_out);
|
| + pktz.SetPacketConsumer(&consumer);
|
| + pktz.OnData(blob_in);
|
| + return consumer.success_;
|
| +}
|
| +} // namespace rsp
|
| +
|
| +namespace {
|
| +void Escape(const debug::Blob& blob_in, debug::Blob* blob_out) {
|
| + blob_out->Clear();
|
| + unsigned char prev_c = 0;
|
| + for (size_t i = 0; i < blob_in.Size(); i++) {
|
| + unsigned char c = blob_in[i];
|
| + if (((('$' == c) || ('#' == c) || ('*' == c) || ('}' == c) || (3 == c)) &&
|
| + (prev_c != '*')) || (c > 126)) {
|
| + // escape it by '}'
|
| + blob_out->PushBack('}');
|
| + c = c ^ 0x20;
|
| + }
|
| + blob_out->PushBack(c);
|
| + prev_c = blob_in[i];
|
| + }
|
| +}
|
| +
|
| +char GetHexDigit(unsigned int value, int digit_position) {
|
| + const char* kDigitStrings = "0123456789ABCDEF";
|
| + unsigned int digit = (value >> (4 * digit_position)) & 0xF;
|
| + return kDigitStrings[digit];
|
| +}
|
| +} // namespace
|
| +
|
|
|