Reads a variable-length Long value. @param buf The buffer to read from. @return The value read.
(final ChannelBuffer buf)
| 1303 | * @return The value read. |
| 1304 | */ |
| 1305 | @SuppressWarnings("fallthrough") |
| 1306 | static long readVLong(final ChannelBuffer buf) { |
| 1307 | byte b = buf.readByte(); |
| 1308 | // Unless the first half of the first byte starts with 0xb1000, we're |
| 1309 | // dealing with a single-byte value. |
| 1310 | if ((b & 0xF0) != 0x80) { // 0xF0 = 0b11110000, 0x80 = 0b10000000 |
| 1311 | return b; |
| 1312 | } |
| 1313 | |
| 1314 | // The value is negative if the 5th bit is 0. |
| 1315 | final boolean negate = (b & 0x08) == 0; // 0x08 = 0b00001000 |
| 1316 | long result = 0; |
| 1317 | switch (b & 0x07) { // Look at the low 3 bits (the length). |
| 1318 | case 0x00: |
| 1319 | result = buf.readLong(); |
| 1320 | break; |
| 1321 | case 0x01: |
| 1322 | result = buf.readUnsignedInt(); |
| 1323 | result <<= 32; |
| 1324 | result |= buf.readUnsignedMedium(); |
| 1325 | break; |
| 1326 | case 0x02: |
| 1327 | result = buf.readUnsignedMedium(); |
| 1328 | result <<= 24; |
| 1329 | result |= buf.readUnsignedMedium(); |
| 1330 | break; |
| 1331 | case 0x03: |
| 1332 | b = buf.readByte(); |
| 1333 | result <<= 8; |
| 1334 | result |= b & 0xFF; |
| 1335 | case 0x04: |
| 1336 | result <<= 32; |
| 1337 | result |= buf.readUnsignedInt(); |
| 1338 | break; |
| 1339 | case 0x05: |
| 1340 | result |= buf.readUnsignedMedium(); |
| 1341 | break; |
| 1342 | case 0x06: |
| 1343 | result |= buf.readUnsignedShort(); |
| 1344 | break; |
| 1345 | case 0x07: |
| 1346 | b = buf.readByte(); |
| 1347 | result <<= 8; |
| 1348 | result |= b & 0xFF; |
| 1349 | } |
| 1350 | return negate ? ~result : result; |
| 1351 | } |
| 1352 | |
| 1353 | /** |
| 1354 | * Reads a 32-bit variable-length integer value as used in Protocol Buffers. |