2016-11-21 12:14:09 +00:00
|
|
|
//
|
|
|
|
// FileHolder.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 21/11/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef FileHolder_hpp
|
|
|
|
#define FileHolder_hpp
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <cstdio>
|
2016-11-21 12:47:16 +00:00
|
|
|
#include <cstdint>
|
2017-09-23 00:28:11 +00:00
|
|
|
#include <mutex>
|
2017-07-22 20:02:25 +00:00
|
|
|
#include <string>
|
2017-11-03 02:32:00 +00:00
|
|
|
#include <vector>
|
2016-11-21 12:14:09 +00:00
|
|
|
|
|
|
|
namespace Storage {
|
|
|
|
|
2017-11-03 02:32:00 +00:00
|
|
|
class FileHolder final {
|
2016-11-21 12:14:09 +00:00
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
ErrorCantOpen = -1
|
|
|
|
};
|
2017-11-03 02:32:00 +00:00
|
|
|
|
|
|
|
enum class FileMode {
|
|
|
|
ReadWrite,
|
|
|
|
Read,
|
|
|
|
Rewrite
|
|
|
|
};
|
2016-11-21 12:14:09 +00:00
|
|
|
|
2017-11-03 02:32:00 +00:00
|
|
|
~FileHolder();
|
|
|
|
FileHolder(const std::string &file_name, FileMode ideal_mode = FileMode::ReadWrite);
|
2016-11-21 12:14:09 +00:00
|
|
|
|
2016-11-21 12:47:16 +00:00
|
|
|
/*!
|
2017-11-03 02:32:00 +00:00
|
|
|
Performs @c get8 four times on @c file, casting each result to a @c uint32_t
|
2016-11-21 12:47:16 +00:00
|
|
|
and returning the four assembled in little endian order.
|
|
|
|
*/
|
2017-11-03 02:32:00 +00:00
|
|
|
uint32_t get32le();
|
2016-11-21 12:47:16 +00:00
|
|
|
|
|
|
|
/*!
|
2017-11-03 02:32:00 +00:00
|
|
|
Performs @c get8 four times on @c file, casting each result to a @c uint32_t
|
2016-11-21 12:47:16 +00:00
|
|
|
and returning the four assembled in big endian order.
|
|
|
|
*/
|
2017-11-03 02:32:00 +00:00
|
|
|
uint32_t get32be();
|
2016-11-21 12:47:16 +00:00
|
|
|
|
|
|
|
/*!
|
2017-11-03 02:32:00 +00:00
|
|
|
Performs @c get8 three times on @c file, casting each result to a @c uint32_t
|
|
|
|
and returning the three assembled in little endian order.
|
2016-11-21 12:47:16 +00:00
|
|
|
*/
|
2017-11-03 02:32:00 +00:00
|
|
|
uint32_t get24le();
|
2016-11-21 12:47:16 +00:00
|
|
|
|
2017-07-22 20:02:25 +00:00
|
|
|
/*!
|
2017-11-03 02:32:00 +00:00
|
|
|
Performs @c get8 three times on @c file, casting each result to a @c uint32_t
|
|
|
|
and returning the three assembled in big endian order.
|
2017-07-22 20:02:25 +00:00
|
|
|
*/
|
2017-11-03 02:32:00 +00:00
|
|
|
uint32_t get24be();
|
2017-07-22 20:02:25 +00:00
|
|
|
|
2016-12-30 23:08:12 +00:00
|
|
|
/*!
|
2017-11-03 02:32:00 +00:00
|
|
|
Performs @c get8 two times on @c file, casting each result to a @c uint32_t
|
|
|
|
and returning the two assembled in little endian order.
|
2016-12-30 23:08:12 +00:00
|
|
|
*/
|
2017-11-03 02:32:00 +00:00
|
|
|
uint16_t get16le();
|
2016-12-30 23:08:12 +00:00
|
|
|
|
2017-10-03 23:36:06 +00:00
|
|
|
/*!
|
2017-11-03 02:32:00 +00:00
|
|
|
Performs @c get8 two times on @c file, casting each result to a @c uint32_t
|
|
|
|
and returning the two assembled in big endian order.
|
2017-10-03 23:36:06 +00:00
|
|
|
*/
|
2017-11-03 02:32:00 +00:00
|
|
|
uint16_t get16be();
|
|
|
|
|
|
|
|
/*! Reads a single byte from @c file */
|
|
|
|
uint8_t get8();
|
|
|
|
|
|
|
|
std::vector<uint8_t> read(size_t size);
|
|
|
|
size_t read(uint8_t *buffer, size_t size);
|
|
|
|
size_t write(const std::vector<uint8_t> &);
|
|
|
|
size_t write(const uint8_t *buffer, size_t size);
|
|
|
|
|
|
|
|
void seek(long offset, int whence);
|
|
|
|
long tell();
|
|
|
|
void flush();
|
|
|
|
bool eof();
|
2017-10-03 23:36:06 +00:00
|
|
|
|
2017-07-17 11:34:10 +00:00
|
|
|
class BitStream {
|
|
|
|
public:
|
|
|
|
uint8_t get_bits(int q) {
|
|
|
|
uint8_t result = 0;
|
|
|
|
while(q--) {
|
2017-10-22 01:50:53 +00:00
|
|
|
result = static_cast<uint8_t>((result << 1) | get_bit());
|
2017-07-17 11:34:10 +00:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2017-11-03 02:32:00 +00:00
|
|
|
BitStream(FILE *file, bool lsb_first) :
|
|
|
|
file_(file),
|
|
|
|
lsb_first_(lsb_first),
|
|
|
|
next_value_(0),
|
|
|
|
bits_remaining_(0) {}
|
|
|
|
friend FileHolder;
|
|
|
|
|
2017-07-17 11:34:10 +00:00
|
|
|
FILE *file_;
|
|
|
|
bool lsb_first_;
|
|
|
|
uint8_t next_value_;
|
|
|
|
int bits_remaining_;
|
|
|
|
|
|
|
|
uint8_t get_bit() {
|
|
|
|
if(!bits_remaining_) {
|
|
|
|
bits_remaining_ = 8;
|
2017-10-22 01:50:53 +00:00
|
|
|
next_value_ = static_cast<uint8_t>(fgetc(file_));
|
2017-07-17 11:34:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t bit;
|
|
|
|
if(lsb_first_) {
|
|
|
|
bit = next_value_ & 1;
|
|
|
|
next_value_ >>= 1;
|
|
|
|
} else {
|
|
|
|
bit = next_value_ >> 7;
|
|
|
|
next_value_ <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bits_remaining_--;
|
|
|
|
|
|
|
|
return bit;
|
|
|
|
}
|
|
|
|
};
|
2017-11-03 02:32:00 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Obtains a BitStream for reading from the file from the current reading cursor.
|
|
|
|
*/
|
|
|
|
BitStream get_bitstream(bool lsb_first);
|
2017-07-17 11:34:10 +00:00
|
|
|
|
2017-11-03 02:32:00 +00:00
|
|
|
/*!
|
|
|
|
Reads @c length bytes from the file and compares them to the first
|
|
|
|
@c length bytes of @c signature. If @c length is 0, it is computed
|
|
|
|
as the length of @c signature not including the terminating null.
|
|
|
|
|
|
|
|
@returns @c true if the bytes read match the signature; @c false otherwise.
|
|
|
|
*/
|
|
|
|
bool check_signature(const char *signature, size_t length = 0);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Determines and returns the file extension — everything from the final character
|
|
|
|
back to the first dot. The string is converted to lowercase before being returned.
|
|
|
|
*/
|
|
|
|
std::string extension();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Ensures the file is at least @c length bytes long, appending 0s until it is
|
|
|
|
if necessary.
|
|
|
|
*/
|
|
|
|
void ensure_is_at_least_length(long length);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@returns @c true if this file is read-only; @c false otherwise.
|
|
|
|
*/
|
|
|
|
bool get_is_known_read_only();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@returns the stat struct describing this file.
|
|
|
|
*/
|
|
|
|
struct stat &stats();
|
|
|
|
|
|
|
|
std::mutex &get_file_access_mutex();
|
2017-07-22 20:02:25 +00:00
|
|
|
|
2017-10-03 23:36:06 +00:00
|
|
|
private:
|
2017-11-03 02:32:00 +00:00
|
|
|
FILE *file_ = nullptr;
|
|
|
|
const std::string name_;
|
|
|
|
|
|
|
|
struct stat file_stats_;
|
|
|
|
bool is_read_only_ = false;
|
|
|
|
|
|
|
|
std::mutex file_access_mutex_;
|
2016-11-21 12:14:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* FileHolder_hpp */
|