blob: 5d05e45614a312712e673387fbce0d8278557d58 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
#pragma once
#include <rocksdb/slice.h>
#include <unistd.h>
#include <cstdint>
#include <string>
enum class Endian {
LITTLE = __ORDER_LITTLE_ENDIAN__,
BIG = __ORDER_BIG_ENDIAN__,
NATIVE = __BYTE_ORDER__,
};
constexpr inline bool IsLittleEndian() { return Endian::NATIVE == Endian::LITTLE; }
constexpr inline bool IsBigEndian() { return Endian::NATIVE == Endian::BIG; }
constexpr inline uint8_t BitSwap(uint8_t x) { return x; }
constexpr inline uint16_t BitSwap(uint16_t x) { return __builtin_bswap16(x); }
constexpr inline uint32_t BitSwap(uint32_t x) { return __builtin_bswap32(x); }
constexpr inline uint64_t BitSwap(uint64_t x) { return __builtin_bswap64(x); }
template <typename T>
constexpr char *EncodeFixed(char *buf, T value) {
if constexpr (IsLittleEndian()) {
value = BitSwap(value);
}
__builtin_memcpy(buf, &value, sizeof(value));
return buf + sizeof(value);
}
inline char *EncodeFixed8(char *buf, uint8_t value) { return EncodeFixed(buf, value); }
inline char *EncodeFixed16(char *buf, uint16_t value) { return EncodeFixed(buf, value); }
inline char *EncodeFixed32(char *buf, uint32_t value) { return EncodeFixed(buf, value); }
inline char *EncodeFixed64(char *buf, uint64_t value) { return EncodeFixed(buf, value); }
inline char *EncodeBuffer(char *buf, rocksdb::Slice value) {
__builtin_memcpy(buf, value.data(), value.size());
return buf + value.size();
}
template <typename T>
void PutFixed(std::string *dst, T value) {
char buf[sizeof(value)];
EncodeFixed(buf, value);
dst->append(buf, sizeof(buf));
}
inline void PutFixed8(std::string *dst, uint8_t value) { PutFixed(dst, value); }
inline void PutFixed16(std::string *dst, uint16_t value) { PutFixed(dst, value); }
inline void PutFixed32(std::string *dst, uint32_t value) { PutFixed(dst, value); }
inline void PutFixed64(std::string *dst, uint64_t value) { PutFixed(dst, value); }
template <typename T>
constexpr T DecodeFixed(const char *ptr) {
T value = 0;
__builtin_memcpy(&value, ptr, sizeof(value));
return IsLittleEndian() ? BitSwap(value) : value;
}
inline uint8_t DecodeFixed8(const char *ptr) { return DecodeFixed<uint8_t>(ptr); }
inline uint16_t DecodeFixed16(const char *ptr) { return DecodeFixed<uint16_t>(ptr); }
inline uint32_t DecodeFixed32(const char *ptr) { return DecodeFixed<uint32_t>(ptr); }
inline uint64_t DecodeFixed64(const char *ptr) { return DecodeFixed<uint64_t>(ptr); }
template <typename T>
bool GetFixed(rocksdb::Slice *input, T *value) {
if (input->size() < sizeof(T)) return false;
*value = DecodeFixed<T>(input->data());
input->remove_prefix(sizeof(T));
return true;
}
inline bool GetFixed8(rocksdb::Slice *input, uint8_t *value) { return GetFixed(input, value); }
inline bool GetFixed16(rocksdb::Slice *input, uint16_t *value) { return GetFixed(input, value); }
inline bool GetFixed32(rocksdb::Slice *input, uint32_t *value) { return GetFixed(input, value); }
inline bool GetFixed64(rocksdb::Slice *input, uint64_t *value) { return GetFixed(input, value); }
inline void PutSizedString(std::string *dst, rocksdb::Slice value) {
PutFixed32(dst, value.size());
dst->append(value.ToStringView());
}
inline bool GetSizedString(rocksdb::Slice *input, rocksdb::Slice *value) {
uint32_t size = 0;
if (!GetFixed32(input, &size)) return false;
if (input->size() < size) return false;
*value = rocksdb::Slice(input->data(), size);
input->remove_prefix(size);
return true;
}
char *EncodeDouble(char *buf, double value);
void PutDouble(std::string *dst, double value);
double DecodeDouble(const char *ptr);
bool GetDouble(rocksdb::Slice *input, double *value);
char *EncodeVarint32(char *dst, uint32_t v);
void PutVarint32(std::string *dst, uint32_t v);
bool GetVarint32(rocksdb::Slice *input, uint32_t *value);