c2pa-cpp
C++ API for the C2PA SDK
Loading...
Searching...
No Matches
c2pa::detail Namespace Reference

Classes

struct  StreamSeekTraits
 Traits (templated): how to seek and get position for a given stream type. More...
 
struct  StreamSeekTraits< std::iostream >
 
struct  StreamSeekTraits< std::istream >
 
struct  StreamSeekTraits< std::ostream >
 

Functions

bool error_indicates_manifest_not_found (const char *message) noexcept
 True if the C2PA error message indicates no JUMBF / manifest in the asset (ManifestNotFound).
 
std::vector< std::string > c_mime_types_to_vector (const char *const *mime_types, uintptr_t count)
 Converts a C array of C strings to a std::vector of std::string.
 
constexpr std::ios_base::seekdir whence_to_seekdir (C2paSeekMode whence) noexcept
 Maps C2PA seek mode to std::ios seek direction.
 
template<typename Stream >
bool is_stream_usable (Stream *s) noexcept
 Check if stream is in valid state for I/O operations.
 
template<typename Stream >
intptr_t stream_seeker (StreamContext *context, intptr_t offset, C2paSeekMode whence)
 
template<typename Stream >
intptr_t stream_reader (StreamContext *context, uint8_t *buffer, intptr_t size)
 
template<typename Stream , typename Op >
intptr_t stream_op (StreamContext *context, Op op)
 
template<typename Stream >
intptr_t stream_writer (StreamContext *context, const uint8_t *buffer, intptr_t size)
 Writer impl.
 
template<typename Stream >
intptr_t stream_flusher (StreamContext *context)
 Flusher impl.
 
template<typename StreamType >
std::unique_ptr< StreamTypeopen_file_binary (const std::filesystem::path &path)
 Open a binary file stream with error handling.
 
std::string extract_file_extension (const std::filesystem::path &path) noexcept
 Extract file extension without the leading dot.
 
template<typename T >
std::string c_string_to_string (T *c_result)
 Convert C string result to C++ string with cleanup.
 
std::vector< unsigned charto_byte_vector (const unsigned char *data, int64_t size)
 Convert C byte array result to C++ vector.
 

Function Documentation

◆ c_mime_types_to_vector()

std::vector< std::string > c2pa::detail::c_mime_types_to_vector ( const char *const mime_types,
uintptr_t  count 
)
inline

Converts a C array of C strings to a std::vector of std::string.

Parameters
mime_typesPointer to an array of C strings (const char*).
countNumber of elements in the array.
Returns
A std::vector containing the strings from the input array.

This function takes ownership of the input array and frees it using c2pa_free_string_array().

45 {
46 std::vector<std::string> result;
47 if (mime_types == nullptr) { return result; }
48
49 try {
50 result.reserve(count);
51 for(uintptr_t i = 0; i < count; i++) {
52 if (mime_types[i] != nullptr) {
53 result.emplace_back(mime_types[i]);
54 }
55 }
56 } catch (...) {
57 c2pa_free_string_array(mime_types, count);
58 throw;
59 }
60
61 c2pa_free_string_array(mime_types, count);
62 return result;
63}

◆ c_string_to_string()

template<typename T >
std::string c2pa::detail::c_string_to_string ( T c_result)
inline

Convert C string result to C++ string with cleanup.

Parameters
c_resultRaw C string from C API
Returns
C++ string (throws if null)
249 {
250 if (c_result == nullptr) {
251 throw C2paException();
252 }
253 std::string str(c_result);
254 c2pa_free(c_result);
255 return str;
256}
Exception class for C2pa errors. This class is used to throw exceptions for errors encountered by the...
Definition c2pa.hpp:87

◆ error_indicates_manifest_not_found()

bool c2pa::detail::error_indicates_manifest_not_found ( const char message)
inlinenoexcept

True if the C2PA error message indicates no JUMBF / manifest in the asset (ManifestNotFound).

35 {
36 return message != nullptr && std::strstr(message, "ManifestNotFound") != nullptr;
37}

◆ extract_file_extension()

std::string c2pa::detail::extract_file_extension ( const std::filesystem::path &  path)
inlinenoexcept

Extract file extension without the leading dot.

Parameters
pathFilesystem path
Returns
Extension string (e.g., "jpg" not ".jpg")
240 {
241 auto ext = path.extension().string();
242 return ext.empty() ? "" : ext.substr(1);
243}

◆ is_stream_usable()

template<typename Stream >
bool c2pa::detail::is_stream_usable ( Stream s)
inlinenoexcept

Check if stream is in valid state for I/O operations.

77 {
78 return s && !s->bad();
79}

◆ open_file_binary()

template<typename StreamType >
std::unique_ptr< StreamType > c2pa::detail::open_file_binary ( const std::filesystem::path &  path)
inline

Open a binary file stream with error handling.

Template Parameters
StreamTypestd::ifstream or std::ofstream
Parameters
pathPath to the file
Returns
Unique pointer to opened stream
226{
227 auto stream = std::make_unique<StreamType>(
228 path,
229 std::ios_base::binary
230 );
231 if (!stream->is_open()) {
232 throw C2paException("Failed to open file: " + path.string());
233 }
234 return stream;
235}

◆ stream_flusher()

template<typename Stream >
intptr_t c2pa::detail::stream_flusher ( StreamContext context)

Flusher impl.

213 {
214 return stream_op<Stream>(context, [](Stream* s) {
215 s->flush();
216 return 0;
217 });
218}

◆ stream_op()

template<typename Stream , typename Op >
intptr_t c2pa::detail::stream_op ( StreamContext *  context,
Op  op 
)

Get stream from context, used by writer and flusher. Exceptions must not unwind into Rust/C, so any throw is converted to an IoError return.

183 {
184 try {
185 auto* stream = reinterpret_cast<Stream*>(context);
186 if (!is_stream_usable(stream)) {
187 return stream_error_return(StreamError::IoError);
188 }
189 const intptr_t result = op(stream);
190 if (stream->fail()) {
191 return stream_error_return(StreamError::InvalidArgument);
192 }
193 if (stream->bad()) {
194 return stream_error_return(StreamError::IoError);
195 }
196 return result;
197 } catch (...) {
198 return stream_error_return(StreamError::IoError);
199 }
200}
bool is_stream_usable(Stream *s) noexcept
Check if stream is in valid state for I/O operations.
Definition c2pa_internal.hpp:77
int stream_error_return(StreamError e) noexcept
Set errno from StreamError and return error sentinel.
Definition c2pa.hpp:79

◆ stream_reader()

template<typename Stream >
intptr_t c2pa::detail::stream_reader ( StreamContext context,
uint8_t buffer,
intptr_t  size 
)

Reader impl. Exceptions must not unwind into Rust/C, so any throw is converted to an IoError return.

149 {
150 if (!context || !buffer) {
151 return stream_error_return(StreamError::InvalidArgument);
152 }
153 if (size < 0) {
154 return stream_error_return(StreamError::InvalidArgument);
155 }
156 if (size == 0) {
157 return 0;
158 }
159 try {
160 auto* stream = reinterpret_cast<Stream*>(context);
161 if (!is_stream_usable(stream)) {
162 return stream_error_return(StreamError::IoError);
163 }
164 stream->read(reinterpret_cast<char*>(buffer), size);
165 if (stream->fail()) {
166 if (!stream->eof()) {
167 return stream_error_return(StreamError::InvalidArgument);
168 }
169 }
170 if (stream->bad()) {
171 return stream_error_return(StreamError::IoError);
172 }
173 return static_cast<intptr_t>(stream->gcount());
174 } catch (...) {
175 return stream_error_return(StreamError::IoError);
176 }
177}

◆ stream_seeker()

template<typename Stream >
intptr_t c2pa::detail::stream_seeker ( StreamContext context,
intptr_t  offset,
C2paSeekMode  whence 
)

Seeker impl. Exceptions must not unwind into Rust/C, so any throw is converted to an IoError return.

120 {
121 try {
122 auto* stream = reinterpret_cast<Stream*>(context);
123 if (!is_stream_usable(stream)) {
124 return stream_error_return(StreamError::IoError);
125 }
126 const std::ios_base::seekdir dir = whence_to_seekdir(whence);
127 stream->clear();
128 StreamSeekTraits<Stream>::seek(stream, offset, dir);
129 if (stream->fail()) {
130 return stream_error_return(StreamError::InvalidArgument);
131 }
132 if (stream->bad()) {
133 return stream_error_return(StreamError::IoError);
134 }
135 const int64_t pos = StreamSeekTraits<Stream>::tell(stream);
136 if (pos < 0) {
137 return stream_error_return(StreamError::IoError);
138 }
139 return static_cast<intptr_t>(pos);
140 } catch (...) {
141 return stream_error_return(StreamError::IoError);
142 }
143}

◆ stream_writer()

template<typename Stream >
intptr_t c2pa::detail::stream_writer ( StreamContext context,
const uint8_t buffer,
intptr_t  size 
)

Writer impl.

204 {
205 return stream_op<Stream>(context, [buffer, size](Stream* s) {
206 s->write(reinterpret_cast<const char*>(buffer), size);
207 return size;
208 });
209}

◆ to_byte_vector()

std::vector< unsigned char > c2pa::detail::to_byte_vector ( const unsigned char data,
int64_t  size 
)
inline

Convert C byte array result to C++ vector.

Parameters
dataRaw byte array from C API
sizeSize of the byte array (result from C API call)
Returns
Vector containing the bytes (throws if null or negative size)

This helper extracts the pattern of checking C API results, copying to a vector, and freeing the C-allocated memory. The C API contract is: if result < 0, the operation failed. A null data pointer with size == 0 is a valid empty result (the C API returns null for empty byte arrays).

267 {
268 if (size < 0 || (data == nullptr && size > 0)) {
269 c2pa_free(data); // May be null or allocated, c2pa_free handles both
270 throw C2paException();
271 }
272 if (size == 0) {
273 c2pa_free(data);
274 return {};
275 }
276
277 auto result = std::vector<unsigned char>(data, data + size);
278 c2pa_free(data);
279 return result;
280}

◆ whence_to_seekdir()

constexpr std::ios_base::seekdir c2pa::detail::whence_to_seekdir ( C2paSeekMode  whence)
constexprnoexcept

Maps C2PA seek mode to std::ios seek direction.

66 {
67 switch (whence) {
68 case C2paSeekMode::Start: return std::ios_base::beg;
69 case C2paSeekMode::Current: return std::ios_base::cur;
70 case C2paSeekMode::End: return std::ios_base::end;
71 default: return std::ios_base::beg;
72 }
73}