Skip to content

Commit

Permalink
Standalone 5/N: Implement and test ZarrStream_s (#297)
Browse files Browse the repository at this point in the history
Depends on #295
  • Loading branch information
aliddell authored Sep 26, 2024
1 parent 0658371 commit 16c553f
Show file tree
Hide file tree
Showing 12 changed files with 1,003 additions and 4 deletions.
8 changes: 4 additions & 4 deletions include/acquire.zarr.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ extern "C"

/**
* @brief Get the version of the Zarr API.
* @return The version of the Zarr API.
* @return Semver formatted version of the Zarr API.
*/
uint32_t Zarr_get_api_version();
const char* Zarr_get_api_version();

/**
* @brief Set the log level for the Zarr API.
Expand All @@ -58,10 +58,10 @@ extern "C"

/**
* @brief Get the message for the given status code.
* @param status The status code.
* @param code The status code.
* @return A human-readable status message.
*/
const char* Zarr_get_status_message(ZarrStatusCode status);
const char* Zarr_get_status_message(ZarrStatusCode code);

/**
* @brief Allocate memory for the dimension array in the Zarr stream settings struct.
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
add_subdirectory(logger)
add_subdirectory(streaming)

if (BUILD_ACQUIRE_DRIVER_ZARR)
add_subdirectory(driver)
endif ()
4 changes: 4 additions & 0 deletions src/logger/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ std::mutex Logger::log_mutex_{};
void
Logger::set_log_level(LogLevel level)
{
if (level < LogLevel_Debug || level > LogLevel_Error) {
throw std::invalid_argument("Invalid log level");
}

current_level_ = level;
}

Expand Down
40 changes: 40 additions & 0 deletions src/streaming/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
set(tgt acquire-zarr)

add_library(${tgt}
macros.hh
acquire.zarr.cpp
zarr.stream.hh
zarr.stream.cpp
)

target_include_directories(${tgt}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/logger>
)

target_link_libraries(${tgt} PRIVATE
acquire-logger
blosc_static
miniocpp::miniocpp
)

target_compile_definitions(${tgt} PRIVATE
"ACQUIRE_ZARR_API_VERSION=\"0.0.1\""
)

set_target_properties(${tgt} PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

install(TARGETS ${tgt}
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)

# Install public header files
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/
DESTINATION include
)
169 changes: 169 additions & 0 deletions src/streaming/acquire.zarr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#include "acquire.zarr.h"
#include "zarr.stream.hh"
#include "macros.hh"

#include <cstdint> // uint32_t

extern "C"
{
const char* Zarr_get_api_version()
{
return ACQUIRE_ZARR_API_VERSION;
}

ZarrStatusCode Zarr_set_log_level(ZarrLogLevel level_)
{
LogLevel level;
switch (level_) {
case ZarrLogLevel_Debug:
level = LogLevel_Debug;
break;
case ZarrLogLevel_Info:
level = LogLevel_Info;
break;
case ZarrLogLevel_Warning:
level = LogLevel_Warning;
break;
case ZarrLogLevel_Error:
level = LogLevel_Error;
break;
default:
return ZarrStatusCode_InvalidArgument;
}

try {
Logger::set_log_level(level);
} catch (const std::exception& e) {
LOG_ERROR("Error setting log level: %s", e.what());
return ZarrStatusCode_InternalError;
}
return ZarrStatusCode_Success;
}

ZarrLogLevel Zarr_get_log_level()
{
ZarrLogLevel level;
switch (Logger::get_log_level()) {
case LogLevel_Debug:
level = ZarrLogLevel_Debug;
break;
case LogLevel_Info:
level = ZarrLogLevel_Info;
break;
case LogLevel_Warning:
level = ZarrLogLevel_Warning;
break;
default:
level = ZarrLogLevel_Error;
break;
}
return level;
}

const char* Zarr_get_status_message(ZarrStatusCode code)
{
switch (code) {
case ZarrStatusCode_Success:
return "Success";
case ZarrStatusCode_InvalidArgument:
return "Invalid argument";
case ZarrStatusCode_Overflow:
return "Buffer overflow";
case ZarrStatusCode_InvalidIndex:
return "Invalid index";
case ZarrStatusCode_NotYetImplemented:
return "Not yet implemented";
case ZarrStatusCode_InternalError:
return "Internal error";
case ZarrStatusCode_OutOfMemory:
return "Out of memory";
case ZarrStatusCode_IOError:
return "I/O error";
case ZarrStatusCode_CompressionError:
return "Compression error";
case ZarrStatusCode_InvalidSettings:
return "Invalid settings";
default:
return "Unknown error";
}
}

ZarrStatusCode ZarrStreamSettings_create_dimension_array(
struct ZarrStreamSettings_s* settings,
size_t dimension_count)
{
EXPECT_VALID_ARGUMENT(settings, "Null pointer: settings");
EXPECT_VALID_ARGUMENT(dimension_count >= 3,
"Invalid dimension count: %zu",
dimension_count);

ZarrDimensionProperties* dimensions = nullptr;

try {
dimensions = new ZarrDimensionProperties[dimension_count];
} catch (const std::bad_alloc&) {
LOG_ERROR("Failed to allocate memory for dimensions");
return ZarrStatusCode_OutOfMemory;
}

ZarrStreamSettings_destroy_dimension_array(settings);
settings->dimensions = dimensions;
settings->dimension_count = dimension_count;

return ZarrStatusCode_Success;
}

void ZarrStreamSettings_destroy_dimension_array(
struct ZarrStreamSettings_s* settings)
{
if (settings == nullptr) {
return;
}

if (settings->dimensions != nullptr) {
delete[] settings->dimensions;
settings->dimensions = nullptr;
}
settings->dimension_count = 0;
}

ZarrStream_s* ZarrStream_create(struct ZarrStreamSettings_s* settings)
{

ZarrStream_s* stream = nullptr;

try {
stream = new ZarrStream_s(settings);
} catch (const std::bad_alloc&) {
LOG_ERROR("Failed to allocate memory for Zarr stream");
} catch (const std::exception& e) {
LOG_ERROR("Error creating Zarr stream: %s", e.what());
}

return stream;
}

void ZarrStream_destroy(struct ZarrStream_s* stream)
{
delete stream;
}

ZarrStatusCode ZarrStream_append(struct ZarrStream_s* stream,
const void* data,
size_t bytes_in,
size_t* bytes_out)
{
EXPECT_VALID_ARGUMENT(stream, "Null pointer: stream");
EXPECT_VALID_ARGUMENT(data, "Null pointer: data");
EXPECT_VALID_ARGUMENT(bytes_out, "Null pointer: bytes_out");

try {
*bytes_out = stream->append(data, bytes_in);
} catch (const std::exception& e) {
LOG_ERROR("Error appending data: %s", e.what());
return ZarrStatusCode_InternalError;
}

return ZarrStatusCode_Success;
}
}
28 changes: 28 additions & 0 deletions src/streaming/macros.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include "logger.hh"

#define EXPECT(e, ...) \
do { \
if (!(e)) { \
const std::string __err = LOG_ERROR(__VA_ARGS__); \
throw std::runtime_error(__err); \
} \
} while (0)
#define CHECK(e) EXPECT(e, "Expression evaluated as false:\n\t%s", #e)

#define EXPECT_VALID_ARGUMENT(e, ...) \
do { \
if (!(e)) { \
LOG_ERROR(__VA_ARGS__); \
return ZarrStatusCode_InvalidArgument; \
} \
} while (0)

#define EXPECT_VALID_INDEX(e, ...) \
do { \
if (!(e)) { \
LOG_ERROR(__VA_ARGS__); \
return ZarrStatusCode_InvalidIndex; \
} \
} while (0)
Loading

0 comments on commit 16c553f

Please sign in to comment.