Base: Add ASCIIInputStream
Based on the modifications to InputStream from the LinkStage3 fork. Needed for correct restoration of StringHasher.
This commit is contained in:
@@ -621,6 +621,7 @@ void StringHasher::RestoreDocFile(Base::Reader& reader)
|
||||
|
||||
void StringHasher::restoreStreamNew(std::istream& stream, std::size_t count)
|
||||
{
|
||||
Base::ASCIIInputStream asciiStream (stream);
|
||||
_hashes->clear();
|
||||
std::string content;
|
||||
boost::io::ios_flags_saver ifs(stream);
|
||||
@@ -688,7 +689,7 @@ void StringHasher::restoreStreamNew(std::istream& stream, std::size_t count)
|
||||
}
|
||||
|
||||
if (!d.isPostfixed()) {
|
||||
stream >> content;
|
||||
asciiStream >> content;
|
||||
if (d.isHashed() || d.isBinary()) {
|
||||
d._data = QByteArray::fromBase64(content.c_str());
|
||||
}
|
||||
@@ -815,7 +816,12 @@ void StringHasher::Restore(Base::XMLReader& reader)
|
||||
|
||||
std::size_t count = reader.getAttributeAsUnsigned("count");
|
||||
if (newTag) {
|
||||
try {
|
||||
restoreStreamNew(reader.beginCharStream(), count);
|
||||
} catch (const Base::Exception &e) {
|
||||
e.ReportException();
|
||||
FC_ERR("Failed to restore string table: full-document recompute strongly recommended.");
|
||||
}
|
||||
reader.readEndElement("StringHasher2");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -832,3 +832,65 @@ std::streambuf::pos_type Streambuf::seekpos(std::streambuf::pos_type pos,
|
||||
{
|
||||
return seekoff(pos, std::ios_base::beg);
|
||||
}
|
||||
|
||||
// The custom string handler written by realthunder for the LinkStage3 toponaming code, to handle
|
||||
// reading multi-line strings directly into a std::string. Imported from LinkStage3 and refactored
|
||||
// during the TNP mitigation project in February 2024.
|
||||
ASCIIInputStream& ASCIIInputStream::operator>>(std::string& outputString)
|
||||
{
|
||||
uint32_t numberOfLines;
|
||||
char inputChar;
|
||||
// The number of lines is followed by a colon as the delimiter. The string itself is then
|
||||
// allowed to start with any character.
|
||||
_in >> numberOfLines >> inputChar;
|
||||
|
||||
_ss.str("");
|
||||
for (uint32_t lineNumber = 0; lineNumber < numberOfLines && _in; ++lineNumber) {
|
||||
while (true) {
|
||||
if (!_in.get(inputChar)) {
|
||||
break;
|
||||
}
|
||||
// Normalize \r\n to \n
|
||||
if (inputChar == '\r') {
|
||||
if (!_in.get(inputChar)) {
|
||||
break;
|
||||
}
|
||||
if (inputChar == '\n') {
|
||||
break;
|
||||
}
|
||||
_ss.put('\r');
|
||||
_ss.put(inputChar);
|
||||
}
|
||||
else {
|
||||
_ss.put(inputChar);
|
||||
if (inputChar == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reading the last line
|
||||
while (_in.get(inputChar)) {
|
||||
// Normalize \r\n to \n, but DO NOT insert '\n' into the extracted
|
||||
// line, because the last '\n' is inserted by us (See OutputStream
|
||||
// operator>>(const char*) above)
|
||||
if (inputChar == '\r') {
|
||||
if (!_in.get(inputChar)) {
|
||||
break;
|
||||
}
|
||||
if (inputChar == '\n') {
|
||||
break;
|
||||
}
|
||||
_ss.put('\r');
|
||||
}
|
||||
else if (inputChar == '\n') {
|
||||
break;
|
||||
}
|
||||
|
||||
_ss.put(inputChar);
|
||||
}
|
||||
|
||||
outputString = _ss.str();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "FileInfo.h"
|
||||
@@ -140,6 +141,121 @@ private:
|
||||
std::istream& _in;
|
||||
};
|
||||
|
||||
/**
|
||||
* The ASCIIInputStream class provides reading of ASCII data from an istream, with custom handling
|
||||
* for std::string to make it easier to read a single multi-line (or multi-word) string. This is
|
||||
* designed for easy compatibility with the LinkStage3 implementation of the InputStream class, used
|
||||
* to store StringHashers for the toponaming mitigation technique.
|
||||
*/
|
||||
class BaseExport ASCIIInputStream: public Stream
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
* @param rin: upstream input
|
||||
*/
|
||||
explicit ASCIIInputStream(std::istream& rin)
|
||||
: _in(rin)
|
||||
{}
|
||||
|
||||
ASCIIInputStream(const ASCIIInputStream&) = delete;
|
||||
|
||||
ASCIIInputStream(const ASCIIInputStream&&) noexcept = delete;
|
||||
|
||||
void operator=(const ASCIIInputStream&) = delete;
|
||||
|
||||
void operator=(const ASCIIInputStream&&) = delete;
|
||||
|
||||
~ASCIIInputStream() override = default;
|
||||
|
||||
ASCIIInputStream& operator>>(bool& input)
|
||||
{
|
||||
_in >> input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(int8_t& ch)
|
||||
{
|
||||
int index {};
|
||||
_in >> index;
|
||||
ch = (int8_t)index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(uint8_t& uch)
|
||||
{
|
||||
unsigned uns {};
|
||||
_in >> uns;
|
||||
uch = (uint8_t)uns;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(int16_t& int16)
|
||||
{
|
||||
_in >> int16;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(uint16_t& us)
|
||||
{
|
||||
_in >> us;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(int32_t& int32)
|
||||
{
|
||||
_in >> int32;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(uint32_t& ui)
|
||||
{
|
||||
_in >> ui;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(int64_t& int64)
|
||||
{
|
||||
_in >> int64;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(uint64_t& ul)
|
||||
{
|
||||
_in >> ul;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(float& flt)
|
||||
{
|
||||
_in >> flt;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(double& dbl)
|
||||
{
|
||||
_in >> dbl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASCIIInputStream& operator>>(std::string& str);
|
||||
|
||||
ASCIIInputStream& operator>>(char& chr)
|
||||
{
|
||||
chr = (char)_in.get();
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
// test if _Ipfx succeeded
|
||||
return !_in.eof();
|
||||
}
|
||||
|
||||
private:
|
||||
std::istream& _in;
|
||||
std::ostringstream _ss;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user