Fast path reading (when the remaining bytes are sufficient)
(err *Error)
| 1329 | |
| 1330 | // Fast path reading (when the remaining bytes are sufficient) |
| 1331 | func (b *ByteBuffer) readVarUint32Fast(err *Error) uint32 { |
| 1332 | // Single instruction load using unsafe pointer cast (little-endian only) |
| 1333 | // On big-endian systems, use binary.LittleEndian which the compiler optimizes |
| 1334 | var bulk uint64 |
| 1335 | if isLittleEndian { |
| 1336 | bulk = *(*uint64)(unsafe.Pointer(&b.data[b.readerIndex])) |
| 1337 | } else { |
| 1338 | bulk = binary.LittleEndian.Uint64(b.data[b.readerIndex:]) |
| 1339 | } |
| 1340 | |
| 1341 | result := uint32(bulk & 0x7F) |
| 1342 | readLength := 1 |
| 1343 | |
| 1344 | if (bulk & 0x80) != 0 { |
| 1345 | result |= uint32((bulk >> 1) & 0x3F80) |
| 1346 | readLength = 2 |
| 1347 | if (bulk & 0x8000) != 0 { |
| 1348 | result |= uint32((bulk >> 2) & 0x1FC000) |
| 1349 | readLength = 3 |
| 1350 | if (bulk & 0x800000) != 0 { |
| 1351 | result |= uint32((bulk >> 3) & 0xFE00000) |
| 1352 | readLength = 4 |
| 1353 | if (bulk & 0x80000000) != 0 { |
| 1354 | fifth := byte(bulk >> 32) |
| 1355 | if fifth > 0x0F { |
| 1356 | if err != nil { |
| 1357 | *err = DeserializationError("VarUint32 overflow") |
| 1358 | } |
| 1359 | return 0 |
| 1360 | } |
| 1361 | result |= uint32((bulk >> 4) & 0xF0000000) |
| 1362 | readLength = 5 |
| 1363 | } |
| 1364 | } |
| 1365 | } |
| 1366 | } |
| 1367 | b.readerIndex += readLength |
| 1368 | return result |
| 1369 | } |
| 1370 | |
| 1371 | // Slow path reading (processing byte by byte) |
| 1372 | func (b *ByteBuffer) readVarUint32Slow(err *Error) uint32 { |
no test coverage detected