Skip to content

Commit

Permalink
add range checks
Browse files Browse the repository at this point in the history
  • Loading branch information
enderslash1010 committed Nov 23, 2024
1 parent 2c28b60 commit 1066ee0
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 90 deletions.
36 changes: 23 additions & 13 deletions gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MainWindow::MainWindow(QWidget *parent)

QObject::connect(ui->THUMLevel, &QLineEdit::editingFinished, this, &MainWindow::updateText);
ui->THUMLevel->setProperty(SAVE_FIELD_PROPERTY, THUMLevel);
saveFieldMap.insert({THUMLevel, {ui->THUMLevel, Type::UINT_T}});
saveFieldMap.insert({THUMLevel, {ui->THUMLevel, Type::INT_T}});

QObject::connect(ui->THUMNameString, &QLineEdit::editingFinished, this, &MainWindow::updateText);
ui->THUMNameString->setProperty(SAVE_FIELD_PROPERTY, THUMNameString);
Expand All @@ -25,6 +25,11 @@ MainWindow::~MainWindow() {
delete ui;
}

void MainWindow::showStatusBarMessage(std::string str)
{
ui->statusbar->showMessage(QString::fromStdString(str));
}

QString MainWindow::getField(SaveFieldID sfID)
{
return this->saveFieldMap.at(sfID).first->getField();
Expand Down Expand Up @@ -71,9 +76,9 @@ void MainWindow::actionOpen()

for (int i = 0; i < LAST_INDEX; i++) setField((SaveFieldID)i);

ui->statusbar->showMessage(QString::fromStdString("Successfully opened " + fileName.toStdString()));
showStatusBarMessage("Successfully opened " + fileName.toStdString());
} catch (std::runtime_error e) {
ui->statusbar->showMessage(QString::fromStdString(e.what()));
showStatusBarMessage(e.what());
}
}

Expand All @@ -82,15 +87,14 @@ void MainWindow::actionSave()
if (saveFile != NULL)
{
saveFile->saveToFile();
ui->statusbar->showMessage(QString::fromStdString("Saved to file " + saveFile->getFileName()));
showStatusBarMessage("Saved to file " + saveFile->getFileName());
}
else
{
ui->statusbar->showMessage(QString::fromStdString("No save file opened"));
showStatusBarMessage("No save file opened");
}
}

// TODO: use a different signal so this is called on focus lost/enter
void MainWindow::updateText()
{
QObject* obj = sender();
Expand All @@ -100,23 +104,24 @@ void MainWindow::updateText()

std::vector<uint8_t> previousBytes = saveFile->getRawBytes(sfID);

bool ok = true;
bool conversionOk = true;
bool saved = true;
switch (type)
{
case UINT_T:
saveFile->setValue(sfID, newText.toUInt(&ok));
saved = saveFile->setValue(sfID, newText.toUInt(&conversionOk));
break;
case INT_T:
saveFile->setValue(sfID, newText.toInt(&ok));
saved = saveFile->setValue(sfID, newText.toInt(&conversionOk));
break;
case BOOL_T:
saveFile->setValue(sfID, newText.toInt(&ok) == 0 ? false : true);
saved = saveFile->setValue(sfID, newText.toInt(&conversionOk) == 0 ? false : true);
break;
case FLOAT_T:
saveFile->setValue(sfID, newText.toFloat(&ok));
saved = saveFile->setValue(sfID, newText.toFloat(&conversionOk));
break;
case STRING_T:
saveFile->setValue(sfID, newText.toStdString());
saved = saveFile->setValue(sfID, newText.toStdString());
break;
case TPL_T:
// TODO
Expand All @@ -126,6 +131,11 @@ void MainWindow::updateText()
break;
}

if (!ok) saveFile->setValue(sfID, previousBytes);
if (!conversionOk)
{
saveFile->setValue(sfID, previousBytes);
showStatusBarMessage("Invalid input");
}
if (!saved) showStatusBarMessage("Value out of range");
this->setField(sfID);
}
2 changes: 2 additions & 0 deletions gui/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class MainWindow : public QMainWindow
void setField(SaveFieldID sfID);
QString getField(SaveFieldID sfID);

