blob: 19ca3286a28df7fbf40f0fd8dad885e12cf2c4e6 [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 "src/connectivity/overnet/lib/vocabulary/slice.h"
#include "src/connectivity/overnet/lib/vocabulary/status.h"
// Utilities to encode/decode slices via some codec.
//
// The general encoded format is:
// (codec type : u8) (encoded bytes)
namespace overnet {
// Collection of functions that define a single codec.
struct CodecVTable {
const char* const name;
Border (*border_for_source_size)(size_t size);
StatusOr<Slice> (*encode)(Slice slice);
StatusOr<Slice> (*decode)(Slice slice);
};
// Mapping from codec identifying byte to the codec implementation.
extern const CodecVTable* const kCodecVtable[256];
// Currently named codecs. Future implementations may expand this.
enum class Coding : uint8_t {
Identity = 0,
Snappy = 1,
};
// Given a coding and a size, how much border should be allocated for a message?
inline Border BorderForSourceSize(Coding coding, size_t size) {
return kCodecVtable[static_cast<uint8_t>(coding)]
->border_for_source_size(size)
.WithAddedPrefix(1);
}
// Given a coding enum, get a name for the codec (or 'Unknown')
inline const char* CodingName(Coding coding) {
return kCodecVtable[static_cast<uint8_t>(coding)]->name;
}
class SliceCodingOracle {
public:
SliceCodingOracle& SetSize(size_t size) {
size_ = size;
return *this;
}
Coding SuggestCoding();
private:
Optional<size_t> size_;
};
// Encode some data with a pre-selected coding.
StatusOr<Slice> Encode(Coding coding, Slice slice);
// Decode an encoded slice.
StatusOr<Slice> Decode(Slice slice);
// Encode some data with an auto-selected coding.
inline StatusOr<Slice> Encode(Slice slice) {
return Encode(SliceCodingOracle().SetSize(slice.length()).SuggestCoding(),
slice);
}
} // namespace overnet