forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Retry landing the flip changes. This time with DEPS!
BUG=none TEST=flip_session_unittest.cc flip_network_transaction_unittest.cc flip_framer_test.cc Review URL: http://codereview.chromium.org/210016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26533 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
mbelshe@google.com
committed
Sep 18, 2009
1 parent
c69157c
commit aea8060
Showing
17 changed files
with
3,770 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
include_rules = [ | ||
"+third_party/modp_b64", | ||
"+third_party/libevent", | ||
"+third_party/zlib", | ||
"+sdch/open_vcdiff", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright (c) 2009 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef NET_FLIP_FLIP_BITMASKS_H_ | ||
#define NET_FLIP_FLIP_BITMASKS_H_ | ||
|
||
namespace flip { | ||
|
||
const int kStreamIdMask = 0x7fffffff; // StreamId mask from the FlipHeader | ||
const int kControlFlagMask = 0x8000; // Control flag mask from the FlipHeader | ||
const int kPriorityMask = 0xc0; // Priority mask from the SYN_FRAME | ||
} // flip | ||
|
||
#endif // NET_FLIP_FLIP_BITMASKS_H_ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
// Copyright (c) 2009 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include <limits> | ||
|
||
#include "flip_frame_builder.h" // cross-google3 directory naming. | ||
#include "flip_protocol.h" | ||
|
||
namespace flip { | ||
|
||
// We mark a read only FlipFrameBuilder with a special capacity_. | ||
static const size_t kCapacityReadOnly = std::numeric_limits<size_t>::max(); | ||
|
||
FlipFrameBuilder::FlipFrameBuilder() | ||
: buffer_(NULL), | ||
capacity_(0), | ||
length_(0), | ||
variable_buffer_offset_(0) { | ||
Resize(kInitialPayload); | ||
} | ||
|
||
FlipFrameBuilder::FlipFrameBuilder(const char* data, int data_len) | ||
: buffer_(const_cast<char*>(data)), | ||
capacity_(kCapacityReadOnly), | ||
length_(data_len), | ||
variable_buffer_offset_(0) { | ||
} | ||
|
||
FlipFrameBuilder::~FlipFrameBuilder() { | ||
if (capacity_ != kCapacityReadOnly) | ||
delete[] buffer_; | ||
} | ||
|
||
bool FlipFrameBuilder::ReadUInt16(void** iter, uint16* result) const { | ||
DCHECK(iter); | ||
if (!*iter) | ||
*iter = const_cast<char*>(buffer_); | ||
|
||
if (!IteratorHasRoomFor(*iter, sizeof(*result))) | ||
return false; | ||
|
||
*result = ntohs(*(reinterpret_cast<uint16*>(*iter))); | ||
|
||
UpdateIter(iter, sizeof(*result)); | ||
return true; | ||
} | ||
|
||
bool FlipFrameBuilder::ReadUInt32(void** iter, uint32* result) const { | ||
DCHECK(iter); | ||
if (!*iter) | ||
*iter = const_cast<char*>(buffer_); | ||
|
||
if (!IteratorHasRoomFor(*iter, sizeof(*result))) | ||
return false; | ||
|
||
*result = ntohl(*(reinterpret_cast<uint32*>(*iter))); | ||
|
||
UpdateIter(iter, sizeof(*result)); | ||
return true; | ||
} | ||
|
||
bool FlipFrameBuilder::ReadString(void** iter, std::string* result) const { | ||
DCHECK(iter); | ||
|
||
uint16 len; | ||
if (!ReadUInt16(iter, &len)) { | ||
VLOG(1) << "Unable to read length"; | ||
return false; | ||
} | ||
if (!IteratorHasRoomFor(*iter, len)) { | ||
VLOG(1) << "!IteratorHasRoomFor"; | ||
return false; | ||
} | ||
|
||
char* chars = reinterpret_cast<char*>(*iter); | ||
result->assign(chars, len); | ||
|
||
UpdateIter(iter, len); | ||
return true; | ||
} | ||
|
||
bool FlipFrameBuilder::ReadBytes(void** iter, const char** data, | ||
uint16 length) const { | ||
DCHECK(iter); | ||
DCHECK(data); | ||
|
||
if (!IteratorHasRoomFor(*iter, length)) | ||
return false; | ||
|
||
*data = reinterpret_cast<const char*>(*iter); | ||
|
||
UpdateIter(iter, length); | ||
return true; | ||
} | ||
|
||
bool FlipFrameBuilder::ReadData(void** iter, const char** data, | ||
uint16* length) const { | ||
DCHECK(iter); | ||
DCHECK(data); | ||
DCHECK(length); | ||
|
||
if (!ReadUInt16(iter, length)) | ||
return false; | ||
|
||
return ReadBytes(iter, data, *length); | ||
} | ||
|
||
char* FlipFrameBuilder::BeginWrite(size_t length) { | ||
size_t offset = length_; | ||
size_t needed_size = length_ + length; | ||
if (needed_size > capacity_ && !Resize(std::max(capacity_ * 2, needed_size))) | ||
return NULL; | ||
|
||
#ifdef ARCH_CPU_64_BITS | ||
DCHECK_LE(length, std::numeric_limits<uint32>::max()); | ||
#endif | ||
|
||
return buffer_ + offset; | ||
} | ||
|
||
void FlipFrameBuilder::EndWrite(char* dest, int length) { | ||
} | ||
|
||
bool FlipFrameBuilder::WriteBytes(const void* data, uint16 data_len) { | ||
DCHECK(capacity_ != kCapacityReadOnly); | ||
|
||
char* dest = BeginWrite(data_len); | ||
if (!dest) | ||
return false; | ||
|
||
memcpy(dest, data, data_len); | ||
|
||
EndWrite(dest, data_len); | ||
length_ += data_len; | ||
return true; | ||
} | ||
|
||
bool FlipFrameBuilder::WriteString(const std::string& value) { | ||
if (value.size() > 0xffff) | ||
return false; | ||
|
||
if (!WriteUInt16(static_cast<int>(value.size()))) | ||
return false; | ||
|
||
return WriteBytes(value.data(), static_cast<uint16>(value.size())); | ||
} | ||
|
||
char* FlipFrameBuilder::BeginWriteData(uint16 length) { | ||
DCHECK_EQ(variable_buffer_offset_, 0U) << | ||
"There can only be one variable buffer in a FlipFrameBuilder"; | ||
|
||
if (!WriteUInt16(length)) | ||
return false; | ||
|
||
char *data_ptr = BeginWrite(length); | ||
if (!data_ptr) | ||
return NULL; | ||
|
||
variable_buffer_offset_ = data_ptr - buffer_ - sizeof(int); | ||
|
||
// EndWrite doesn't necessarily have to be called after the write operation, | ||
// so we call it here to pad out what the caller will eventually write. | ||
EndWrite(data_ptr, length); | ||
return data_ptr; | ||
} | ||
|
||
bool FlipFrameBuilder::Resize(size_t new_capacity) { | ||
if (new_capacity < capacity_) | ||
return true; | ||
|
||
char* p = new char[new_capacity]; | ||
if (buffer_) { | ||
memcpy(p, buffer_, capacity_); | ||
delete[] buffer_; | ||
} | ||
if (!p && new_capacity > 0) | ||
return false; | ||
buffer_ = p; | ||
capacity_ = new_capacity; | ||
return true; | ||
} | ||
|
||
} // namespace flip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
// Copyright (c) 2009 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef NET_FLIP_FRAME_BUILDER_H_ | ||
#define NET_FLIP_FRAME_BUILDER_H_ | ||
|
||
#ifdef WIN32 | ||
#include <winsock2.h> // for htonl() functions | ||
#else | ||
#include <arpa/inet.h> | ||
#endif | ||
|
||
#include <string> | ||
|
||
#include "base/logging.h" | ||
#include "flip_protocol.h" // cross-google3 directory naming. | ||
|
||
#ifdef WIN32 | ||
#undef VLOG | ||
#define VLOG(x) LOG_IF(INFO, false) | ||
#endif // WIN32 | ||
|
||
namespace flip { | ||
|
||
// This class provides facilities for basic binary value packing and unpacking | ||
// into Flip frames. Note: this is similar to Chrome's pickle class, but is | ||
// simplified to work in both the client and server, and without excess | ||
// padding. | ||
// | ||
// The FlipFrameBuilder supports appending primitive values (int, string, etc) | ||
// to a frame instance. The FlipFrameBuilder grows its internal memory buffer | ||
// dynamically to hold the sequence of primitive values. The internal memory | ||
// buffer is exposed as the "data" of the FlipFrameBuilder. | ||
// | ||
// When reading from a FlipFrameBuilder the consumer must know what value types | ||
// to read and in what order to read them as the FlipFrameBuilder does not keep | ||
// track of the type of data written to it. | ||
class FlipFrameBuilder { | ||
public: | ||
FlipFrameBuilder(); | ||
~FlipFrameBuilder(); | ||
|
||
// Initializes a FlipFrameBuilder from a const block of data. The data is | ||
// not copied; instead the data is merely referenced by this | ||
// FlipFrameBuilder. Only const methods should be used when initialized | ||
// this way. | ||
FlipFrameBuilder(const char* data, int data_len); | ||
|
||
// Returns the size of the FlipFrameBuilder's data. | ||
int length() const { return length_; } | ||
|
||
// Returns the data for this FlipFrameBuilder. | ||
const FlipFrame* data() const { | ||
return reinterpret_cast<FlipFrame*>(buffer_); | ||
} | ||
|
||
// Takes the buffer from the FlipFrameBuilder. | ||
FlipFrame* take() { | ||
FlipFrame* rv = reinterpret_cast<FlipFrame*>(buffer_); | ||
buffer_ = NULL; | ||
capacity_ = 0; | ||
length_ = 0; | ||
return rv; | ||
} | ||
|
||
// Methods for reading the payload of the FlipFrameBuilder. To read from the | ||
// start of the FlipFrameBuilder, initialize *iter to NULL. If successful, | ||
// these methods return true. Otherwise, false is returned to indicate that | ||
// the result could not be extracted. | ||
bool ReadUInt16(void** iter, uint16* result) const; | ||
bool ReadUInt32(void** iter, uint32* result) const; | ||
bool ReadString(void** iter, std::string* result) const; | ||
bool ReadBytes(void** iter, const char** data, uint16 length) const; | ||
bool ReadData(void** iter, const char** data, uint16* length) const; | ||
|
||
// Methods for adding to the payload. These values are appended to the end | ||
// of the FlipFrameBuilder payload. When reading values, you must read them | ||
// in the order they were added. Note - binary integers are converted from | ||
// host to network form. | ||
bool WriteUInt16(uint16 value) { | ||
value = htons(value); | ||
return WriteBytes(&value, sizeof(value)); | ||
} | ||
bool WriteUInt32(uint32 value) { | ||
value = htonl(value); | ||
return WriteBytes(&value, sizeof(value)); | ||
} | ||
bool WriteString(const std::string& value); | ||
bool WriteBytes(const void* data, uint16 data_len); | ||
|
||
// Write an integer to a particular offset in the data buffer. | ||
bool WriteUInt32ToOffset(int offset, uint32 value) { | ||
if (offset + sizeof(value) > length_) | ||
return false; | ||
value = htonl(value); | ||
char *ptr = buffer_ + offset; | ||
memcpy(ptr, &value, sizeof(value)); | ||
return true; | ||
} | ||
|
||
// Allows the caller to write data directly into the FlipFrameBuilder. | ||
// This saves a copy when the data is not already available in a buffer. | ||
// The caller must not write more than the length it declares it will. | ||
// Use ReadData to get the data. | ||
// Returns NULL on failure. | ||
// | ||
// The returned pointer will only be valid until the next write operation | ||
// on this FlipFrameBuilder. | ||
char* BeginWriteData(uint16 length); | ||
|
||
// Returns true if the given iterator could point to data with the given | ||
// length. If there is no room for the given data before the end of the | ||
// payload, returns false. | ||
bool IteratorHasRoomFor(const void* iter, int len) const { | ||
const char* end_of_region = reinterpret_cast<const char*>(iter) + len; | ||
VLOG(1) << "len: " << len; | ||
if (len < 0) { | ||
VLOG(1) << "Len < 0"; | ||
return false; | ||
} else if (iter < buffer_) { | ||
VLOG(1) << "iter < buffer_"; | ||
return false; | ||
} else if (iter > end_of_payload()) { | ||
VLOG(1) << "iter > end_of_payload())"; | ||
return false; | ||
} else if (iter > end_of_region) { | ||
VLOG(1) << "iter > end_of_region)"; | ||
return false; | ||
} else if (end_of_region > end_of_payload()) { | ||
VLOG(1) << "end_of_region > end_of_payload()"; | ||
VLOG(1) << "end_of_region - end_of_payload(): " | ||
<< (end_of_region - end_of_payload()); | ||
|
||
return false; | ||
} | ||
|
||
// Watch out for overflow in pointer calculation, which wraps. | ||
return (iter <= end_of_region) && (end_of_region <= end_of_payload()); | ||
} | ||
|
||
protected: | ||
size_t capacity() const { | ||
return capacity_; | ||
} | ||
|
||
const char* end_of_payload() const { return buffer_ + length_; } | ||
|
||
// Resizes the buffer for use when writing the specified amount of data. The | ||
// location that the data should be written at is returned, or NULL if there | ||
// was an error. Call EndWrite with the returned offset and the given length | ||
// to pad out for the next write. | ||
char* BeginWrite(size_t length); | ||
|
||
// Completes the write operation by padding the data with NULL bytes until it | ||
// is padded. Should be paired with BeginWrite, but it does not necessarily | ||
// have to be called after the data is written. | ||
void EndWrite(char* dest, int length); | ||
|
||
// Resize the capacity, note that the input value should include the size of | ||
// the header: new_capacity = sizeof(Header) + desired_payload_capacity. | ||
// A new failure will cause a Resize failure... and caller should check | ||
// the return result for true (i.e., successful resizing). | ||
bool Resize(size_t new_capacity); | ||
|
||
// Moves the iterator by the given number of bytes. | ||
static void UpdateIter(void** iter, int bytes) { | ||
*iter = static_cast<char*>(*iter) + bytes; | ||
} | ||
|
||
// Initial size of the payload. | ||
static const int kInitialPayload = 1024; | ||
|
||
private: | ||
char* buffer_; | ||
size_t capacity_; // Allocation size of payload (or -1 if buffer is const). | ||
size_t length_; // current length of the buffer | ||
size_t variable_buffer_offset_; // IF non-zero, then offset to a buffer. | ||
}; | ||
|
||
} // namespace flip | ||
|
||
#endif // NET_FLIP_FRAME_BUILDER_H_ | ||
|
Oops, something went wrong.