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

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

Powered by Google App Engine
This is Rietveld 408576698