void showStatusBarMessage(std::string str);

private slots:
void actionOpen();
void actionSave();
Expand Down
18 changes: 12 additions & 6 deletions include/DataObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class DataObject

DataObject(unsigned int startByte, unsigned int lengthInBytes, Type type, unsigned int numRows, unsigned int numColumns);

bool setRawBytes(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], std::vector<uint8_t> value) const;
void setRawBytes(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], std::vector<uint8_t> value) const;

public:
DataObject(unsigned int startByte, unsigned int startBit, unsigned int lengthInBits, Type type);
Expand All @@ -30,19 +30,25 @@ class DataObject

std::vector<uint8_t> getRawBytes(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES]) const;

// TODO: range checks in setValue functions
template <typename T>
void setValue(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], T value) const
bool setValue(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], T value) const
{
std::vector<uint8_t> rawBytes = Types::toRaw(value);
std::vector<uint8_t> rawBytes = Types::toRaw(value, this->bitLength);
if (rawBytes.empty()) return false;

if (this->type == STRING_T) for (int i = rawBytes.size(); i < (this->bitLength / 8); i++) rawBytes.push_back(0);
this->setRawBytes(saveFile, rawBytes);
return true;
}

void setValue(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], std::string value) const
bool setValue(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], std::string value) const
{
std::vector<uint8_t> rawBytes = Types::toRaw(value, this->bitLength);
if (rawBytes.empty()) return false;

for (int i = value.size(); i < (this->bitLength / 8); i++) value += (char)0;
this->setRawBytes(saveFile, Types::toRaw(value));
this->setRawBytes(saveFile, Types::toRaw(value, this->bitLength));
return true;
}

virtual const DataObject* at(unsigned int row, unsigned int column) const
Expand Down
4 changes: 2 additions & 2 deletions include/SaveFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ class SaveFile
return Types::toValue<T>(this->getRawBytes(*dataObj));
}

template<typename T> void setValue(SaveFieldID sfID, T value)
template<typename T> bool setValue(SaveFieldID sfID, T value)
{
(*dataMap[sfID]).setValue(this->saveFile, value);
return (*dataMap[sfID]).setValue(this->saveFile, value);
}

template<typename T> void setArrayValue(SaveFieldID aID, unsigned int index, unsigned int elementName, T value)
Expand Down
83 changes: 44 additions & 39 deletions include/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,62 @@

enum Type
{
UINT_T,
INT_T,
BOOL_T,
FLOAT_T,
STRING_T,
TPL_T,
ARRAY_T
UINT_T,
INT_T,
BOOL_T,
FLOAT_T,
STRING_T,
TPL_T,
ARRAY_T
};

class Types
{
private:
public:

template <typename T>
static T toValue(std::vector<uint8_t> rawBytes)
{
T result = 0;
template <typename T>
static T toValue(std::vector<uint8_t> rawBytes)
{
T result = 0;

for (uint8_t byte : rawBytes)
{
result <<= 8;
result |= byte;
}
for (uint8_t byte : rawBytes)
{
result <<= 8;
result |= byte;
}

return result;
}
return result;
}

// Returns the big-endian representation of x
template <typename T>
static std::vector<uint8_t> toRaw(T x)
{
std::vector<uint8_t> v;
unsigned int sizeInBytes = sizeof(T);
do // When x==0, loop is run once to put 0 into v
{
v.insert(v.begin(), x & (T) 0xFF);
x >>= 8;
sizeInBytes--;
} while (x != 0 && sizeInBytes > 0);
return v;
}
// Returns the big-endian representation of x
template <typename T>
static std::vector<uint8_t> toRaw(T x, unsigned int maxBits)
{
std::vector<uint8_t> v;
unsigned int mask = maxBits < 32 ? ((1 << maxBits) - 1) : 0xFFFFFFFF;
T temp = (x & mask);
if ((T)(x & mask) == x)
{
unsigned int sizeInBytes = sizeof(T);
do // When x==0, loop is run once to put 0 into v
{
v.insert(v.begin(), x & (T) 0xFF);
x >>= 8;
sizeInBytes--;
} while (x != 0 && sizeInBytes > 0);
}
return v;
}

static std::vector<uint8_t> toRaw(float x);
static std::vector<uint8_t> toRaw(bool x);
static std::vector<uint8_t> toRaw(int x);
static std::vector<uint8_t> toRaw(std::string x);
static std::vector<uint8_t> toRaw(const char* x) { return toRaw((std::string)x); }
static std::vector<uint8_t> toRaw(std::vector<uint8_t> x) { return x; }
static std::vector<uint8_t> toRaw(float x, unsigned int maxBits);
static std::vector<uint8_t> toRaw(bool x, unsigned int maxBits);
static std::vector<uint8_t> toRaw(int x, unsigned int maxBits);
static std::vector<uint8_t> toRaw(std::string x, unsigned int maxBits);
static std::vector<uint8_t> toRaw(const char* x, unsigned int maxBits) { return toRaw((std::string)x, maxBits); }
static std::vector<uint8_t> toRaw(std::vector<uint8_t> x, unsigned int maxBits) { return x; }

static std::string toString(Type t);
static std::string toString(Type t);
};

