Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: remoting/protocol/message_decoder.cc

Issue 4017002: HostMessageDispatcher to parse control messages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged again Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/protocol/message_decoder.h ('k') | remoting/protocol/message_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium 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 "remoting/protocol/message_decoder.h"
6
7 #include "base/logging.h"
8 #include "net/base/io_buffer.h"
9 #include "remoting/base/multiple_array_input_stream.h"
10 #include "remoting/proto/internal.pb.h"
11 #include "talk/base/byteorder.h"
12
13 namespace remoting {
14
15 MessageDecoder::MessageDecoder()
16 : available_bytes_(0),
17 next_payload_(0),
18 next_payload_known_(false) {
19 }
20
21 MessageDecoder::~MessageDecoder() {}
22
23 void MessageDecoder::AddBuffer(scoped_refptr<net::IOBuffer> data,
24 int data_size) {
25 buffer_list_.push_back(new net::DrainableIOBuffer(data, data_size));
26 available_bytes_ += data_size;
27 }
28
29 MultipleArrayInputStream* MessageDecoder::CreateInputStreamFromData() {
30 // Determine the payload size. If we already know it then skip this part.
31 // We may not have enough data to determine the payload size so use a
32 // utility function to find out.
33 int next_payload = -1;
34 if (!next_payload_known_ && GetPayloadSize(&next_payload)) {
35 DCHECK_NE(-1, next_payload);
36 next_payload_ = next_payload;
37 next_payload_known_ = true;
38 }
39
40 // If the next payload size is still not known or we don't have enough
41 // data for parsing then exit.
42 if (!next_payload_known_ || available_bytes_ < next_payload_)
43 return NULL;
44 next_payload_known_ = false;
45
46 // The following loop gather buffers in |buffer_list_| that sum up to
47 // |next_payload_| bytes. These buffers are added to |stream|.
48
49 // Create a MultipleArrayInputStream for parsing.
50 // TODO(hclam): Avoid creating this object everytime.
51 MultipleArrayInputStream* stream = new MultipleArrayInputStream();
52 while (next_payload_ > 0 && !buffer_list_.empty()) {
53 scoped_refptr<net::DrainableIOBuffer> buffer = buffer_list_.front();
54 int read_bytes = std::min(buffer->BytesRemaining(), next_payload_);
55
56 // This call creates a new instance of DrainableIOBuffer internally.
57 // This will reference the same base pointer but maintain it's own
58 // version of data pointer.
59 stream->AddBuffer(buffer, read_bytes);
60
61 // Adjust counters.
62 buffer->DidConsume(read_bytes);
63 next_payload_ -= read_bytes;
64 available_bytes_ -= read_bytes;
65
66 // If the front buffer is fully read then remove it from the queue.
67 if (!buffer->BytesRemaining())
68 buffer_list_.pop_front();
69 }
70 DCHECK_EQ(0, next_payload_);
71 DCHECK_LE(0, available_bytes_);
72 return stream;
73 }
74
75 static int GetHeaderSize(const std::string& header) {
76 return header.length();
77 }
78
79 bool MessageDecoder::GetPayloadSize(int* size) {
80 // The header has a size of 4 bytes.
81 const int kHeaderSize = sizeof(int32);
82
83 if (available_bytes_ < kHeaderSize)
84 return false;
85
86 std::string header;
87 while (GetHeaderSize(header) < kHeaderSize && !buffer_list_.empty()) {
88 scoped_refptr<net::DrainableIOBuffer> buffer = buffer_list_.front();
89
90 // Find out how many bytes we need and how many bytes are available in this
91 // buffer.
92 int needed_bytes = kHeaderSize - GetHeaderSize(header);
93 int available_bytes = buffer->BytesRemaining();
94
95 // Then append the required bytes into the header and advance the last
96 // read position.
97 int read_bytes = std::min(needed_bytes, available_bytes);
98 header.append(buffer->data(), read_bytes);
99 buffer->DidConsume(read_bytes);
100 available_bytes_ -= read_bytes;
101
102 // If the buffer is depleted then remove it from the queue.
103 if (!buffer->BytesRemaining()) {
104 buffer_list_.pop_front();
105 }
106 }
107
108 *size = talk_base::GetBE32(header.c_str());
109 return true;
110 }
111
112 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/message_decoder.h ('k') | remoting/protocol/message_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698