Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 0.33.0 - 2025-04-15

### Enhancements
- Added `id` field to `LiveSubscription` requests, which will be used for improved error
messages
- Removed Windows-only `dirent` dependency

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

## 0.32.1 - 2025-04-07

### Bug fixes
Expand Down
14 changes: 1 addition & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.14)
# Project details
#

project("databento" VERSION 0.32.1 LANGUAGES CXX)
project("databento" VERSION 0.33.0 LANGUAGES CXX)
string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPERCASE)

#
Expand Down Expand Up @@ -225,18 +225,6 @@ else()
add_system_include_property(date)
endif()

#
# Platform-specific dependencies
#
if(WIN32)
find_path(
DIRENT_INCLUDE_DIR "dirent.h"
PATHS "${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include"
REQUIRED
)
target_include_directories(${PROJECT_NAME} PRIVATE ${DIRENT_INCLUDE_DIR})
endif()

target_link_libraries(
${PROJECT_NAME}
PUBLIC
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ You'll need to ensure the following dependencies are installed:
- [nlohmann\_json (header-only)](https://github.com/nlohmann/json)
- [cpp-httplib (header-only)](https://github.com/yhirose/cpp-httplib)
- [date (header-only)](https://github.com/HowardHinnant/date)
- [dirent (Windows-only, header-only)](https://github.com/tronkko/dirent)

By default, date, cpp-httplib and nlohmann\_json are downloaded by CMake as part of the build process.
If you would like to use a local version of these libraries, enable the CMake flag
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
Loading
Loading