aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/tourist/trace/src/data.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/tourist/trace/src/data.cpp')
-rw-r--r--thirdparty/tourist/trace/src/data.cpp166
1 files changed, 166 insertions, 0 deletions
diff --git a/thirdparty/tourist/trace/src/data.cpp b/thirdparty/tourist/trace/src/data.cpp
new file mode 100644
index 000000000..da42284dc
--- /dev/null
+++ b/thirdparty/tourist/trace/src/data.cpp
@@ -0,0 +1,166 @@
+#include <foundation/platform.h>
+#include <foundation/types.h>
+#include <trace/detail/data.h>
+
+//------------------------------------------------------------------------------
+#ifdef _WIN32
+
+DataSource::DataSource(const Path& path)
+{
+ HANDLE handle = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ,
+ nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (handle == INVALID_HANDLE_VALUE)
+ throw std::runtime_error("Failed to open file");
+
+ _handle = uintptr(handle);
+}
+
+DataSource::~DataSource()
+{
+ auto handle = HANDLE(_handle);
+ CloseHandle(handle);
+}
+
+int32 DataSource::read(void* out, uint32 size)
+{
+ auto handle = HANDLE(_handle);
+
+ DWORD bytes_read;
+ if (!ReadFile(handle, out, size, &bytes_read, nullptr))
+ throw std::runtime_error("Read error");
+
+ return bytes_read;
+}
+
+int64 DataSource::get_size() const
+{
+ if (_size >= 0)
+ return _size;
+
+ auto handle = HANDLE(_handle);
+
+ LARGE_INTEGER out;
+ GetFileSizeEx(handle, &out);
+ return _size = out.QuadPart;
+}
+
+#else // POSIX
+
+DataSource::DataSource(const Path& path)
+{
+ int fd = ::open(path.string().c_str(), O_RDONLY);
+ if (fd < 0)
+ throw std::runtime_error("Failed to open file");
+
+ _handle = uintptr(fd);
+}
+
+DataSource::~DataSource()
+{
+ ::close(int(_handle));
+}
+
+int32 DataSource::read(void* out, uint32 size)
+{
+ ssize_t bytes_read = ::read(int(_handle), out, size);
+ if (bytes_read < 0)
+ throw std::runtime_error("Read error");
+
+ return int32(bytes_read);
+}
+
+int64 DataSource::get_size() const
+{
+ if (_size >= 0)
+ return _size;
+
+ struct stat st;
+ if (fstat(int(_handle), &st) < 0)
+ return _size = 0;
+
+ return _size = st.st_size;
+}
+
+#endif
+
+
+
+//------------------------------------------------------------------------------
+DataStream::DataStream(DataSource& data_source, Allocator& allocator)
+: _data_source(data_source)
+, _allocator(allocator)
+{
+}
+
+//------------------------------------------------------------------------------
+uint64 DataStream::tell() const
+{
+ return _position;
+}
+
+//------------------------------------------------------------------------------
+uint32 DataStream::get_available() const
+{
+ return _stream.get_remaining();
+}
+
+//------------------------------------------------------------------------------
+Buffer DataStream::read(uint32 size)
+{
+ const uint8* ptr = _read(size);
+ return _buffer.create_sub_buffer(ptr, size);
+}
+
+//------------------------------------------------------------------------------
+const uint8* DataStream::_read(uint32 size)
+{
+ _position += size;
+
+ if (_stream.get_remaining() >= size)
+ return _stream.read(size);
+
+ MutableBuffer buffer = _allocator.create_buffer(BUFFER_SIZE);
+ uint8* cursor = buffer.get_pointer();
+ uint32 buffer_size = buffer.get_size();
+
+ if (uint32 remaining = _stream.get_remaining())
+ {
+ const void* src = _stream.read(remaining);
+ std::memcpy(cursor, src, remaining);
+ cursor += remaining;
+ buffer_size -= remaining;
+ }
+
+ uint32 read_size = 0;
+ while (true)
+ {
+ int32 i = _data_source.read(cursor + read_size, buffer_size - read_size);
+ if (i <= 0)
+ throw Eof();
+
+ if ((read_size += i) >= size)
+ break;
+ }
+
+ if (read_size < buffer_size)
+ {
+ buffer_size = BUFFER_SIZE - buffer_size + read_size;
+ _buffer = buffer.create_sub_buffer(0u, buffer_size);
+ }
+ else
+ _buffer = std::move(buffer);
+
+ _stream = _buffer.create_stream();
+
+ return _stream.read(size);
+}
+
+//------------------------------------------------------------------------------
+template <> int8 DataStream::read< int8 >() { return *( int8 *)_read(sizeof( int8 )); }
+template <> int16 DataStream::read< int16>() { return *( int16*)_read(sizeof( int16)); }
+template <> int32 DataStream::read< int32>() { return *( int32*)_read(sizeof( int32)); }
+template <> int64 DataStream::read< int64>() { return *( int64*)_read(sizeof( int64)); }
+template <> uint8 DataStream::read<uint8 >() { return *(uint8 *)_read(sizeof(uint8 )); }
+template <> uint16 DataStream::read<uint16>() { return *(uint16*)_read(sizeof(uint16)); }
+template <> uint32 DataStream::read<uint32>() { return *(uint32*)_read(sizeof(uint32)); }
+template <> uint64 DataStream::read<uint64>() { return *(uint64*)_read(sizeof(uint64)); }