replace the filesystem because apparently i actually used that
parent
aa97660877
commit
4743018302
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
include(cmake/color.cmake)
|
||||
|
||||
set(BLT_VERSION 0.16.6)
|
||||
set(BLT_VERSION 0.16.7)
|
||||
set(BLT_TEST_VERSION 0.0.1)
|
||||
|
||||
set(BLT_TARGET BLT)
|
||||
|
|
20
README.md
20
README.md
|
@ -25,7 +25,25 @@ A C++17 common utilities library to make thing easy!
|
|||
- Computes a rolling average in a dynamically allocated array.
|
||||
- Useful for average FPS over a period of time
|
||||
- ### fixed_point.h
|
||||
-
|
||||
- Provides a 64bit fixed point number with 2^32 bits of precision on each side of the decimal
|
||||
- Mostly optimal assembly, avoids sign extension by using 64 bit numbers
|
||||
- Requires your compiler to support 128 bit numbers
|
||||
- Docs: TODO
|
||||
- ### fixed_point_vector.h
|
||||
- Not finished due to complications in the vector type, this is a TODO
|
||||
- ### log_util.h
|
||||
- provides overloads for logging math types
|
||||
- ### math.h
|
||||
- blt::toRadians
|
||||
- to radians function (from deg)
|
||||
- blt::f_randi
|
||||
- fast random integer from seed
|
||||
- blt::fsqrt
|
||||
- fast inverse square root algorithm, floats only
|
||||
- blt::pow
|
||||
- power function
|
||||
- blt::round_up
|
||||
- rounds up to a variable number of decimal places
|
||||
|
||||
# Specialties
|
||||
## blt::logging.v2
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* <Short Description>
|
||||
* Copyright (C) 2024 Brett Terpstra
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLT_FILESYSTEM_H
|
||||
#define BLT_FILESYSTEM_H
|
||||
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
|
||||
namespace blt::fs
|
||||
{
|
||||
/**
|
||||
* A simple interface which provides a way of reading the next block of data from a resource.
|
||||
* The interface provides a single function "read" which will read a specified number of bytes into the buffer.
|
||||
* The implementation for this could be fstreams, zlib deflate, or any method filesystem access.
|
||||
* Reading of a large number of bytes ( > block size) is guaranteed to not significantly increase the read time and will likely result in a
|
||||
* direct passthrough to the underlying system. Small reads will be buffered, hence the name "block" reader.
|
||||
*/
|
||||
class block_reader
|
||||
{
|
||||
protected:
|
||||
// 32768 block size seems the fastest on my system
|
||||
unsigned long m_bufferSize;
|
||||
public:
|
||||
explicit block_reader(size_t bufferSize): m_bufferSize(bufferSize)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Reads bytes from the internal filesystem implementation
|
||||
* @param buffer buffer to copy the read bytes into
|
||||
* @param bytes number of bytes to read
|
||||
* @return status code. non-zero return codes indicates a failure has occurred.
|
||||
*/
|
||||
virtual int read(char* buffer, size_t bytes) = 0;
|
||||
|
||||
virtual size_t gcount() = 0;
|
||||
|
||||
virtual char get()
|
||||
{
|
||||
char c[1];
|
||||
read(c, 1);
|
||||
return c[0];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A buffered block writer without a definite backend implementation. Exactly the same as a block_reader but for writing to the filesystem.
|
||||
*/
|
||||
class block_writer
|
||||
{
|
||||
protected:
|
||||
unsigned long m_bufferSize;
|
||||
public:
|
||||
explicit block_writer(unsigned long bufferSize): m_bufferSize(bufferSize)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Writes the bytes to the filesystem backend implementation
|
||||
* @param buffer bytes to write
|
||||
* @param bytes number of bytes to write
|
||||
* @return non-zero code if failure
|
||||
*/
|
||||
virtual int write(char* buffer, size_t bytes) = 0;
|
||||
|
||||
virtual int put(char c)
|
||||
{
|
||||
char a[1];
|
||||
a[0] = c;
|
||||
return write(a, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the internal buffer is written to the filesystem.
|
||||
*/
|
||||
virtual void flush() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* fstream implementation of the block reader.
|
||||
*/
|
||||
class fstream_block_reader : public block_reader
|
||||
{
|
||||
private:
|
||||
std::fstream& m_stream;
|
||||
char* m_buffer = nullptr;
|
||||
size_t readIndex = 0;
|
||||
public:
|
||||
explicit fstream_block_reader(std::fstream& stream, size_t bufferSize = 131072);
|
||||
|
||||
explicit fstream_block_reader(fstream_block_reader& copy) = delete;
|
||||
|
||||
explicit fstream_block_reader(fstream_block_reader&& move) = delete;
|
||||
|
||||
fstream_block_reader& operator=(const fstream_block_reader& copy) = delete;
|
||||
|
||||
fstream_block_reader& operator=(const fstream_block_reader&& move) = delete;
|
||||
|
||||
int read(char* buffer, size_t bytes) override;
|
||||
|
||||
size_t gcount() final
|
||||
{
|
||||
return m_stream.gcount();
|
||||
}
|
||||
|
||||
~fstream_block_reader()
|
||||
{
|
||||
delete[] m_buffer;
|
||||
}
|
||||
};
|
||||
|
||||
class fstream_block_writer : public block_writer
|
||||
{
|
||||
private:
|
||||
std::fstream& m_stream;
|
||||
char* m_buffer;
|
||||
size_t writeIndex = 0;
|
||||
|
||||
void flush_internal();
|
||||
|
||||
public:
|
||||
explicit fstream_block_writer(std::fstream& stream, size_t bufferSize = 131072):
|
||||
block_writer(bufferSize), m_stream(stream), m_buffer(new char[bufferSize])
|
||||
{}
|
||||
|
||||
explicit fstream_block_writer(fstream_block_writer& copy) = delete;
|
||||
|
||||
explicit fstream_block_writer(fstream_block_writer&& move) = delete;
|
||||
|
||||
fstream_block_writer& operator=(const fstream_block_writer& copy) = delete;
|
||||
|
||||
fstream_block_writer& operator=(const fstream_block_writer&& move) = delete;
|
||||
|
||||
int write(char* buffer, size_t bytes) override;
|
||||
|
||||
inline void flush() override
|
||||
{
|
||||
flush_internal();
|
||||
}
|
||||
|
||||
~fstream_block_writer()
|
||||
{
|
||||
flush_internal();
|
||||
delete[] m_buffer;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //BLT_FILESYSTEM_H
|
|
@ -57,10 +57,11 @@ namespace blt
|
|||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
static inline constexpr double pow(int b, int p)
|
||||
|
||||
template<typename B, typename P, typename R = decltype(B() * P())>
|
||||
static inline constexpr R pow(B b, P p)
|
||||
{
|
||||
int collection = 1;
|
||||
R collection = 1;
|
||||
for (int i = 0; i < p; i++)
|
||||
collection *= b;
|
||||
return collection;
|
||||
|
@ -79,7 +80,7 @@ namespace blt
|
|||
return value;
|
||||
else
|
||||
{
|
||||
constexpr double multiplier = pow(10, decimal_places);
|
||||
constexpr double multiplier = pow(10.0, decimal_places);
|
||||
return ((int) (value * multiplier) + 1) / multiplier;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 67c24619e4f5ab2097b74cc397732c17a25d6944
|
||||
Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5
|
|
@ -1,54 +1,79 @@
|
|||
/*
|
||||
* Created by Brett on 29/01/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
* <Short Description>
|
||||
* Copyright (C) 2024 Brett Terpstra
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <blt/fs/filesystem.h>
|
||||
#include <cstring>
|
||||
#include "blt/std/logging.h"
|
||||
#include <blt/std/logging.h>
|
||||
|
||||
blt::fs::fstream_block_reader::fstream_block_reader(std::fstream& stream, size_t bufferSize) :
|
||||
block_reader(bufferSize), m_stream(stream), m_buffer(new char[bufferSize]) {
|
||||
if (!m_stream.good() || m_stream.fail())
|
||||
BLT_WARN("Provided std::fstream is not good! Clearing!");
|
||||
m_stream.clear();
|
||||
}
|
||||
|
||||
int blt::fs::fstream_block_reader::read(char* buffer, size_t bytes) {
|
||||
if (readIndex == 0)
|
||||
m_stream.read(m_buffer, (long) m_bufferSize);
|
||||
if (readIndex + bytes >= m_bufferSize) {
|
||||
// copy out all the data from the current buffer
|
||||
auto bytesLeft = m_bufferSize - readIndex;
|
||||
memcpy(buffer, m_buffer + readIndex, bytesLeft);
|
||||
readIndex = 0;
|
||||
// now to prevent large scale reading in small blocks, we should just read the entire thing into the buffer.
|
||||
m_stream.read(buffer + bytesLeft, (long) (bytes - bytesLeft));
|
||||
} else {
|
||||
// but in the case that the size of the data read is small, we should read in blocks and copy from that buffer
|
||||
// that should be quicker since file operations are slow.
|
||||
std::memcpy(buffer, m_buffer + readIndex, bytes);
|
||||
readIndex += bytes;
|
||||
namespace blt::fs
|
||||
{
|
||||
|
||||
fstream_block_reader::fstream_block_reader(std::fstream& stream, size_t bufferSize):
|
||||
block_reader(bufferSize), m_stream(stream), m_buffer(new char[bufferSize])
|
||||
{
|
||||
if (!m_stream.good() || m_stream.fail())
|
||||
BLT_WARN("Provided std::fstream is not good! Clearing!");
|
||||
m_stream.clear();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blt::fs::fstream_block_writer::write(char* buffer, size_t bytes) {
|
||||
if (writeIndex + bytes >= m_bufferSize) {
|
||||
// in an attempt to stay efficient we write out the old buffer and the new buffer
|
||||
// since there is a good chance there is more than a buffer's worth of data being written
|
||||
// otherwise the buffer is almost full and can be written anyway. (this might be bad for performance especially if the FS wants round numbers)
|
||||
|
||||
int fstream_block_reader::read(char* buffer, size_t bytes)
|
||||
{
|
||||
if (readIndex == 0)
|
||||
m_stream.read(m_buffer, (long) m_bufferSize);
|
||||
if (readIndex + bytes >= m_bufferSize)
|
||||
{
|
||||
// copy out all the data from the current buffer
|
||||
auto bytesLeft = m_bufferSize - readIndex;
|
||||
memcpy(buffer, m_buffer + readIndex, bytesLeft);
|
||||
readIndex = 0;
|
||||
// now to prevent large scale reading in small blocks, we should just read the entire thing into the buffer.
|
||||
m_stream.read(buffer + bytesLeft, (long) (bytes - bytesLeft));
|
||||
} else
|
||||
{
|
||||
// but in the case that the size of the data read is small, we should read in blocks and copy from that buffer
|
||||
// that should be quicker since file operations are slow.
|
||||
std::memcpy(buffer, m_buffer + readIndex, bytes);
|
||||
readIndex += bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fstream_block_writer::write(char* buffer, size_t bytes)
|
||||
{
|
||||
if (writeIndex + bytes >= m_bufferSize)
|
||||
{
|
||||
// in an attempt to stay efficient we write out the old buffer and the new buffer
|
||||
// since there is a good chance there is more than a buffer's worth of data being written
|
||||
// otherwise the buffer is almost full and can be written anyway. (this might be bad for performance especially if the FS wants round numbers)
|
||||
m_stream.write(m_buffer, (long) writeIndex);
|
||||
writeIndex = 0;
|
||||
m_stream.write(buffer, (long) bytes);
|
||||
} else
|
||||
{
|
||||
std::memcpy(m_buffer + writeIndex, buffer, bytes);
|
||||
writeIndex += bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fstream_block_writer::flush_internal()
|
||||
{
|
||||
m_stream.write(m_buffer, (long) writeIndex);
|
||||
writeIndex = 0;
|
||||
m_stream.write(buffer, (long) bytes);
|
||||
} else {
|
||||
std::memcpy(m_buffer + writeIndex, buffer, bytes);
|
||||
writeIndex += bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blt::fs::fstream_block_writer::flush_internal() {
|
||||
m_stream.write(m_buffer, (long) writeIndex);
|
||||
writeIndex = 0;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue