Skip to content

Commit 08acb7d

Browse files
Matthäus G. ChajdasMatthäus G. Chajdas
authored andcommitted
RDF 1.2.0
1 parent 6955070 commit 08acb7d

File tree

16 files changed

+229
-42
lines changed

16 files changed

+229
-42
lines changed

CMakeLists.txt

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
### Copyright (c) 2021-2022 Advanced Micro Devices, Inc. All rights reserved. ###
1+
### Copyright (c) 2021-2023 Advanced Micro Devices, Inc. All rights reserved. ###
22
cmake_minimum_required(VERSION 3.13..3.21)
33
project(rdf LANGUAGES CXX C)
44

@@ -11,7 +11,7 @@ endif()
1111
option(RDF_BUILD_TESTS "Build the tests" ${RDF_IS_TOP_LEVEL})
1212
option(RDF_BUILD_TOOLS "Build RDF tools" ${RDF_IS_TOP_LEVEL})
1313
option(RDF_BUILD_INSTALL "Install RDF libs" ${RDF_IS_TOP_LEVEL})
14-
option(RDF_ENABLE_CXX_BINDINGS "Allow usage of C++ interface for RDF library" ON)
14+
option(RDF_ENABLE_CXX_BINDINGS "Enable the C++ interface" ON)
1515
option(RDF_STATIC "Build RDF as a static library" OFF)
1616

1717
if(RDF_BUILD_TESTS)
@@ -40,7 +40,60 @@ if (RDF_IS_TOP_LEVEL)
4040
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
4141
endif()
4242

43-
add_subdirectory(imported)
43+
################################################################################
44+
# Import third party libraries
45+
# For each library, three steps are checked to ensure it is present:
46+
# 1. Check if target is already provided
47+
# 2. Try to find lib via vcpkg
48+
# 3. Add target locally
49+
# We have to do this here for VCPKG to work, as we can't alias targets from
50+
# VCPKG in a subdirectory, and VCPKG uses different target names which we
51+
# don't want to force on everyone
52+
# We use QUIET on all finds because failure is an option (we just fall back
53+
# to our internal copy.)
54+
55+
if(NOT TARGET zstd)
56+
find_package(zstd QUIET)
57+
if(TARGET zstd::libzstd_shared)
58+
add_library(zstd ALIAS zstd::libzstd_shared)
59+
elseif(TARGET zstd::libzstd_static)
60+
add_library(zstd ALIAS zstd::libzstd_static)
61+
else()
62+
add_subdirectory(imported/zstd)
63+
endif()
64+
endif()
65+
66+
if(RDF_BUILD_TESTS AND (NOT TARGET catch2))
67+
find_package(Catch2 QUIET)
68+
if(TARGET Catch2::Catch2)
69+
add_library(catch2 ALIAS Catch2::Catch2WithMain)
70+
else()
71+
add_subdirectory(imported/catch2)
72+
endif()
73+
endif()
74+
75+
if(RDF_BUILD_TOOLS)
76+
if(NOT TARGET cli11)
77+
find_package(CLI11 QUIET)
78+
if(TARGET CLI11::CLI11)
79+
add_library(cli11 ALIAS CLI11::CLI11)
80+
else()
81+
add_subdirectory(imported/cli11)
82+
endif()
83+
endif()
84+
85+
if(NOT TARGET json)
86+
find_package(nlohmann_json QUIET)
87+
if(TARGET nlohmann_json::nlohmann_json)
88+
add_library(json ALIAS nlohmann_json::nlohmann_json)
89+
else()
90+
add_subdirectory(imported/json)
91+
endif()
92+
endif()
93+
endif()
94+
95+
################################################################################
96+
# Project build
4497
add_subdirectory(rdf)
4598
if(RDF_BUILD_TOOLS)
4699
add_subdirectory(rdfi)

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ Patch releases (for example, `1.1.1`) will be bumped for bug fixes and other imp
4545
* **1.1.3**:
4646
* Fix missing includes on GCC13
4747
* Update `Zstd` dependency from 1.4.5 to 1.5.5
48+
* **1.2.0**
49+
* Add support for [VCPKG](https://vcpkg.io/)
50+
* The library can be now consumed via VCPKG
51+
* The build can optionally use VCPKG to fetch dependencies
52+
* Add a new `Close` callback function to `rdfUserStream`. This allows wrapped user streams to clean up the wrapped object, making it easier to track lifetime.

imported/CMakeLists.txt

Lines changed: 0 additions & 21 deletions
This file was deleted.

rdf/inc/amdrdf.h

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
(static_cast<std::uint32_t>(minor) << 12) | \
2727
(static_cast<std::uint32_t>(patch)))
2828

29-
#define RDF_INTERFACE_VERSION RDF_MAKE_VERSION(1, 1, 3)
29+
#define RDF_INTERFACE_VERSION RDF_MAKE_VERSION(1, 2, 0)
3030

3131
extern "C" {
3232
struct rdfChunkFile;
@@ -70,13 +70,23 @@ struct rdfStreamFromFileCreateInfo
7070
/**
7171
* @brief User-provided I/O callbacks
7272
*
73-
* There are five callback functions here which will be called with the user-
73+
* There are six callback functions here which will be called with the user-
7474
* provided context variable:
7575
*
7676
* - Seek/Tell/GetSize must be always non-null
7777
* - Read/Write can be null. Note that a stream which has both set to null
7878
* is invalid. The chunk writer can work with a stream that is in write-
7979
* only mode only if it's not appending.
80+
* - Close can be null. This function will be called when the stream is closed,
81+
* which can be used to clean-up the context. A closed stream cannot be
82+
* reused, and it's the responsibility of the user to ensure a stream
83+
* is not closed more than once.
84+
*
85+
* The first argument is always the context provided along with the user
86+
* stream. Notice that the context pointer is copied internally, so you can't
87+
* rely on the address of the context to be the same as the one passed into
88+
* the various create functions. Specifically, you can't use `&ctx` to modify
89+
* the context provided at creation time.
8090
*/
8191
struct rdfUserStream
8292
{
@@ -137,11 +147,21 @@ struct rdfUserStream
137147
*
138148
* This function must be always provided.
139149
*
140-
* - `size` must not be `null`
150+
* - `size` must not be `null`
141151
* - The provided context will be passed into `ctx`
142152
*/
143153
int (*GetSize)(void* ctx, std::int64_t* size);
144154

155+
/**
156+
* @brief Close the stream.
157+
* @return rdfResult
158+
*
159+
* This function can be `null` if the stream handles closing elsewhere.
160+
*
161+
* @since 1.2
162+
*/
163+
int (*Close)(void* ctx);
164+
145165
void* context;
146166
};
147167

rdf/src/amdrdf.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* Copyright (c) 2021-2022 Advanced Micro Devices, Inc. All rights reserved. */
22
#include "amdrdf.h"
33

4-
#include <zstd/zstd.h>
4+
#include <zstd.h>
55

66
#include <cassert>
77
#include <cstdio>
@@ -70,6 +70,8 @@ namespace internal
7070
bool CanWrite() const;
7171
bool CanRead() const;
7272

73+
void Close();
74+
7375
private:
7476
virtual std::int64_t ReadImpl(const std::int64_t count, void* buffer) = 0;
7577
virtual std::int64_t WriteImpl(const std::int64_t count, const void* buffer) = 0;
@@ -80,6 +82,8 @@ namespace internal
8082

8183
virtual bool CanWriteImpl() const = 0;
8284
virtual bool CanReadImpl() const = 0;
85+
86+
virtual void CloseImpl() = 0;
8387
};
8488

8589
///////////////////////////////////////////////////////////////////////////
@@ -155,6 +159,13 @@ namespace internal
155159
return stream_.Read != nullptr;
156160
}
157161

162+
void CloseImpl() override
163+
{
164+
if (stream_.Close) {
165+
stream_.Close(stream_.context);
166+
}
167+
}
168+
158169
void CheckCall(int result) const
159170
{
160171
if (result != rdfResultOk) {
@@ -812,6 +823,12 @@ namespace internal
812823
return WriteImpl(size, buffer);
813824
}
814825

826+
//////////////////////////////////////////////////////////////////////
827+
void IStream::Close()
828+
{
829+
CloseImpl();
830+
}
831+
815832
//////////////////////////////////////////////////////////////////////
816833
bool IStream::CanRead() const
817834
{
@@ -852,11 +869,6 @@ namespace internal
852869
public:
853870
Filestream(std::FILE* fd, rdfStreamAccess accessMode) : fd_(fd), accessMode_(accessMode) {}
854871

855-
~Filestream()
856-
{
857-
std::fclose(fd_);
858-
}
859-
860872
private:
861873
std::int64_t ReadImpl(const std::int64_t count, void* buffer) override
862874
{
@@ -917,6 +929,12 @@ namespace internal
917929
#endif
918930
}
919931

932+
void CloseImpl() override
933+
{
934+
std::fclose(fd_);
935+
fd_ = nullptr;
936+
}
937+
920938
std::FILE* fd_;
921939
rdfStreamAccess accessMode_;
922940
};
@@ -990,6 +1008,13 @@ namespace internal
9901008
return true;
9911009
}
9921010

1011+
void CloseImpl() override
1012+
{
1013+
buffer_ = nullptr;
1014+
size_ = 0;
1015+
readPointer_ = 0;
1016+
}
1017+
9931018
std::int64_t size_;
9941019
std::size_t readPointer_ = 0;
9951020
const void* buffer_;
@@ -1062,6 +1087,12 @@ namespace internal
10621087
return true;
10631088
}
10641089

1090+
void CloseImpl() override
1091+
{
1092+
data_.clear();
1093+
offset_ = 0;
1094+
}
1095+
10651096
std::vector<unsigned char> data_;
10661097
std::size_t offset_ = 0;
10671098
};
@@ -1383,6 +1414,8 @@ int RDF_EXPORT rdfStreamClose(rdfStream** handle)
13831414
return rdfResult::rdfResultInvalidArgument;
13841415
}
13851416

1417+
(*handle)->stream->Close();
1418+
13861419
delete *handle;
13871420
*handle = nullptr;
13881421

rdf/test/src/IO_test.cpp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Copyright (c) 2021-2022 Advanced Micro Devices, Inc. All rights reserved. */
2-
#include <catch2/catch.hpp>
2+
#include <catch.hpp>
33

44
#include "amdrdf.h"
55

@@ -89,6 +89,8 @@ TEST_CASE("rdfUserStream", "[rdf]")
8989
{
9090
std::int64_t bytesRead = 0;
9191
std::int64_t bytesWritten = 0;
92+
93+
bool isClosed = false;
9294
} ctx;
9395

9496
rdfUserStream us = {};
@@ -115,6 +117,11 @@ TEST_CASE("rdfUserStream", "[rdf]")
115117
return rdfResultOk;
116118
};
117119

120+
us.Close = [](void* context) -> int {
121+
static_cast<Context*>(context)->isClosed = true;
122+
return rdfResultOk;
123+
};
124+
118125
us.GetSize = [](void*, std::int64_t*) -> int { return rdfResultOk; };
119126
us.Tell = [](void*, std::int64_t*) -> int { return rdfResultOk; };
120127
us.Seek = [](void*, std::int64_t) -> int { return rdfResultOk; };
@@ -130,6 +137,9 @@ TEST_CASE("rdfUserStream", "[rdf]")
130137
CHECK(ctx.bytesWritten == 256);
131138

132139
rdfStreamClose(&stream);
140+
141+
// Our close sets "isClosed"
142+
CHECK(ctx.isClosed);
133143
}
134144

135145
TEST_CASE("ChunkFileWriter with write-only stream", "[rdf]")
@@ -232,3 +242,49 @@ TEST_CASE("rdfUserStream required functions", "[rdf]")
232242
CHECK(stream == nullptr);
233243
}
234244
}
245+
246+
TEST_CASE("rdfUserStream Close() can throw", "[rdf]")
247+
{
248+
/*
249+
Check that we can throw from Close(), and we can catch that, and still
250+
repeat the Close() and correctly close the stream.
251+
*/
252+
253+
bool shouldThrow = true;
254+
255+
rdfUserStream us = {};
256+
us.GetSize = [](void* ctx, int64_t* o) -> int {
257+
return rdfResultOk;
258+
};
259+
us.Read = [](void* ctx, int64_t c, void* p, int64_t* o) -> int {
260+
return rdfResultOk;
261+
};
262+
us.Write = [](void* ctx, int64_t c, const void* p, int64_t* o) -> int {
263+
return rdfResultOk;
264+
};
265+
us.Seek = [](void* ctx, int64_t o) -> int {
266+
return rdfResultOk;
267+
};
268+
us.Tell = [](void* ctx, int64_t* p) -> int {
269+
*p = 0;
270+
return rdfResultOk;
271+
};
272+
us.Close = [](void* ctx) -> int {
273+
if (*static_cast<bool*>(ctx)) {
274+
throw 23;
275+
}
276+
277+
return rdfResultOk;
278+
};
279+
us.context = &shouldThrow;
280+
281+
rdfStream* stream;
282+
rdfStreamCreateFromUserStream(&us, &stream);
283+
284+
CHECK(rdfStreamClose(&stream) != rdfResultOk);
285+
REQUIRE(stream != nullptr);
286+
287+
shouldThrow = false;
288+
CHECK(rdfStreamClose(&stream) == rdfResultOk);
289+
CHECK(stream == nullptr);
290+
}

0 commit comments

Comments
 (0)