bool Protocol::decodeCheckpoints()

in Protocol.cpp [226:268]


bool Protocol::decodeCheckpoints(int protocolVersion, char *src, int64_t &off,
                                 int64_t max,
                                 std::vector<Checkpoint> &checkpoints) {
  ByteRange br = makeByteRange(src, max, off);  // will check for off>0 max>0
  const ByteRange obr = br;
  uint64_t len;
  bool ok = decodeUInt64(br, len);
  for (uint64_t i = 0; ok && i < len; i++) {
    Checkpoint checkpoint;
    ok = decodeInt32C(br, checkpoint.port) &&
         decodeInt64C(br, checkpoint.numBlocks);
    if (ok && protocolVersion >= CHECKPOINT_OFFSET_VERSION) {
      ok = decodeInt64C(br, checkpoint.lastBlockReceivedBytes);
    }
    if (ok && protocolVersion >= CHECKPOINT_SEQ_ID_VERSION) {
      // Deal with -1 encoded by pre 1.27 version
      uint64_t uv = 0;
      ok = decodeUInt64(br, uv);
      checkpoint.lastBlockSeqId = static_cast<int64_t>(uv);
      if (ok && protocolVersion < VARINT_CHANGE) {
        // pre 1.27 encodes -1 for invalid and use 9 0xff bytes and 1 0x01 byte
        // 1.27+ decodes the 9 0xff as max uint64_t (all FFs) so we check and
        // consume the leftover 0x01
        if (uv == 0xffffffffffffffff && !br.empty()) {
          if (br.front() != 0x01) {
            WLOG(ERROR) << "Unexpected decoding of pre1.27 -1 : " << br.front();
            ok = false;
          }
          br.advance(1);  // 1.26 used 10 bytes
          WLOG(INFO) << "Fixed v" << protocolVersion << " chkpt to -1 seqid";
          checkpoint.lastBlockSeqId = -1;
        }
      }
      ok = ok && decodeInt64C(br, checkpoint.lastBlockOffset);
      checkpoint.hasSeqId = true;
    }
    if (ok) {
      checkpoints.emplace_back(checkpoint);
    }
  }
  off += offset(br, obr);
  return ok;
}