summaryrefslogtreecommitdiff
path: root/chromium/net/quic/quic_data_writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/quic/quic_data_writer.cc')
-rw-r--r--chromium/net/quic/quic_data_writer.cc51
1 files changed, 51 insertions, 0 deletions
diff --git a/chromium/net/quic/quic_data_writer.cc b/chromium/net/quic/quic_data_writer.cc
index 61e72922365..b7aff26fe01 100644
--- a/chromium/net/quic/quic_data_writer.cc
+++ b/chromium/net/quic/quic_data_writer.cc
@@ -56,6 +56,45 @@ bool QuicDataWriter::WriteUInt64(uint64 value) {
return WriteBytes(&value, sizeof(value));
}
+bool QuicDataWriter::WriteUFloat16(uint64 value) {
+ uint16 result;
+ if (value < (GG_UINT64_C(1) << kUFloat16MantissaEffectiveBits)) {
+ // Fast path: either the value is denormalized, or has exponent zero.
+ // Both cases are represented by the value itself.
+ result = value;
+ } else if (value >= kUFloat16MaxValue) {
+ // Value is out of range; clamp it to the maximum representable.
+ result = numeric_limits<uint16>::max();
+ } else {
+ // The highest bit is between position 13 and 42 (zero-based), which
+ // corresponds to exponent 1-30. In the output, mantissa is from 0 to 10,
+ // hidden bit is 11 and exponent is 11 to 15. Shift the highest bit to 11
+ // and count the shifts.
+ uint16 exponent = 0;
+ for (uint16 offset = 16; offset > 0; offset /= 2) {
+ // Right-shift the value until the highest bit is in position 11.
+ // For offset of 16, 8, 4, 2 and 1 (binary search over 1-30),
+ // shift if the bit is at or above 11 + offset.
+ if (value >= (GG_UINT64_C(1) << (kUFloat16MantissaBits + offset))) {
+ exponent += offset;
+ value >>= offset;
+ }
+ }
+
+ DCHECK_GE(exponent, 1);
+ DCHECK_LE(exponent, kUFloat16MaxExponent);
+ DCHECK_GE(value, GG_UINT64_C(1) << kUFloat16MantissaBits);
+ DCHECK_LT(value, GG_UINT64_C(1) << kUFloat16MantissaEffectiveBits);
+
+ // Hidden bit (position 11) is set. We should remove it and increment the
+ // exponent. Equivalently, we just add it to the exponent.
+ // This hides the bit.
+ result = value + (exponent << kUFloat16MantissaBits);
+ }
+
+ return WriteBytes(&result, sizeof(result));
+}
+
bool QuicDataWriter::WriteStringPiece16(StringPiece val) {
if (val.length() > numeric_limits<uint16>::max()) {
return false;
@@ -66,6 +105,18 @@ bool QuicDataWriter::WriteStringPiece16(StringPiece val) {
return WriteBytes(val.data(), val.size());
}
+bool QuicDataWriter::WriteIOVector(const IOVector& data) {
+ char *dest = BeginWrite(data.TotalBufferSize());
+ if (!dest) {
+ return false;
+ }
+ for (size_t i = 0; i < data.Size(); ++i) {
+ WriteBytes(data.iovec()[i].iov_base, data.iovec()[i].iov_len);
+ }
+
+ return true;
+}
+
char* QuicDataWriter::BeginWrite(size_t length) {
if (length_ > capacity_) {
return NULL;