blob: adf19990fda9c3595397d7e7c3dd74c014842041 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdint.h>
#include <iosfwd>
#include "garnet/lib/overnet/vocabulary/status.h"
namespace overnet {
// A sequence number
class SeqNum {
public:
static constexpr size_t kMaxWireLength = 4;
// Construct with the sequence number and the number of outstanding messages
// in the same stream - the wire representation will be scaled such that the
// correct sequence number is unambiguous.
SeqNum(uint64_t seq, uint64_t outstanding_messages);
static StatusOr<SeqNum> Parse(const uint8_t** bytes, const uint8_t* end);
static bool IsOutstandingMessagesLegal(uint64_t outstanding_messages) {
return outstanding_messages < (1 << 28);
}
size_t wire_length() const { return (rep_[0] >> 6) + 1; }
uint8_t* Write(uint8_t* dst) const {
memcpy(dst, rep_, wire_length());
return dst + wire_length();
}
std::string ToString() const;
uint64_t Reconstruct(uint64_t window_base) const;
// Helper to make writing mocks easier.
uint64_t ReconstructFromZero_TestOnly() const { return Reconstruct(0); }
bool operator==(const SeqNum& rhs) const {
return wire_length() == rhs.wire_length() &&
0 == memcmp(rep_, rhs.rep_, wire_length());
}
bool operator!=(const SeqNum& rhs) const { return !operator==(rhs); }
private:
SeqNum() {}
uint8_t rep_[kMaxWireLength];
};
std::ostream& operator<<(std::ostream& out, SeqNum seq_num);
} // namespace overnet