34#include <NDEVR/File.h>
35#include <NDEVR/String.h>
36#include <NDEVR/Dictionary.h>
37#include <NDEVR/Bounds.h>
38#include <NDEVR/Compressor.h>
44#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)
45#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
46 static constexpr bool kNativeLittleEndian =
true;
47#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
48 static constexpr bool kNativeLittleEndian =
false;
50#error Unsupported native endianness
53#elif defined(_WIN32) || defined(_WIN64)
54 static constexpr bool kNativeLittleEndian =
true;
56#elif defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
57 static constexpr bool kNativeLittleEndian =
true;
59#elif defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM) || defined(_M_ARM64)
60 static constexpr bool kNativeLittleEndian =
true;
62#elif defined(__ARMEB__) || defined(__AARCH64EB__)
63 static constexpr bool kNativeLittleEndian =
false;
66#error Cannot determine endianness at compile time on this platform (C++17)
77 static_assert(std::is_integral<T>::value,
"T must be an integral type");
78 static_assert(!std::is_same<T, bool>::value,
"bool is not supported");
80 using U =
typename std::make_unsigned<T>::type;
81 U x =
static_cast<U
>(v);
84 for (std::size_t i = 0; i <
sizeof(T); ++i)
86 y = (y << 8) | (x & static_cast<U>(0xFF));
90 return static_cast<T
>(y);
99 constexpr T
_LE(T v)
noexcept
101 static_assert(std::is_integral<T>::value,
"T must be an integral type");
102 static_assert(!std::is_same<T, bool>::value,
"bool is not supported");
104 return kNativeLittleEndian ? v :
ByteSwap(v);
113 constexpr T
_BE(T v)
noexcept
115 static_assert(std::is_integral<T>::value,
"T must be an integral type");
116 static_assert(!std::is_same<T, bool>::value,
"bool is not supported");
118 return kNativeLittleEndian ?
ByteSwap(v) : v;
124 template <
class t_type>
253 template<
class t_type>
254 typename std::enable_if<!ObjectInfo<t_type>::Buffer>::type
write(
const t_type& data)
264 template<
class t_type,
class t_memory_manager>
267 if (data.size() != 0)
308 template<
class t_type,
class t_memory_manager>
313 sizes.setSize(data.size());
314 for (
uint04 i = 0; i < data.size(); i++)
316 uint04 size = data[i].size();;
320 Buffer<
decltype(t_type::Type())> combined_data(total_size);
321 for (
uint04 i = 0; i < data.size(); i++)
323 combined_data.addAll(data[i]);
325 write(sizes, compression_mode);
326 write(combined_data, compression_mode);
335 if (data.
size() != 0)
400 if (size > data.
size())
414 if (size > data.
size())
417 for(
uint04 i = 0; i < add_size; i++)
418 fwrite(&fill_space, add_size, 1,
m_file.filePtr());
426 template<
class t_type>
440 template<
class t_type>
451 fread(&data,
sizeof(t_type), 1,
m_file.filePtr());
458 template<
class t_type>
464 fseek(
m_file.filePtr(),
sizeof(t_type), SEEK_CUR);
509 template<
class t_type,
class t_memory_manager>
513 read(data, allow_multithread);
519 template<
class t_type,
class t_memory_manager>
522 bool allow_multithread =
false;
523 read(data, allow_multithread);
530 template<
class t_type,
class t_memory_manager>
534 Buffer<
decltype(t_type::Type())> combined_data;
536 allow_multithread =
false;
537 read(sizes, allow_multithread);
538 read(combined_data, allow_multithread);
539 data.setSize(sizes.size());
540 uint04 current_offset = 0;
541 for (
uint04 i = 0; i < sizes.size(); i++)
545 data[i].addAll(&combined_data[0] + current_offset, sizes[i]);
546 current_offset += sizes[i];
555 template<
class t_memory_manager>
560 allow_multithread =
false;
561 read(indices, allow_multithread);
562 data.setSize(indices.size());
563 for (
uint04 i = 0; i < indices.size(); i++)
566 if (bounds.
span() > 0U)
567 data[i] =
m_strings.substr(bounds[MIN], bounds[MAX]);
577 template<
class t_type,
class t_memory_manager>
585 using t_index_type =
typename t_memory_manager::index_type;
589 if (data.size() != 0)
std::enable_if<!ObjectInfo< t_type >::Buffer >::type write(const t_type &data)
Writes a non-buffer type as raw bytes to the file.
BinaryFile(const Buffer< uint01 > &data)
Constructs a BinaryFile from a Buffer of bytes.
BinaryFile(BinaryFile &&bf) noexcept
Move constructor.
String m_strings
Accumulated string data for the string reference table.
void switchToFile(File file, bool is_write, bool is_safe)
Switches the underlying file to a different file and reopens it.
void open(bool read, bool safe)
Opens the file for reading or writing.
uint08 m_cache_location
Current read/write position within the cached data.
File m_file
The underlying file handle for disk-based I/O.
bool canRead() const
Checks whether enough data remains to read a value of the given type.
void readString(String &string, char terminator='\0')
Reads a string up to a terminating character.
void skip()
Advances the read position by the size of the given type without reading.
void setUseLargeCompression(bool use_large_compression)
Enables or disables large (64-bit) compression size headers.
Dictionary< String, uint04 > m_string_reference
Maps strings to their index in the string reference table.
const HighCapacityBuffer< uint01 > & cachedData() const
Returns a const reference to the in-memory cached data.
BinaryFile()
Constructs an empty BinaryFile backed by an in-memory cache.
bool m_is_read
Whether the file was opened for reading.
void writeStringData(CompressionMode compression_mode)
Writes the accumulated string reference table to the file.
uint04 readData(char *string, uint04 max_size)
Reads raw data into a character buffer up to a maximum size.
void writeDirect(const uint01 *ptr, uint08 size)
Writes raw bytes directly to the file or cache.
void seek(uint08 location)
Seeks to an absolute byte position in the file or cache.
uint08 m_file_size
Cached file size to avoid repeated filesystem queries.
bool isFinished()
Checks whether the file has been fully read.
BinaryCompressionObject createCompressionObject()
Creates a BinaryCompressionObject initialized with this file's compression settings.
void readStringBuffer(Buffer< String, t_memory_manager > &data, bool &allow_multithread)
Reads a buffer of strings using the string reference table for decompression.
uint08 position() const
Returns the current read or write position in the file or cache.
BinaryFile & operator=(BinaryFile &&bf) noexcept
Move assignment operator.
uint04 readString(char *string, char terminator='\0')
Reads a string into a character buffer up to a terminating character.
const File & file() const
Returns a const reference to the underlying File object.
fltp08 fltp_error
Floating-point error tolerance used during compression.
std::enable_if<!ObjectInfo< t_type >::Buffer >::type read(Buffer< t_type, t_memory_manager > &data, bool &allow_multithread)
Reads a buffer of non-buffer elements with decompression.
void uncompressAll()
Decompresses all pending multithreaded compression objects.
fltp04 percent() const
Returns the current read progress as a percentage of the total file size.
uint08 readDirect(uint01 *ptr, uint08 size)
Reads raw bytes directly from the file or cache.
bool m_large_compression
Whether to use 64-bit size fields for compression headers.
bool m_using_cache
Whether the file is operating in cached (in-memory) mode.
std::enable_if< ObjectInfo< t_type >::Buffer >::type read(Buffer< t_type, t_memory_manager > &data, bool &allow_multithread)
Reads a buffer of buffer elements (nested buffers) with decompression.
void writeRawData(const StringView &data, uint04 size, char fill_space='\0')
Writes a string as raw data padded or truncated to a fixed size.
std::enable_if<!ObjectInfo< t_type >::Buffer >::type write(const Buffer< t_type, t_memory_manager > &data, CompressionMode compression_mode=CompressionMode::e_no_compression)
Writes a buffer of non-buffer elements with optional compression.
BinaryFile(const HighCapacityBuffer< uint01 > &data)
Constructs a BinaryFile from an existing data buffer (copy).
HighCapacityBuffer< uint01 > m_compressed_data
Temporary buffer for compressed data during read/write operations.
uint08 m_max_buffer_size
Maximum buffer size for cached read/write operations.
void writeTerminatingString(const StringView &string, char terminator='\0')
Writes a string followed by a terminating character.
HighCapacityBuffer< uint01 > & cachedData()
Returns a mutable reference to the in-memory cached data.
void writeCompression(BinaryCompressionObject &compression_object)
Writes a compression object's data to the file.
File & file()
Returns a mutable reference to the underlying File object.
t_type read()
Reads a single value of the given type from the file or cache.
void readStringData(bool has_reference_table)
Reads the string reference table from the file.
void write(const StringView &data, CompressionMode compression_mode)
Writes a string view with optional compression.
bool writeDirectlyFrom(File file)
Writes data from a file on disk directly into the cache.
bool m_multithreaded_compression
Whether multithreaded decompression is enabled.
bool readDirectlyTo(File file)
Reads the cached data directly to a file on disk.
void read(Buffer< t_type, t_memory_manager > &data)
Reads a compressed buffer using the file's multithreading setting.
void readNow(Buffer< t_type, t_memory_manager > &data)
Reads a compressed buffer synchronously, disabling multithreaded decompression.
HighCapacityBuffer< uint01 > m_cached_data
In-memory cache of the file's raw byte contents.
void cachedOpen(bool read)
Opens the file and reads its entire contents into an in-memory cache.
BinaryFile(HighCapacityBuffer< uint01 > &&data)
Constructs a BinaryFile from an existing data buffer (move).
Buffer< Bounds< 1, uint04 > > m_string_size_info
Stores the start and end bounds of each string in m_strings.
void close()
Closes the file and flushes any pending data.
uint08 fileSize() const
Returns the size of the underlying file in bytes.
void uncompressSections(uint04 start, uint04 count)
Decompresses a range of pending multithreaded compression objects.
Buffer< BinaryCompressionObject > m_compressions
Pending compression objects for multithreaded decompression.
BinaryFile(const File &file)
Constructs a BinaryFile associated with the given file on disk.
String readData(uint04 max_size)
Reads raw data up to a maximum size and returns it as a String.
BinaryFile(const uint01 *data, uint08 size)
Constructs a BinaryFile from a raw pointer and size.
void setMaxBufferSize(uint08 max_buffer_size)
Sets the maximum buffer size for cached operations.
std::enable_if< ObjectInfo< t_type >::Buffer >::type write(const Buffer< t_type, t_memory_manager > &data, CompressionMode compression_mode)
Writes a buffer of buffer elements (nested buffers) with optional compression.
A specification of upper and lower bounds in N-dimensions.
constexpr Ray< t_dims, t_type > span() const
The side lengths of these bounds.
The equivelent of std::vector but with a bit more control.
static CompressionMode PickCompressionMode(CompressionMode compression_mode=e_default_compression)
Selects the most appropriate compression mode for the given type.
static void DecompressData(BinaryCompressionObject &data)
Decompresses the BinaryCompressionObject.
static void CompressData(BinaryCompressionObject &data)
Compresses the BinaryCompressionObject.
A hash-based key-value store, useful for quick associative lookups.
Logic for reading or writing to a file as well as navigating filesystems or other common file operati...
Logic for reading or writing to a string or a user friendly, TranslatedString.
The core String View class for the NDEVR API.
constexpr const char * begin() const
Returns a pointer to the beginning of the string data.
constexpr uint04 size() const
Returns the byte size of this string view.
The core String class for the NDEVR API.
The primary namespace for the NDEVR SDK.
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator Author: Tyler Parke Date: 2017-11-05...
float fltp04
Defines an alias representing a 4 byte floating-point number Bit layout is as follows: -Sign: 1 bit a...
constexpr std::enable_if<!ObjectInfo< t_type >::Buffer, TypeInfo >::type GetTypeInfo()
Constructs a TypeInfo for a non-buffer type at compile time using ObjectInfo traits.
uint64_t uint08
-Defines an alias representing an 8 byte, unsigned integer
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
double fltp08
Defines an alias representing an 8 byte floating-point number.
CompressionMode
Forward declaration of the Module struct for module metadata.
@ e_string_compression
Compression mode tailored for string data.
@ e_no_compression
No compression is applied; data is stored raw.
@ e_string_reference
Stores strings by reference index into a shared table.
constexpr T _LE(T v) noexcept
Converts a value from little-endian to native byte order.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
constexpr T ByteSwap(T v) noexcept
Reverses the byte order of an integral value.
constexpr T _BE(T v) noexcept
Converts a value from big-endian to native byte order.
constexpr t_type ChangeEndian(t_type in)
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
A container for storing compressed data, typically used for File IO operations.
uint08 uncompressed_size
Size in bytes of the uncompressed data.
uint08 buffer_size
Number of logical elements in the buffer.
TypeInfo object_type
Type information describing the elements being compressed.
CompressionMode compression_mode
The compression algorithm to apply.
uint01 * compressed_data
Pointer to the compressed data buffer.
uint01 * uncompressed_data
Pointer to the raw uncompressed data buffer.
uint08 compressed_size
Size in bytes of the compressed data.