template <>
Expand Down
4 changes: 1 addition & 3 deletions src/DataObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,9 @@ std::vector<uint8_t> DataObject::getRawBytes(uint8_t (&saveFile)[SAVEFILE_LENGTH
* In the case when bytes.size() > this.size(), the additional MSB in bytes are ignored (bytes = 0xABCD -> DataObject = 0xCD for this.size() = 1)
* In the case when bytes.size() < this.size(), the additional MSB associated with the DataObject are cleared (bytes = 0xFF -> DataObject = 0x00FF for this.size() = 2)
*/
bool DataObject::setRawBytes(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], std::vector<uint8_t> value) const
void DataObject::setRawBytes(uint8_t(&saveFile)[SAVEFILE_LENGTH_BYTES], std::vector<uint8_t> value) const
{
//if (value.size() > (this->getLengthInBits() / 8))
for (int i = 0, currBit = this->endBit, currByte = this->endByte, currValueByte = value.size() - 1; i < this->bitLength; i++, (++currBit) %= 8, currByte = ((currBit == 0) ? currByte - 1 : currByte), currValueByte = ((currBit == this->endBit) ? currValueByte - 1 : currValueByte)) saveFile[currByte] = ((currValueByte >= 0) && ((value.at(currValueByte) >> (i % 8)) & 0x1)) ? (saveFile[currByte] | (1 << currBit)) : (saveFile[currByte] & ~(1 << currBit));
return true;
}

unsigned int DataObject::getLengthInBits() const
Expand Down
45 changes: 24 additions & 21 deletions src/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,47 @@ bool Types::toValue<bool>(std::vector<uint8_t> rawBytes)
return rawBool == 0 ? false : true;
}

std::vector<uint8_t> Types::toRaw(float x)
std::vector<uint8_t> Types::toRaw(float x, unsigned int maxBits)
{
std::vector<uint8_t> v;
if (sizeof(float) <= (maxBits / 8))
{
uint8_t floatBytes[sizeof(float)];
memcpy(floatBytes, &x, sizeof(x));

uint8_t floatBytes[sizeof(float)];
memcpy(floatBytes, &x, sizeof(x));
int floatInIntRep = 0;
for (uint8_t byte : floatBytes)
{
floatInIntRep <<= 8;
floatInIntRep |= byte;
}

int floatInIntRep = 0;
for (uint8_t byte : floatBytes)
{
floatInIntRep <<= 8;
floatInIntRep |= byte;
}

uint32_t bigEndianFloat = htonl(floatInIntRep);
uint32_t bigEndianFloat = htonl(floatInIntRep);

for (int i = 0; bigEndianFloat != 0 && i < 4; i++)
{
v.insert(v.begin(), bigEndianFloat & 0xFF);
bigEndianFloat >>= 8;
}
for (int i = 0; i < sizeof(float); i++)
{
v.insert(v.begin(), bigEndianFloat & 0xFF);
bigEndianFloat >>= 8;
}
}

return v;
}

