lib/file: implement open function
parent
e8d41efeef
commit
9610f4a4a2
|
@ -39,6 +39,7 @@ COMPILE_COMMANDS=(
|
||||||
"$CXX_WITH_FLAGS src/test/nbt_write_string_failure_mode.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_write_string_failure_mode"
|
"$CXX_WITH_FLAGS src/test/nbt_write_string_failure_mode.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_write_string_failure_mode"
|
||||||
"$CXX_WITH_FLAGS src/test/nbt_tags.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_tags"
|
"$CXX_WITH_FLAGS src/test/nbt_tags.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_tags"
|
||||||
"$CXX_WITH_FLAGS src/test/nbt_size_helpers.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_size_helpers"
|
"$CXX_WITH_FLAGS src/test/nbt_size_helpers.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -o bin/test/nbt_size_helpers"
|
||||||
|
"$CXX_WITH_FLAGS src/test/file.cpp -I./include -Lbin/lib -l:file.so -o bin/test/file"
|
||||||
)
|
)
|
||||||
for command in ${!COMPILE_COMMANDS[@]}; do
|
for command in ${!COMPILE_COMMANDS[@]}; do
|
||||||
echo "${COMPILE_COMMANDS[command]}"
|
echo "${COMPILE_COMMANDS[command]}"
|
||||||
|
|
|
@ -91,6 +91,10 @@ namespace ErrorCodes {
|
||||||
|
|
||||||
const uint8_t INVALID_TYPE = 8;
|
const uint8_t INVALID_TYPE = 8;
|
||||||
|
|
||||||
|
//file errors
|
||||||
|
const uint8_t FILE_READ_FAILED = 9;
|
||||||
|
const uint8_t FILE_NOT_FOUND = 10;
|
||||||
|
|
||||||
const uint8_t UNIMPLEMENTED = 254;
|
const uint8_t UNIMPLEMENTED = 254;
|
||||||
|
|
||||||
const uint8_t UNKNOWN = 255;
|
const uint8_t UNKNOWN = 255;
|
||||||
|
|
154
src/lib/file.cpp
154
src/lib/file.cpp
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2022, FOSS-VG Developers and Contributers
|
// Copyright 2022, FOSS-VG Developers and Contributers
|
||||||
//
|
//
|
||||||
// Author(s):
|
// Author(s):
|
||||||
// <add authors here>
|
// Bodgemaster, Shwoomple
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify it
|
// This program is free software: you can redistribute it and/or modify it
|
||||||
// under the terms of the GNU Affero General Public License as published
|
// under the terms of the GNU Affero General Public License as published
|
||||||
|
@ -16,4 +16,156 @@
|
||||||
// version 3 along with this program.
|
// version 3 along with this program.
|
||||||
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
|
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <exception>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "tinyutf8/tinyutf8.h"
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
|
File::File(std::string path, char mode, uint64_t cursorPosition): mode(mode), path(path), cursorPosition(cursorPosition){
|
||||||
|
switch(this->mode){
|
||||||
|
case 'w':
|
||||||
|
case 'm':
|
||||||
|
this->fileStream.open(path, std::fstream::out | std::fstream::binary);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'e':
|
||||||
|
this->fileStream.open(path, std::fstream::in | std::fstream::binary);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
this->fileStream.open(path, std::fstream::app | std::fstream::binary);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
std::filesystem::path filePath = path;
|
||||||
|
this->size = ErrorOr<uint64_t>(std::filesystem::file_size(filePath));
|
||||||
|
}catch(std::exception e){
|
||||||
|
this->size = ErrorOr<uint64_t>(true, ErrorCodes::FILE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File::File(const File& file){
|
||||||
|
this->mode = file.getMode();
|
||||||
|
this->isOpen = file.isOpen;
|
||||||
|
this->eof = file.eof;
|
||||||
|
this->path = file.path;
|
||||||
|
this->cursorPosition = file.cursorPosition;
|
||||||
|
this->size = file.size;
|
||||||
|
|
||||||
|
if(this->isOpen){
|
||||||
|
this->open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File& File::operator=(const File& file){
|
||||||
|
File cpFile(file);
|
||||||
|
return cpFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::open(){
|
||||||
|
switch(this->mode){
|
||||||
|
case 'w':
|
||||||
|
case 'm':
|
||||||
|
this->fileStream.open(this->path, std::fstream::out | std::fstream::binary);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'e':
|
||||||
|
this->fileStream.open(this->path, std::fstream::in | std::fstream::binary);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
this->fileStream.open(this->path, std::fstream::app | std::fstream::binary);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
std::filesystem::path filePath = this->path;
|
||||||
|
this->size = ErrorOr<uint64_t>(std::filesystem::file_size(filePath));
|
||||||
|
}catch(std::exception e){
|
||||||
|
this->size = ErrorOr<uint64_t>(true, ErrorCodes::FILE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::close(){
|
||||||
|
this->fileStream.close();
|
||||||
|
this->isOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char File::getMode() const{
|
||||||
|
return this->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<uint8_t> File::readByte(){
|
||||||
|
if(this->size.isError){
|
||||||
|
return ErrorOr<uint8_t>(true, this->size.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->cursorPosition += 1;
|
||||||
|
this->fileStream.seekg(this->cursorPosition);
|
||||||
|
|
||||||
|
char* byte = new char;
|
||||||
|
try{
|
||||||
|
this->fileStream.read(byte, 1);
|
||||||
|
delete byte;
|
||||||
|
}catch(std::exception e){
|
||||||
|
return ErrorOr<uint8_t>(true, ErrorCodes::FILE_READ_FAILED);
|
||||||
|
}
|
||||||
|
return ErrorOr<uint8_t>((uint8_t) *byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<std::vector<uint8_t>> File::read(uint64_t bytes){
|
||||||
|
if(this->size.isError){
|
||||||
|
return ErrorOr<std::vector<uint8_t>>(true, this->size.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->cursorPosition += 1;
|
||||||
|
this->fileStream.seekg(this->cursorPosition);
|
||||||
|
|
||||||
|
char* buffer = new char[bytes];
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
try{
|
||||||
|
this->fileStream.read(buffer, bytes);
|
||||||
|
for(uint64_t i=0; i<bytes; i++){
|
||||||
|
data.push_back((uint8_t) buffer[i]);
|
||||||
|
}
|
||||||
|
delete[] buffer;
|
||||||
|
}catch(std::exception e){
|
||||||
|
return ErrorOr<std::vector<uint8_t>>(true, ErrorCodes::FILE_READ_FAILED);
|
||||||
|
}
|
||||||
|
return ErrorOr<std::vector<uint8_t>>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<tiny_utf8::string> File::readString(uint64_t bytes){
|
||||||
|
if(this->size.isError){
|
||||||
|
return ErrorOr<tiny_utf8::string>(true, this->size.errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<std::vector<uint8_t>> data = this->read(bytes);
|
||||||
|
if(data.isError){
|
||||||
|
return ErrorOr<tiny_utf8::string>(true, data.errorCode);
|
||||||
|
}
|
||||||
|
std::string s;
|
||||||
|
for(auto byte: data.value){
|
||||||
|
s.push_back(byte);
|
||||||
|
}
|
||||||
|
return ErrorOr<tiny_utf8::string>(tiny_utf8::string(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<File*> File::open(std::string path, char mode, uint64_t startPosition){
|
||||||
|
File *file = new File(path, mode, startPosition);
|
||||||
|
file->isOpen = true;
|
||||||
|
file->eof = false;
|
||||||
|
|
||||||
|
if(file->size.isError){
|
||||||
|
return ErrorOr<File*>(true, file->size.errorCode); //if file is not found
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorOr<File*>(file);
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2022, FOSS-VG Developers and Contributers
|
// Copyright 2022, FOSS-VG Developers and Contributers
|
||||||
//
|
//
|
||||||
// Author(s):
|
// Author(s):
|
||||||
// BodgeMaster
|
// BodgeMaster, Shwoomple
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify it
|
// This program is free software: you can redistribute it and/or modify it
|
||||||
// under the terms of the GNU Affero General Public License as published
|
// under the terms of the GNU Affero General Public License as published
|
||||||
|
@ -18,31 +18,39 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <tinyutf8/tinyutf8.h>
|
#include <tinyutf8/tinyutf8.h>
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
|
||||||
|
|
||||||
class File {
|
class File {
|
||||||
private:
|
private:
|
||||||
//TODO: add other necessary internals to this section as needed
|
//TODO: add other necessary internals to this section as needed
|
||||||
char mode;
|
char mode;
|
||||||
|
std::fstream fileStream;
|
||||||
//TODO: add other necessary details to the constructor as needed
|
//TODO: add other necessary details to the constructor as needed
|
||||||
// For example, the fstream (or whatever mechanism is used) needs
|
// For example, the fstream (or whatever mechanism is used) needs
|
||||||
// to be handed over from File::open() to the File object.
|
// to be handed over from File::open() to the File object.
|
||||||
//
|
//
|
||||||
// Remember to add a destructor to the public section if pointers
|
// Remember to add a destructor to the public section if pointers
|
||||||
// are to be used.
|
// are to be used.
|
||||||
File(char mode, uint64_t cursorPosition);
|
File(std::string path, char mode, uint64_t cursorPosition);
|
||||||
public:
|
public:
|
||||||
bool isOpen;
|
bool isOpen;
|
||||||
bool eof;
|
bool eof;
|
||||||
|
std::string path;
|
||||||
uint64_t cursorPosition;
|
uint64_t cursorPosition;
|
||||||
// may be error if not a regular file or size cannot be determined
|
// may be error if not a regular file or size cannot be determined
|
||||||
ErrorOr<uint64_t> size;
|
ErrorOr<uint64_t> size;
|
||||||
|
|
||||||
|
File() = default;
|
||||||
|
File(const File& file);
|
||||||
|
File& operator=(const File& file);
|
||||||
void open();
|
void open();
|
||||||
void close();
|
void close();
|
||||||
|
char getMode() const;
|
||||||
|
|
||||||
// only applicable to read and edit modes
|
// only applicable to read and edit modes
|
||||||
// moves the cursor to the right of the read section
|
// moves the cursor to the right of the read section
|
||||||
|
@ -86,5 +94,5 @@ class File {
|
||||||
//
|
//
|
||||||
// A startPosition of 0xFFFFFFFF is considered to be the end of
|
// A startPosition of 0xFFFFFFFF is considered to be the end of
|
||||||
// the file whatever its size.
|
// the file whatever its size.
|
||||||
static ErrorOr<File> open(std::string path, char mode, uint64_t startPosition=0);
|
static ErrorOr<File*> open(std::string path, char mode, uint64_t startPosition=0);
|
||||||
};
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2022, FOSS-VG Developers and Contributers
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Affero General Public License as published
|
||||||
|
// by the Free Software Foundation, version 3.
|
||||||
|
//
|
||||||
|
// 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// version 3 along with this program.
|
||||||
|
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
|
||||||
|
#include "assert.hpp"
|
||||||
|
#include "tinyutf8/tinyutf8.h"
|
||||||
|
#include "../lib/file.hpp"
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
std::cout << "################################################################################" << std::endl;
|
||||||
|
std::cout << "File tests" << std::endl;
|
||||||
|
std::cout << "################################################################################" << std::endl;
|
||||||
|
File *file;
|
||||||
|
|
||||||
|
//read test
|
||||||
|
file = File::open("../../resources/unicode_data/normal_utf-8", 'r').value;
|
||||||
|
tiny_utf8::string data = file->readString(file->size.value).value;
|
||||||
|
std::cout << file->size.isError << std::endl;
|
||||||
|
std::cout << data << std::endl;
|
||||||
|
}
|
Loading…
Reference in New Issue