Decode reads the next custom-encoded value from its reader and returns it.
()
| 363 | |
| 364 | // Decode reads the next custom-encoded value from its reader and returns it. |
| 365 | func (dec *WALDecoder) Decode() (*TimedWALMessage, error) { |
| 366 | b := make([]byte, 4) |
| 367 | |
| 368 | _, err := dec.rd.Read(b) |
| 369 | if errors.Is(err, io.EOF) { |
| 370 | return nil, err |
| 371 | } |
| 372 | if err != nil { |
| 373 | return nil, DataCorruptionError{fmt.Errorf("failed to read checksum: %v", err)} |
| 374 | } |
| 375 | crc := binary.BigEndian.Uint32(b) |
| 376 | |
| 377 | b = make([]byte, 4) |
| 378 | _, err = dec.rd.Read(b) |
| 379 | if err != nil { |
| 380 | return nil, DataCorruptionError{fmt.Errorf("failed to read length: %v", err)} |
| 381 | } |
| 382 | length := binary.BigEndian.Uint32(b) |
| 383 | |
| 384 | if length > maxMsgSizeBytes { |
| 385 | return nil, DataCorruptionError{fmt.Errorf( |
| 386 | "length %d exceeded maximum possible value of %d bytes", |
| 387 | length, |
| 388 | maxMsgSizeBytes)} |
| 389 | } |
| 390 | |
| 391 | data := make([]byte, length) |
| 392 | n, err := dec.rd.Read(data) |
| 393 | if err != nil { |
| 394 | return nil, DataCorruptionError{fmt.Errorf("failed to read data: %v (read: %d, wanted: %d)", err, n, length)} |
| 395 | } |
| 396 | |
| 397 | // check checksum before decoding data |
| 398 | actualCRC := crc32.Checksum(data, crc32c) |
| 399 | if actualCRC != crc { |
| 400 | return nil, DataCorruptionError{fmt.Errorf("checksums do not match: read: %v, actual: %v", crc, actualCRC)} |
| 401 | } |
| 402 | |
| 403 | var res = new(tmcons.TimedWALMessage) |
| 404 | err = proto.Unmarshal(data, res) |
| 405 | if err != nil { |
| 406 | return nil, DataCorruptionError{fmt.Errorf("failed to decode data: %v", err)} |
| 407 | } |
| 408 | |
| 409 | walMsg, err := WALFromProto(res.Msg) |
| 410 | if err != nil { |
| 411 | return nil, DataCorruptionError{fmt.Errorf("failed to convert from proto: %w", err)} |
| 412 | } |
| 413 | tMsgWal := &TimedWALMessage{ |
| 414 | Time: res.Time, |
| 415 | Msg: walMsg, |
| 416 | } |
| 417 | |
| 418 | return tMsgWal, err |
| 419 | } |
| 420 | |
| 421 | type nilWAL struct{} |
| 422 |