Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.33.0 - TBD

### Enhancements
- Added `id` field to `LiveSubscription` requests, which will be used for improved error
messages

### Breaking changes
- Changed `DbnDecoder`, `FileStream`, `IReadable`, `IWritable` to work on `byte`s

## 0.32.1 - 2025-04-07

### Bug fixes
Expand Down
4 changes: 2 additions & 2 deletions include/databento/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ static constexpr auto kSymbolCstrLen = 71;
// The multiplier for converting the `length` field in `RecordHeader` to bytes.
static constexpr std::size_t kRecordHeaderLengthMultiplier = 4;

// This is not necessarily a comprehensive list of available datasets. Please
// use `Historical.MetadataListDatasets` to retrieve an up-to-date list.
// This is not a comprehensive list of datasets, for that see the `Dataset`
// enum.
namespace dataset {
// The dataset code for Databento Equities Basic.
static constexpr auto kDbeqBasic = "DBEQ.BASIC";
Expand Down
25 changes: 12 additions & 13 deletions include/databento/dbn_decoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ class DbnDecoder {
VersionUpgradePolicy upgrade_policy);

static std::pair<std::uint8_t, std::size_t> DecodeMetadataVersionAndSize(
const std::uint8_t* buffer, std::size_t size);
const std::byte* buffer, std::size_t size);
static Metadata DecodeMetadataFields(std::uint8_t version,
const std::vector<std::uint8_t>& buffer);
const std::vector<std::byte>& buffer);
// Decodes a record possibly applying upgrading the data according to the
// given version and upgrade policy. If an upgrade is applied,
// compat_buffer is modified.
static Record DecodeRecordCompat(
std::uint8_t version, VersionUpgradePolicy upgrade_policy, bool ts_out,
std::array<std::uint8_t, kMaxRecordLen>* compat_buffer, Record rec);
std::array<std::byte, kMaxRecordLen>* compat_buffer, Record rec);

// Should be called exactly once.
Metadata DecodeMetadata();
Expand All @@ -44,19 +44,19 @@ class DbnDecoder {
private:
static std::string DecodeSymbol(
std::size_t symbol_cstr_len,
std::vector<std::uint8_t>::const_iterator& buffer_it);
std::vector<std::byte>::const_iterator& buffer_it);
static std::vector<std::string> DecodeRepeatedSymbol(
std::size_t symbol_cstr_len,
std::vector<std::uint8_t>::const_iterator& buffer_it,
std::vector<std::uint8_t>::const_iterator buffer_end_it);
std::vector<std::byte>::const_iterator& buffer_it,
std::vector<std::byte>::const_iterator buffer_end_it);
static std::vector<SymbolMapping> DecodeSymbolMappings(
std::size_t symbol_cstr_len,
std::vector<std::uint8_t>::const_iterator& buffer_it,
std::vector<std::uint8_t>::const_iterator buffer_end_it);
std::vector<std::byte>::const_iterator& buffer_it,
std::vector<std::byte>::const_iterator buffer_end_it);
static SymbolMapping DecodeSymbolMapping(
std::size_t symbol_cstr_len,
std::vector<std::uint8_t>::const_iterator& buffer_it,
std::vector<std::uint8_t>::const_iterator buffer_end_it);
std::vector<std::byte>::const_iterator& buffer_it,
std::vector<std::byte>::const_iterator buffer_end_it);
bool DetectCompression();
std::size_t FillBuffer();
std::size_t GetReadBufferSize() const;
Expand All @@ -67,11 +67,10 @@ class DbnDecoder {
VersionUpgradePolicy upgrade_policy_;
bool ts_out_{};
std::unique_ptr<IReadable> input_;
std::vector<std::uint8_t> read_buffer_;
std::vector<std::byte> read_buffer_;
std::size_t buffer_idx_{};
// Must be 8-byte aligned for records
alignas(
RecordHeader) std::array<std::uint8_t, kMaxRecordLen> compat_buffer_{};
alignas(RecordHeader) std::array<std::byte, kMaxRecordLen> compat_buffer_{};
Record current_record_{nullptr};
};
} // namespace databento
57 changes: 29 additions & 28 deletions include/databento/detail/json_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <map> // multimap
#include <string>
#include <string_view>
#include <vector>

#include "databento/datetime.hpp" // UnixNanos
Expand All @@ -22,7 +23,7 @@ void SetIfNotEmpty(httplib::Params* params, const std::string& key,
const std::vector<databento::JobState>& states);

