refactor: Add StreamReader and StreamWriter classes
This commit is contained in:
parent
74267e1123
commit
a182063e2e
11 changed files with 500 additions and 1 deletions
|
@ -48,19 +48,25 @@ add_definitions(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
|
|||
## libsystem static library
|
||||
|
||||
set(SYSTEM_HEADERS
|
||||
src/system/endianutil.h
|
||||
src/system/jobs.h
|
||||
src/system/log.h
|
||||
src/system/pathutil.h
|
||||
src/system/random.h
|
||||
src/system/streamreader.h
|
||||
src/system/streamutil.h
|
||||
src/system/streamwriter.h
|
||||
src/system/types.h)
|
||||
|
||||
set(SYSTEM_SOURCES
|
||||
src/system/endianutil.cpp
|
||||
src/system/jobs.cpp
|
||||
src/system/log.cpp
|
||||
src/system/pathutil.cpp
|
||||
src/system/random.cpp
|
||||
src/system/streamutil.cpp)
|
||||
src/system/streamreader.cpp
|
||||
src/system/streamutil.cpp
|
||||
src/system/streamwriter.cpp)
|
||||
|
||||
add_library(libsystem STATIC ${SYSTEM_HEADERS} ${SYSTEM_SOURCES})
|
||||
set_target_properties(libsystem PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
|
@ -388,6 +394,7 @@ set(GAME_HEADERS
|
|||
src/game/room.h
|
||||
src/game/rp/classes.h
|
||||
src/game/rp/types.h
|
||||
src/game/savfile.h
|
||||
src/game/script/routines.h
|
||||
src/game/script/util.h
|
||||
src/game/types.h)
|
||||
|
@ -462,6 +469,7 @@ set(GAME_SOURCES
|
|||
src/game/portraits.cpp
|
||||
src/game/room.cpp
|
||||
src/game/rp/classes.cpp
|
||||
src/game/savfile.cpp
|
||||
src/game/script/routines.cpp
|
||||
src/game/script/routines_common.cpp
|
||||
src/game/script/routines_kotor.cpp
|
||||
|
|
26
src/game/savfile.cpp
Normal file
26
src/game/savfile.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 "savfile.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
35
src/game/savfile.h
Normal file
35
src/game/savfile.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace reone {
|
||||
|
||||
namespace game {
|
||||
|
||||
class SavFile {
|
||||
public:
|
||||
SavFile() = default;
|
||||
|
||||
private:
|
||||
SavFile(const SavFile &) = delete;
|
||||
SavFile &operator=(const SavFile &) = delete;
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
||||
} // namespace reone
|
93
src/system/endianutil.cpp
Normal file
93
src/system/endianutil.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 "endianutil.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace reone {
|
||||
|
||||
template <>
|
||||
void swapBytes(uint16_t &val) {
|
||||
val = ((val >> 8) & 0xff) | ((val & 0xff) << 8);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swapBytes(uint32_t &val) {
|
||||
val = ((val >> 24) & 0xff) |
|
||||
(((val >> 16) & 0xff) << 8) |
|
||||
(((val >> 8) & 0xff) << 16) |
|
||||
((val & 0xff) << 24);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swapBytes(uint64_t &val) {
|
||||
val = ((val >> 56) & 0xff) |
|
||||
(((val >> 48) & 0xff) << 8) |
|
||||
(((val >> 40) & 0xff) << 16) |
|
||||
(((val >> 32) & 0xff) << 24) |
|
||||
(((val >> 24) & 0xff) << 32) |
|
||||
(((val >> 16) & 0xff) << 40) |
|
||||
(((val >> 8) & 0xff) << 48) |
|
||||
((val & 0xff) << 56);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swapBytes(int16_t &val) {
|
||||
val = ((val >> 8) & 0xff) | ((val & 0xff) << 8);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swapBytes(int32_t &val) {
|
||||
val = ((val >> 24) & 0xff) |
|
||||
(((val >> 16) & 0xff) << 8) |
|
||||
(((val >> 8) & 0xff) << 16) |
|
||||
((val & 0xff) << 24);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swapBytes(int64_t &val) {
|
||||
val = ((val >> 56) & 0xff) |
|
||||
(((val >> 48) & 0xff) << 8) |
|
||||
(((val >> 40) & 0xff) << 16) |
|
||||
(((val >> 32) & 0xff) << 24) |
|
||||
(((val >> 24) & 0xff) << 32) |
|
||||
(((val >> 16) & 0xff) << 40) |
|
||||
(((val >> 8) & 0xff) << 48) |
|
||||
((val & 0xff) << 56);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swapBytes(float &val) {
|
||||
uint32_t uintVal;
|
||||
memcpy(&uintVal, &val, 4);
|
||||
swapBytes(uintVal);
|
||||
memcpy(&val, &uintVal, 4);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swapBytes(double &val) {
|
||||
uint64_t uintVal;
|
||||
memcpy(&uintVal, &val, 8);
|
||||
swapBytes(uintVal);
|
||||
memcpy(&val, &uintVal, 8);
|
||||
}
|
||||
|
||||
} // namespace reone
|
25
src/system/endianutil.h
Normal file
25
src/system/endianutil.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace reone {
|
||||
|
||||
template <class T>
|
||||
void swapBytes(T &val);
|
||||
|
||||
} // namespace reone
|
118
src/system/streamreader.cpp
Normal file
118
src/system/streamreader.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 "streamreader.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "endianutil.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace reone {
|
||||
|
||||
StreamReader::StreamReader(const shared_ptr<istream> &stream, Endianess endianess) :
|
||||
_stream(stream),
|
||||
_endianess(endianess) {
|
||||
|
||||
if (!stream) {
|
||||
throw invalid_argument("stream must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t StreamReader::getByte() {
|
||||
uint8_t val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 1);
|
||||
return val;
|
||||
}
|
||||
|
||||
uint16_t StreamReader::getUint16() {
|
||||
uint16_t val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 2);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T StreamReader::fixEndianess(T val) {
|
||||
if (!isSameEndianess()) {
|
||||
swapBytes(val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
bool StreamReader::isSameEndianess() const {
|
||||
return _endianess == Endianess::Little;
|
||||
}
|
||||
|
||||
uint32_t StreamReader::getUint32() {
|
||||
uint32_t val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 4);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
uint64_t StreamReader::getUint64() {
|
||||
uint64_t val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 8);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
int16_t StreamReader::getInt16() {
|
||||
int16_t val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 2);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
int32_t StreamReader::getInt32() {
|
||||
int32_t val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 4);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
int64_t StreamReader::getInt64() {
|
||||
int64_t val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 8);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
float StreamReader::getFloat() {
|
||||
float val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 4);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
double StreamReader::getDouble() {
|
||||
double val;
|
||||
_stream->read(reinterpret_cast<char *>(&val), 8);
|
||||
return fixEndianess(val);
|
||||
}
|
||||
|
||||
string StreamReader::getCString() {
|
||||
stringbuf ss;
|
||||
_stream->get(ss, '\0');
|
||||
_stream->seekg(1, ios::cur);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
string StreamReader::getString(int len) {
|
||||
string val;
|
||||
val.resize(len);
|
||||
_stream->read(&val[0], len);
|
||||
return move(val);
|
||||
}
|
||||
|
||||
} // namespace reone
|
58
src/system/streamreader.h
Normal file
58
src/system/streamreader.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
class StreamReader {
|
||||
public:
|
||||
StreamReader(const std::shared_ptr<std::istream> &stream, Endianess endianess = Endianess::Little);
|
||||
|
||||
uint8_t getByte();
|
||||
uint16_t getUint16();
|
||||
uint32_t getUint32();
|
||||
uint64_t getUint64();
|
||||
int16_t getInt16();
|
||||
int32_t getInt32();
|
||||
int64_t getInt64();
|
||||
float getFloat();
|
||||
double getDouble();
|
||||
std::string getCString();
|
||||
std::string getString(int len);
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::istream> _stream;
|
||||
Endianess _endianess;
|
||||
|
||||
StreamReader(const StreamReader &) = delete;
|
||||
StreamReader &operator=(const StreamReader &) = delete;
|
||||
|
||||
bool isSameEndianess() const;
|
||||
|
||||
template <class T>
|
||||
T fixEndianess(T val);
|
||||
};
|
||||
|
||||
} // namespace reone
|
38
src/system/streamwriter.cpp
Normal file
38
src/system/streamwriter.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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 "streamwriter.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace reone {
|
||||
|
||||
StreamWriter::StreamWriter(const shared_ptr<ostream> &stream, Endianess endianess) :
|
||||
_stream(stream),
|
||||
_endianess(endianess) {
|
||||
|
||||
if (!stream) {
|
||||
throw invalid_argument("stream must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
void StreamWriter::putByte(uint8_t val) {
|
||||
}
|
||||
|
||||
} // namespace reone
|
42
src/system/streamwriter.h
Normal file
42
src/system/streamwriter.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
namespace reone {
|
||||
|
||||
class StreamWriter {
|
||||
public:
|
||||
StreamWriter(const std::shared_ptr<std::ostream> &stream, Endianess endianess = Endianess::Little);
|
||||
|
||||
void putByte(uint8_t val);
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::ostream> _stream;
|
||||
Endianess _endianess;
|
||||
|
||||
StreamWriter(const StreamWriter &) = delete;
|
||||
StreamWriter &operator=(const StreamWriter &) = delete;
|
||||
};
|
||||
|
||||
} // namespace reone
|
|
@ -21,6 +21,11 @@
|
|||
|
||||
namespace reone {
|
||||
|
||||
enum class Endianess {
|
||||
Little,
|
||||
Big
|
||||
};
|
||||
|
||||
typedef std::vector<char> ByteArray;
|
||||
|
||||
} // namespace reone
|
||||
|
|
51
tests/streamreader.cpp
Normal file
51
tests/streamreader.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Vsevolod Kremianskii
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE streamreader
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include "../src/system/streamreader.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone;
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_get_little_endian) {
|
||||
shared_ptr<istringstream> stream(new istringstream(string("\x01" "\xe8\x03" "\xa0\x86\x01\x00" "\x00\xe4\x0b\x54\x02\x00\x00\x00" "\x60\x79\xfe\xff" "\x00\x00\x80\x3f" "abc\0defgh", 32)));
|
||||
StreamReader reader(stream);
|
||||
BOOST_TEST((reader.getByte() == 0x01));
|
||||
BOOST_TEST((reader.getUint16() == 1000u));
|
||||
BOOST_TEST((reader.getUint32() == 100000u));
|
||||
BOOST_TEST((reader.getUint64() == 10000000000u));
|
||||
BOOST_TEST((reader.getInt32() == -100000));
|
||||
BOOST_TEST((reader.getFloat() == 1.0f));
|
||||
BOOST_TEST((reader.getCString() == "abc"));
|
||||
BOOST_TEST((reader.getString(3) == "def"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_get_big_endian) {
|
||||
shared_ptr<istringstream> stream(new istringstream(string("\x03\xe8" "\x00\x01\x86\xa0" "\x00\x00\x00\x02\x54\x0b\xe4\x00" "\xff\xfe\x79\x60" "\x3f\x80\x00\x00", 22)));
|
||||
StreamReader reader(stream, Endianess::Big);
|
||||
BOOST_TEST((reader.getUint16() == 1000u));
|
||||
BOOST_TEST((reader.getUint32() == 100000u));
|
||||
BOOST_TEST((reader.getUint64() == 10000000000u));
|
||||
BOOST_TEST((reader.getInt32() == -100000));
|
||||
BOOST_TEST((reader.getFloat() == 1.0f));
|
||||
}
|
Loading…
Reference in a new issue