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

Side by Side Diff: components/cast_channel/cast_framer.cc

Issue 2926313002: Revert of [cast_channel] Move cast_channel related files from //extensions to //components (Closed)
Patch Set: Created 3 years, 6 months 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
« no previous file with comments | « components/cast_channel/cast_framer.h ('k') | components/cast_channel/cast_framer_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 2014 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 "components/cast_channel/cast_framer.h"
6
7 #include <stdlib.h>
8
9 #include <limits>
10
11 #include "base/memory/free_deleter.h"
12 #include "base/numerics/safe_conversions.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/sys_byteorder.h"
15 #include "components/cast_channel/proto/cast_channel.pb.h"
16
17 namespace cast_channel {
18 MessageFramer::MessageFramer(scoped_refptr<net::GrowableIOBuffer> input_buffer)
19 : input_buffer_(input_buffer), error_(false) {
20 Reset();
21 }
22
23 MessageFramer::~MessageFramer() {}
24
25 MessageFramer::MessageHeader::MessageHeader() : message_size(0) {}
26
27 void MessageFramer::MessageHeader::SetMessageSize(size_t size) {
28 DCHECK_LT(size, static_cast<size_t>(std::numeric_limits<uint32_t>::max()));
29 DCHECK_GT(size, 0U);
30 message_size = size;
31 }
32
33 // TODO(mfoltz): Investigate replacing header serialization with base::Pickle,
34 // if bit-for-bit compatible.
35 void MessageFramer::MessageHeader::PrependToString(std::string* str) {
36 MessageHeader output = *this;
37 output.message_size = base::HostToNet32(message_size);
38 size_t header_size = MessageHeader::header_size();
39 std::unique_ptr<char, base::FreeDeleter> char_array(
40 static_cast<char*>(malloc(header_size)));
41 memcpy(char_array.get(), &output, header_size);
42 str->insert(0, char_array.get(), header_size);
43 }
44
45 // TODO(mfoltz): Investigate replacing header deserialization with base::Pickle,
46 // if bit-for-bit compatible.
47 void MessageFramer::MessageHeader::Deserialize(char* data,
48 MessageHeader* header) {
49 uint32_t message_size;
50 memcpy(&message_size, data, header_size());
51 header->message_size =
52 base::checked_cast<size_t>(base::NetToHost32(message_size));
53 }
54
55 // static
56 size_t MessageFramer::MessageHeader::header_size() {
57 return sizeof(uint32_t);
58 }
59
60 // static
61 size_t MessageFramer::MessageHeader::max_message_size() {
62 return 65535;
63 }
64
65 std::string MessageFramer::MessageHeader::ToString() {
66 return "{message_size: " +
67 base::UintToString(static_cast<uint32_t>(message_size)) + "}";
68 }
69
70 // static
71 bool MessageFramer::Serialize(const CastMessage& message_proto,
72 std::string* message_data) {
73 DCHECK(message_data);
74 message_proto.SerializeToString(message_data);
75 size_t message_size = message_data->size();
76 if (message_size > MessageHeader::max_message_size()) {
77 message_data->clear();
78 return false;
79 }
80 MessageHeader header;
81 header.SetMessageSize(message_size);
82 header.PrependToString(message_data);
83 return true;
84 }
85
86 size_t MessageFramer::BytesRequested() {
87 size_t bytes_left;
88 if (error_) {
89 return 0;
90 }
91
92 switch (current_element_) {
93 case HEADER:
94 bytes_left = MessageHeader::header_size() - message_bytes_received_;
95 DCHECK_LE(bytes_left, MessageHeader::header_size());
96 VLOG(2) << "Bytes needed for header: " << bytes_left;
97 return bytes_left;
98 case BODY:
99 bytes_left =
100 (body_size_ + MessageHeader::header_size()) - message_bytes_received_;
101 DCHECK_LE(bytes_left, MessageHeader::max_message_size() -
102 MessageHeader::header_size());
103 VLOG(2) << "Bytes needed for body: " << bytes_left;
104 return bytes_left;
105 default:
106 NOTREACHED() << "Unhandled packet element type.";
107 return 0;
108 }
109 }
110
111 std::unique_ptr<CastMessage> MessageFramer::Ingest(size_t num_bytes,
112 size_t* message_length,
113 ChannelError* error) {
114 DCHECK(error);
115 DCHECK(message_length);
116 if (error_) {
117 *error = ChannelError::INVALID_MESSAGE;
118 return nullptr;
119 }
120
121 DCHECK_EQ(base::checked_cast<int32_t>(message_bytes_received_),
122 input_buffer_->offset());
123 CHECK_LE(num_bytes, BytesRequested());
124 message_bytes_received_ += num_bytes;
125 *error = ChannelError::NONE;
126 *message_length = 0;
127 switch (current_element_) {
128 case HEADER:
129 if (BytesRequested() == 0) {
130 MessageHeader header;
131 MessageHeader::Deserialize(input_buffer_->StartOfBuffer(), &header);
132 if (header.message_size > MessageHeader::max_message_size()) {
133 VLOG(1) << "Error parsing header (message size too large).";
134 *error = ChannelError::INVALID_MESSAGE;
135 error_ = true;
136 return nullptr;
137 }
138 current_element_ = BODY;
139 body_size_ = header.message_size;
140 }
141 break;
142 case BODY:
143 if (BytesRequested() == 0) {
144 std::unique_ptr<CastMessage> parsed_message(new CastMessage);
145 if (!parsed_message->ParseFromArray(
146 input_buffer_->StartOfBuffer() + MessageHeader::header_size(),
147 body_size_)) {
148 VLOG(1) << "Error parsing packet body.";
149 *error = ChannelError::INVALID_MESSAGE;
150 error_ = true;
151 return nullptr;
152 }
153 *message_length = body_size_;
154 Reset();
155 return parsed_message;
156 }
157 break;
158 default:
159 NOTREACHED() << "Unhandled packet element type.";
160 return nullptr;
161 }
162
163 input_buffer_->set_offset(message_bytes_received_);
164 return nullptr;
165 }
166
167 void MessageFramer::Reset() {
168 current_element_ = HEADER;
169 message_bytes_received_ = 0;
170 body_size_ = 0;
171 input_buffer_->set_offset(0);
172 }
173
174 } // namespace cast_channel
OLDNEW
« no previous file with comments | « components/cast_channel/cast_framer.h ('k') | components/cast_channel/cast_framer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698