| Index: net/quic/quic_data_writer.cc
|
| diff --git a/net/quic/quic_data_writer.cc b/net/quic/quic_data_writer.cc
|
| index 61e729223652d3f620878a8f7ec64dbf110ffeda..65ce7bee998d5d54e21a925de0a2691924e78ac4 100644
|
| --- a/net/quic/quic_data_writer.cc
|
| +++ b/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;
|
|
|