std::vector<uint8_t> Types::toRaw(int x)
std::vector<uint8_t> Types::toRaw(int x, unsigned int maxBits)
{
return toRaw((unsigned int) x);
unsigned int mask = maxBits < 32 ? ((1 << maxBits) - 1) : 0xFFFFFFFF;
return toRaw(((unsigned int) x) & mask, maxBits);
}

std::vector<uint8_t> Types::toRaw(std::string x)
std::vector<uint8_t> Types::toRaw(std::string x, unsigned int maxBits)
{
std::vector<uint8_t> v;
for (int i = 0; i < x.size(); i++) v.push_back(x.at(i));
if (x.size() <= (maxBits / 8)) for (int i = 0; i < x.size(); i++) v.push_back(x.at(i));
return v;
}

std::vector<uint8_t> Types::toRaw(bool x) { return x ? toRaw(1) : toRaw(0);}
std::vector<uint8_t> Types::toRaw(bool x, unsigned int maxBits) { return x ? toRaw(1, maxBits) : toRaw(0, maxBits); }

std::string Types::toString(Type t)
{
Expand Down
12 changes: 6 additions & 6 deletions src/tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ TEST(Save, floats)
SaveFile* saveFile = new SaveFile();

// Setting and reading as float
float floatTestValues[TEST_POINTS] = { 0.0f, 1.222f, 52792035.67f, -12345.6789, 0.25789f };
float floatTestValues[TEST_POINTS] = { 1.222f, 52792035.67f, -12345.6789, 0.25789f, 0.0f };
for (int i = 0; i < TEST_POINTS; i++)
{
saveFile->setValue(PCPMPlayer1Z, floatTestValues[i]);
Expand Down Expand Up @@ -59,21 +59,21 @@ TEST(Save, floats)

memcpy(&testValue, &boolTestValues[0], sizeof(uint32_t));
saveFile->setValue(PCPMPlayer3Y, false);
EXPECT_EQ(testValue, saveFile->getValue<float>(PCPMPlayer3Y));
EXPECT_TRUE(compareBytes(testValue, saveFile->getValue<float>(PCPMPlayer3Y)));

memcpy(&testValue, &boolTestValues[1], sizeof(uint32_t));
saveFile->setValue(PCPMPlayer3Z, true);
EXPECT_EQ(testValue, saveFile->getValue<float>(PCPMPlayer3Z));
EXPECT_TRUE(compareBytes(testValue, saveFile->getValue<float>(PCPMPlayer3Z)));

// Setting as string, reading as float
const char stringTestValues[TEST_POINTS][5] = { {'h', 'i', 'i', 'i', 0}, {':', '3', ':', '3', 0}, {'1', '2', '3', '4', 0}, {0, 0, 0, 0, 0}, {'.', '/', '?', ';', 0}};
uint32_t stringIntTestValues[TEST_POINTS] = { 0x68696969, 0x3A333A33, 0x31323334, 0x0, 0x2E2F3F3B };
const char stringTestValues[TEST_POINTS][5] = { {'h', 'i', 'i', 'i', 0}, {':', '3', ':', '3', 0}, {'1', '2', '3', '4', 0}, {'0', '0', '0', '0', 0}, {'.', '/', '?', ';', 0}};
uint32_t stringIntTestValues[TEST_POINTS] = { 0x68696969, 0x3A333A33, 0x31323334, 0x30303030, 0x2E2F3F3B };

for (int i = 0; i < TEST_POINTS; i++)
{
memcpy(&testValue, &stringIntTestValues[i], sizeof(float));
saveFile->setValue(CAMDVerticalPosition, stringTestValues[i]);
EXPECT_EQ(testValue, saveFile->getValue<float>(CAMDVerticalPosition));
EXPECT_TRUE(compareBytes(testValue, saveFile->getValue<float>(CAMDVerticalPosition)));
}

delete(saveFile);
Expand Down

0 comments on commit 1066ee0

Please sign in to comment.