From 7c09053e162fdae254e9cdeefa734dd4b0d30816 Mon Sep 17 00:00:00 2001 From: syldium Date: Sun, 5 Jun 2022 19:55:46 +0200 Subject: [PATCH 1/2] #5: added support for long array tags --- src/Globals.h | 2 +- src/NBT/NBTHelper.cpp | 1 + src/NBT/NBTTag.h | 45 +++++++++++++++++++++++++++++++++++++++++++ src/NBT/NBTType.h | 3 ++- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/Globals.h b/src/Globals.h index 63e8562..8253b35 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -10,7 +10,7 @@ typedef unsigned int uint; const unsigned int GZIP_BUFFER_SIZE = 128; const unsigned int WRITE_BUFFER_SIZE = 256; const unsigned int MIN_TAG = 1; -const unsigned int MAX_TAG = 11; +const unsigned int MAX_TAG = 12; typedef signed char jbyte; typedef int16_t jshort; diff --git a/src/NBT/NBTHelper.cpp b/src/NBT/NBTHelper.cpp index d03dd49..0650b39 100644 --- a/src/NBT/NBTHelper.cpp +++ b/src/NBT/NBTHelper.cpp @@ -18,6 +18,7 @@ namespace NBT { tags[NbtList] = new NBTTagList(); tags[NbtCompound] = new NBTTagCompound(); tags[NbtIntArray] = new NBTTagIntArray(); + tags[NbtLongArray] = new NBTTagLongArray(); return tags; }(); diff --git a/src/NBT/NBTTag.h b/src/NBT/NBTTag.h index 381bae3..078d84a 100644 --- a/src/NBT/NBTTag.h +++ b/src/NBT/NBTTag.h @@ -390,6 +390,51 @@ namespace NBT { } }; + class NBTTagLongArray : public NBTTagBasic> { + public: + NBTTagLongArray() : NBTTagBasic("nbt-array.png", "Long Array") {} + + void* Read(ByteBuffer* buffer) const override { + jint length = buffer->ReadInt(); + // TODO: Overflow check + + long* array = new long[length]; + for (jint i = 0; i < length; i++) { + array[i] = buffer->ReadLong(); + } + + return new NBTArray(length, array); + } + + void Write(WriteBuffer* buffer, NBTEntry& entry) const override { + NBTArray& data = GetData(entry); + buffer->WriteInt(data.length); + + for (uint i = 0; i < data.length; i++) { + buffer->WriteLong(data.array[i]); + } + } + + void* CreateDefaultData() const override { + return new NBTArray(0, new jlong[0]); + } + + void SetData(NBTEntry& entry, NBTArray& data) const override { + if (entry.value != NULL) + delete static_cast*>(entry.value); + entry.value = &data; + } + + QVariant GetQtData(NBTEntry& entry) const override { + return QString::number(GetData(entry).length) + QString(" longs"); + } + + bool SetQtData(NBTEntry&, const QVariant&) const override { + // Not possible + return false; + } + }; + class NBTTagList : public NBTTagBasic { public: NBTTagList() : NBTTagBasic("nbt-list.png", "List") {} diff --git a/src/NBT/NBTType.h b/src/NBT/NBTType.h index c4b9c89..08d99d4 100644 --- a/src/NBT/NBTType.h +++ b/src/NBT/NBTType.h @@ -13,7 +13,8 @@ namespace NBT { NbtString = 8, NbtList = 9, NbtCompound = 10, - NbtIntArray = 11 + NbtIntArray = 11, + NbtLongArray = 12 }; enum NBTFileType { From 25a773850ccfb01ba82ebf03717aabff10e02cbe Mon Sep 17 00:00:00 2001 From: thelampgod Date: Fri, 31 May 2024 22:11:55 +0200 Subject: [PATCH 2/2] Add edit dialog for long arrays (#1) --- src/NBT/NBTHelper.cpp | 7 ++++++- src/NBT/NBTHelper.h | 3 ++- src/UI/EditArrayDialog.cpp | 25 ++++++++++++++++++++++++- src/UI/EditArrayDialog.h | 3 ++- src/UI/TreeContextMenu.cpp | 20 ++++++++++++++++---- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/NBT/NBTHelper.cpp b/src/NBT/NBTHelper.cpp index 0650b39..363f31d 100644 --- a/src/NBT/NBTHelper.cpp +++ b/src/NBT/NBTHelper.cpp @@ -39,6 +39,7 @@ namespace NBT { template const NBTTagByteArray* NBTHelper::GetTag(NBTType type); template const NBTTagIntArray* NBTHelper::GetTag(NBTType type); + template const NBTTagLongArray* NBTHelper::GetTag(NBTType type); const NBTTag** NBTHelper::GetAllTags() { return tagsByType; @@ -78,6 +79,10 @@ namespace NBT { return GetTag(NbtIntArray)->GetData(entry); } + NBTArray& NBTHelper::GetLongArray(NBTEntry& entry) { + return GetTag(NbtLongArray)->GetData(entry); + } + void NBTHelper::SetDouble(NBTEntry& entry, jdouble value) { GetTag(NbtDouble)->SetData(entry, value); } @@ -86,4 +91,4 @@ namespace NBT { GetTag(NbtString)->SetData(entry, value); } -} \ No newline at end of file +} diff --git a/src/NBT/NBTHelper.h b/src/NBT/NBTHelper.h index 042c40f..19ffdf3 100644 --- a/src/NBT/NBTHelper.h +++ b/src/NBT/NBTHelper.h @@ -20,6 +20,7 @@ namespace NBT { static jdouble GetDouble(NBTEntry& entry); static NBTArray& GetByteArray(NBTEntry& entry); static NBTArray& GetIntArray(NBTEntry& entry); + static NBTArray& GetLongArray(NBTEntry& entry); static QString& GetString(NBTEntry& entry); static NBTList& GetList(NBTEntry& entry); static NBTCompound* GetCompound(NBTEntry& entry); @@ -30,4 +31,4 @@ namespace NBT { private: static const NBTTag** tagsByType; }; -} \ No newline at end of file +} diff --git a/src/UI/EditArrayDialog.cpp b/src/UI/EditArrayDialog.cpp index 8dbd3dc..ac5b7fb 100644 --- a/src/UI/EditArrayDialog.cpp +++ b/src/UI/EditArrayDialog.cpp @@ -30,6 +30,7 @@ namespace UI { template void EditArrayDialog::setArray(NBT::NBTArray&); template void EditArrayDialog::setArray(NBT::NBTArray&); + template void EditArrayDialog::setArray(NBT::NBTArray&); NBT::NBTArray* EditArrayDialog::getResultByteArray() { QString str = widget.plainTextEdit->toPlainText(); @@ -75,8 +76,30 @@ namespace UI { return nbtArray; } + NBT::NBTArray* EditArrayDialog::getResultLongArray() { + QString str = widget.plainTextEdit->toPlainText(); + QStringList list = str.split(" ", QString::SkipEmptyParts); + + NBT::NBTArray* nbtArray = new NBT::NBTArray(); + nbtArray->length = list.length(); + nbtArray->array = new jlong[list.length()]; + + for (uint i = 0; i < nbtArray->length; i++) { + bool success = false; + jlong number = (sizeof(long) == 8) ? list[i].toLong(&success, 10) : list[i].toLongLong(&success, 10); + if (!success) { + delete nbtArray; + return NULL; + } + + nbtArray->array[i] = number; + } + + return nbtArray; + } + void EditArrayDialog::clickOk() { accept(); } -} \ No newline at end of file +} diff --git a/src/UI/EditArrayDialog.h b/src/UI/EditArrayDialog.h index 48a6cd3..e56916a 100644 --- a/src/UI/EditArrayDialog.h +++ b/src/UI/EditArrayDialog.h @@ -16,6 +16,7 @@ namespace UI { NBT::NBTArray* getResultByteArray(); NBT::NBTArray* getResultIntArray(); + NBT::NBTArray* getResultLongArray(); public slots: void clickOk(); @@ -23,4 +24,4 @@ namespace UI { private: Ui::EditArrayDialog widget; }; -} \ No newline at end of file +} diff --git a/src/UI/TreeContextMenu.cpp b/src/UI/TreeContextMenu.cpp index bc35115..b9b08d5 100644 --- a/src/UI/TreeContextMenu.cpp +++ b/src/UI/TreeContextMenu.cpp @@ -34,7 +34,7 @@ namespace UI { if (item->nbtEntry->type == NbtCompound || item->nbtEntry->type == NbtList) addToCompoundAction->setVisible(true); - if (item->nbtEntry->type == NbtByteArray || item->nbtEntry->type == NbtIntArray) + if (item->nbtEntry->type == NbtByteArray || item->nbtEntry->type == NbtIntArray || item->nbtEntry->type == NbtLongArray) editAction->setVisible(true); } @@ -57,7 +57,7 @@ namespace UI { if (item->nbtEntry == NULL) return; - if (item->nbtEntry->type == NbtByteArray || item->nbtEntry->type == NbtIntArray) + if (item->nbtEntry->type == NbtByteArray || item->nbtEntry->type == NbtIntArray || item->nbtEntry->type == NbtLongArray) editArray(index, item); } @@ -129,7 +129,7 @@ namespace UI { if (item->nbtEntry == NULL) return; - if (item->nbtEntry->type == NbtByteArray || item->nbtEntry->type == NbtIntArray) + if (item->nbtEntry->type == NbtByteArray || item->nbtEntry->type == NbtIntArray || item->nbtEntry->type == NbtLongArray) editArray(index, item); } @@ -217,7 +217,19 @@ namespace UI { NBTHelper::GetTag(NbtIntArray)->SetData(*item->nbtEntry, *newArray); GetModel()->UpdateItem(index); } + } else if (item->nbtEntry->type == NbtLongArray) { + dialog.setArray(NBTHelper::GetLongArray(*item->nbtEntry)); + if (dialog.exec() == QDialog::Accepted) { + NBT::NBTArray* newArray = dialog.getResultLongArray(); + if (newArray == NULL) { + QMessageBox::critical(form, tr("Invalid data"), tr("The input data is invalid.", ""), QMessageBox::Ok, QMessageBox::Ok); + return; + } + + NBTHelper::GetTag(NbtLongArray)->SetData(*item->nbtEntry, *newArray); + GetModel()->UpdateItem(index); + } } } -} \ No newline at end of file +}