OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_data_writer.h" | 5 #include "net/quic/quic_data_writer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 bool QuicDataWriter::WriteUInt48(uint64 value) { | 49 bool QuicDataWriter::WriteUInt48(uint64 value) { |
50 uint32 hi = value >> 32; | 50 uint32 hi = value >> 32; |
51 uint32 lo = value & GG_UINT64_C(0x00000000FFFFFFFF); | 51 uint32 lo = value & GG_UINT64_C(0x00000000FFFFFFFF); |
52 return WriteUInt32(lo) && WriteUInt16(hi); | 52 return WriteUInt32(lo) && WriteUInt16(hi); |
53 } | 53 } |
54 | 54 |
55 bool QuicDataWriter::WriteUInt64(uint64 value) { | 55 bool QuicDataWriter::WriteUInt64(uint64 value) { |
56 return WriteBytes(&value, sizeof(value)); | 56 return WriteBytes(&value, sizeof(value)); |
57 } | 57 } |
58 | 58 |
| 59 bool QuicDataWriter::WriteUFloat16(uint64 value) { |
| 60 uint16 result; |
| 61 if (value < (GG_UINT64_C(1) << kUFloat16MantissaEffectiveBits)) { |
| 62 // Fast path: either the value is denormalized, or has exponent zero. |
| 63 // Both cases are represented by the value itself. |
| 64 result = value; |
| 65 } else if (value >= kUFloat16MaxValue) { |
| 66 // Value is out of range; clamp it to the maximum representable. |
| 67 result = numeric_limits<uint16>::max(); |
| 68 } else { |
| 69 // The highest bit is between position 13 and 42 (zero-based), which |
| 70 // corresponds to exponent 1-30. In the output, mantissa is from 0 to 10, |
| 71 // hidden bit is 11 and exponent is 11 to 15. Shift the highest bit to 11 |
| 72 // and count the shifts. |
| 73 uint16 exponent = 0; |
| 74 for (uint16 offset = 16; offset > 0; offset /= 2) { |
| 75 // Right-shift the value until the highest bit is in position 11. |
| 76 // For offset of 16, 8, 4, 2 and 1 (binary search over 1-30), |
| 77 // shift if the bit is at or above 11 + offset. |
| 78 if (value >= (GG_UINT64_C(1) << (kUFloat16MantissaBits + offset))) { |
| 79 exponent += offset; |
| 80 value >>= offset; |
| 81 } |
| 82 } |
| 83 |
| 84 DCHECK_GE(exponent, 1); |
| 85 DCHECK_LE(exponent, kUFloat16MaxExponent); |
| 86 DCHECK_GE(value, GG_UINT64_C(1) << kUFloat16MantissaBits); |
| 87 DCHECK_LT(value, GG_UINT64_C(1) << kUFloat16MantissaEffectiveBits); |
| 88 |
| 89 // Hidden bit (position 11) is set. We should remove it and increment the |
| 90 // exponent. Equivalently, we just add it to the exponent. |
| 91 // This hides the bit. |
| 92 result = value + (exponent << kUFloat16MantissaBits); |
| 93 } |
| 94 |
| 95 return WriteBytes(&result, sizeof(result)); |
| 96 } |
| 97 |
59 bool QuicDataWriter::WriteStringPiece16(StringPiece val) { | 98 bool QuicDataWriter::WriteStringPiece16(StringPiece val) { |
60 if (val.length() > numeric_limits<uint16>::max()) { | 99 if (val.length() > numeric_limits<uint16>::max()) { |
61 return false; | 100 return false; |
62 } | 101 } |
63 if (!WriteUInt16(val.size())) { | 102 if (!WriteUInt16(val.size())) { |
64 return false; | 103 return false; |
65 } | 104 } |
66 return WriteBytes(val.data(), val.size()); | 105 return WriteBytes(val.data(), val.size()); |
67 } | 106 } |
68 | 107 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 DCHECK_LT(offset, capacity_); | 178 DCHECK_LT(offset, capacity_); |
140 size_t latched_length = length_; | 179 size_t latched_length = length_; |
141 length_ = offset; | 180 length_ = offset; |
142 bool success = WriteUInt48(value); | 181 bool success = WriteUInt48(value); |
143 DCHECK_LE(length_, latched_length); | 182 DCHECK_LE(length_, latched_length); |
144 length_ = latched_length; | 183 length_ = latched_length; |
145 return success; | 184 return success; |
146 } | 185 } |
147 | 186 |
148 } // namespace net | 187 } // namespace net |
OLD | NEW |