diff options
Diffstat (limited to 'chromium/net/quic/quic_data_writer.cc')
-rw-r--r-- | chromium/net/quic/quic_data_writer.cc | 51 |
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; |