template <typename T>
void SetIfPositive(httplib::Params* params, const std::string& key,
void SetIfPositive(httplib::Params* params, std::string_view key,
const T value) {
if (value > 0) {
params->emplace(key, std::to_string(value));
Expand All @@ -31,30 +32,31 @@ void SetIfPositive(httplib::Params* params, const std::string& key,

template <>
inline void SetIfPositive<databento::UnixNanos>(
httplib::Params* params, const std::string& key,
httplib::Params* params, std::string_view key,
const databento::UnixNanos value) {
if (value.time_since_epoch().count()) {
params->emplace(key, databento::ToString(value));
}
}

const nlohmann::json& CheckedAt(const std::string& endpoint,
const nlohmann::json& CheckedAt(std::string_view endpoint,
const nlohmann::json& json,
const std::string& key);
std::string_view key);

template <typename T>
T FromCheckedAtString(const std::string& endpoint, const nlohmann::json& json,
const std::string& key) {
T FromCheckedAtString(std::string_view endpoint, const nlohmann::json& json,
std::string_view key) {
const auto& val_json = CheckedAt(endpoint, json, key);
if (!val_json.is_string()) {
throw JsonResponseError::TypeMismatch(endpoint, key + " string", val_json);
throw JsonResponseError::TypeMismatch(
endpoint, std::string{key} + " string", val_json);
}
return databento::FromString<T>(val_json);
}

template <typename T>
T FromCheckedAtStringOrNull(const std::string& endpoint,
const nlohmann::json& json, const std::string& key,
T FromCheckedAtStringOrNull(std::string_view endpoint,
const nlohmann::json& json, std::string_view key,
T null_value) {
const auto& val_json = CheckedAt(endpoint, json, key);
if (val_json.is_null()) {
Expand All @@ -63,35 +65,34 @@ T FromCheckedAtStringOrNull(const std::string& endpoint,
if (val_json.is_string()) {
return databento::FromString<T>(val_json);
}
throw JsonResponseError::TypeMismatch(endpoint, key + " null or string",
val_json);
throw JsonResponseError::TypeMismatch(
endpoint, std::string{key} + " null or string", val_json);
}

template <typename T>
T ParseAt(const std::string& endpoint, const nlohmann::json& json,
const std::string& key);
T ParseAt(std::string_view endpoint, const nlohmann::json& json,
std::string_view key);
template <>
bool ParseAt(const std::string& endpoint, const nlohmann::json& json,
const std::string& key);
bool ParseAt(std::string_view endpoint, const nlohmann::json& json,
std::string_view key);
template <>
std::string ParseAt(const std::string& endpoint, const nlohmann::json& json,
const std::string& key);
std::string ParseAt(std::string_view endpoint, const nlohmann::json& json,
std::string_view key);
template <>
std::uint64_t ParseAt(const std::string& endpoint, const nlohmann::json& json,
const std::string& key);
std::uint64_t ParseAt(std::string_view endpoint, const nlohmann::json& json,
std::string_view key);
template <>
std::uint16_t ParseAt(const std::string& endpoint, const nlohmann::json& json,
const std::string& key);
std::uint16_t ParseAt(std::string_view endpoint, const nlohmann::json& json,
std::string_view key);
template <>
double ParseAt(const std::string& endpoint, const nlohmann::json& json,
const std::string& key);
double ParseAt(std::string_view endpoint, const nlohmann::json& json,
std::string_view key);
template <>
std::vector<std::string> ParseAt(const std::string& endpoint,
std::vector<std::string> ParseAt(std::string_view endpoint,
const nlohmann::json& json,
const std::string& key);
std::string_view key);
template <>
date::year_month_day ParseAt(const std::string& endpoint,
const nlohmann::json& json,
const std::string& key);
date::year_month_day ParseAt(std::string_view endpoint,
const nlohmann::json& json, std::string_view key);

} // namespace databento::detail
9 changes: 4 additions & 5 deletions include/databento/detail/shared_channel.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <cstddef> // size_t
#include <cstdint> // uint8_t
#include <cstddef> // byte, size_t
#include <memory> // shared_ptr

#include "databento/ireadable.hpp"
Expand All @@ -13,14 +12,14 @@ class SharedChannel : public IReadable {
SharedChannel();

// Write `data` of `length` bytes to the channel.
void Write(const std::uint8_t* data, std::size_t length);
void Write(const std::byte* data, std::size_t length);
// Signal the end of input.
void Finish();
// Read exactly `length` bytes.
void ReadExact(std::uint8_t* buffer, std::size_t length) override;
void ReadExact(std::byte* buffer, std::size_t length) override;
// Read at most `length` bytes. Returns the number of bytes read. Will only
// return 0 if the end of the stream is reached.
std::size_t ReadSome(std::uint8_t* buffer, std::size_t length) override;
std::size_t ReadSome(std::byte* buffer, std::size_t length) override;

private:
class Channel;
Expand Down
12 changes: 7 additions & 5 deletions include/databento/detail/tcp_client.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#pragma once

#include <chrono> // milliseconds
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>

#include "databento/detail/scoped_fd.hpp" // ScopedFd

Expand All @@ -29,13 +31,13 @@ class TcpClient {
TcpClient(const std::string& gateway, std::uint16_t port,
RetryConf retry_conf);

void WriteAll(const std::string& str);
void WriteAll(const char* buffer, std::size_t size);
void ReadExact(char* buffer, std::size_t size);
Result ReadSome(char* buffer, std::size_t max_size);
void WriteAll(std::string_view str);
void WriteAll(const std::byte* buffer, std::size_t size);
void ReadExact(std::byte* buffer, std::size_t size);
Result ReadSome(std::byte* buffer, std::size_t max_size);
// Passing a timeout of 0 will block until data is available of the socket is
// closed, the same behavior as the Read overload without a timeout.
Result ReadSome(char* buffer, std::size_t max_size,
Result ReadSome(std::byte* buffer, std::size_t max_size,
std::chrono::milliseconds timeout);
// Closes the socket.
void Close();
Expand Down
15 changes: 7 additions & 8 deletions include/databento/detail/zstd_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <zstd.h>

#include <cstddef> // size_t
#include <cstdint> // uint8_t
#include <memory> // unique_ptr
#include <vector>

Expand All @@ -16,19 +15,19 @@ class ZstdDecodeStream : public IReadable {
public:
explicit ZstdDecodeStream(std::unique_ptr<IReadable> input);
ZstdDecodeStream(std::unique_ptr<IReadable> input,
std::vector<std::uint8_t>&& in_buffer);
std::vector<std::byte>&& in_buffer);

// Read exactly `length` bytes into `buffer`.
void ReadExact(std::uint8_t* buffer, std::size_t length) override;
void ReadExact(std::byte* buffer, std::size_t length) override;
// Read at most `length` bytes. Returns the number of bytes read. Will only
// return 0 if the end of the stream is reached.
std::size_t ReadSome(std::uint8_t* buffer, std::size_t max_length) override;
std::size_t ReadSome(std::byte* buffer, std::size_t max_length) override;

private:
std::unique_ptr<IReadable> input_;
std::unique_ptr<ZSTD_DStream, std::size_t (*)(ZSTD_DStream*)> z_dstream_;
std::size_t read_suggestion_;
std::vector<std::uint8_t> in_buffer_;
std::vector<std::byte> in_buffer_;
ZSTD_inBuffer z_in_buffer_;
};

Expand All @@ -42,15 +41,15 @@ class ZstdCompressStream : public IWritable {
ZstdCompressStream& operator=(ZstdCompressStream&&) = delete;
~ZstdCompressStream() override;

void WriteAll(const std::uint8_t* buffer, std::size_t length) override;
void WriteAll(const std::byte* buffer, std::size_t length) override;

private:
ILogReceiver* log_receiver_;
IWritable* output_;
std::unique_ptr<ZSTD_CStream, std::size_t (*)(ZSTD_CStream*)> z_cstream_;
std::vector<std::uint8_t> in_buffer_;
std::vector<std::byte> in_buffer_;
ZSTD_inBuffer z_in_buffer_;
std::size_t in_size_;
std::vector<std::uint8_t> out_buffer_;
std::vector<std::byte> out_buffer_;
};
} // namespace databento::detail
30 changes: 15 additions & 15 deletions include/databento/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <cstdint>
#include <exception>
#include <string>
#include <string_view>
#include <utility> // move

namespace databento {
Expand All @@ -32,7 +33,7 @@ class HttpRequestError : public Exception {
httplib::Error ErrorCode() const { return error_code_; }

private:
static std::string BuildMessage(const std::string& request_path,
static std::string BuildMessage(std::string_view request_path,
httplib::Error error_code);

const std::string request_path_;
Expand All @@ -55,9 +56,9 @@ class HttpResponseError : public Exception {
const std::string& ResponseBody() const { return response_body_; }

private:
static std::string BuildMessage(const std::string& request_path,
static std::string BuildMessage(std::string_view request_path,
std::int32_t status_code,
const std::string& response_body);
std::string_view response_body);

const std::string request_path_;
// int32 is the representation used by httplib
Expand Down Expand Up @@ -95,9 +96,9 @@ class InvalidArgumentError : public Exception {
const std::string& Details() const { return details_; }

private:
static std::string BuildMessage(const std::string& method_name,
const std::string& param_name,
const std::string& details);
static std::string BuildMessage(std::string_view method_name,
std::string_view param_name,
std::string_view details);

const std::string method_name_;
const std::string param_name_;
Expand All @@ -108,15 +109,14 @@ class InvalidArgumentError : public Exception {
class JsonResponseError : public Exception {
public:
static JsonResponseError ParseError(
const std::string& path,
const nlohmann::detail::parse_error& parse_error);
static JsonResponseError MissingKey(const std::string& method_name,
std::string_view path, const nlohmann::detail::parse_error& parse_error);
static JsonResponseError MissingKey(std::string_view method_name,
const nlohmann::json& key);
static JsonResponseError TypeMismatch(const std::string& method_name,
const std::string& expected_type_name,
static JsonResponseError TypeMismatch(std::string_view method_name,
std::string_view expected_type_name,
const nlohmann::json& json);
static JsonResponseError TypeMismatch(const std::string& method_name,
const std::string& expected_type_name,
static JsonResponseError TypeMismatch(std::string_view method_name,
std::string_view expected_type_name,
const nlohmann::json& key,
const nlohmann::json& value);

Expand All @@ -138,7 +138,7 @@ class LiveApiError : public Exception {
public:
explicit LiveApiError(std::string message) : Exception{std::move(message)} {}

static LiveApiError UnexpectedMsg(const std::string& message,
const std::string& response);
static LiveApiError UnexpectedMsg(std::string_view message,
std::string_view response);
};
} // namespace databento
Loading
Loading