Merge branch 'develop' of github.com:MultiMC/MultiMC5 into develop
This commit is contained in:
commit
5083a6a809
130
CMakeLists.txt
130
CMakeLists.txt
@ -178,49 +178,53 @@ logger/QsLog.h
|
|||||||
logger/QsLogDest.cpp
|
logger/QsLogDest.cpp
|
||||||
logger/QsLogDest.h
|
logger/QsLogDest.h
|
||||||
|
|
||||||
# GUI
|
# GUI - windows
|
||||||
gui/mainwindow.h
|
gui/MainWindow.h
|
||||||
gui/mainwindow.cpp
|
gui/MainWindow.cpp
|
||||||
gui/settingsdialog.h
|
gui/ConsoleWindow.h
|
||||||
gui/settingsdialog.cpp
|
gui/ConsoleWindow.cpp
|
||||||
gui/CopyInstanceDialog.h
|
|
||||||
gui/CopyInstanceDialog.cpp
|
# GUI - dialogs
|
||||||
gui/newinstancedialog.h
|
gui/dialogs/SettingsDialog.h
|
||||||
gui/newinstancedialog.cpp
|
gui/dialogs/SettingsDialog.cpp
|
||||||
gui/logindialog.h
|
gui/dialogs/CopyInstanceDialog.h
|
||||||
gui/logindialog.cpp
|
gui/dialogs/CopyInstanceDialog.cpp
|
||||||
gui/ProgressDialog.h
|
gui/dialogs/dialogs/
|
||||||
gui/ProgressDialog.cpp
|
gui/dialogs/NewInstanceDialog.cpp
|
||||||
gui/aboutdialog.h
|
gui/dialogs/LoginDialog.h
|
||||||
gui/aboutdialog.cpp
|
gui/dialogs/LoginDialog.cpp
|
||||||
gui/consolewindow.h
|
gui/dialogs/ProgressDialog.h
|
||||||
gui/consolewindow.cpp
|
gui/dialogs/ProgressDialog.cpp
|
||||||
gui/instancedelegate.h
|
gui/dialogs/AboutDialog.h
|
||||||
gui/instancedelegate.cpp
|
gui/dialogs/AboutDialog.cpp
|
||||||
gui/versionselectdialog.h
|
gui/dialogs/VersionSelectDialog.h
|
||||||
gui/versionselectdialog.cpp
|
gui/dialogs/VersionSelectDialog.cpp
|
||||||
gui/lwjglselectdialog.h
|
gui/dialogs/LwjglSelectDialog.h
|
||||||
gui/lwjglselectdialog.cpp
|
gui/dialogs/LwjglSelectDialog.cpp
|
||||||
gui/instancesettings.h
|
gui/dialogs/InstanceSettings.h
|
||||||
gui/instancesettings.cpp
|
gui/dialogs/InstanceSettings.cpp
|
||||||
gui/IconPickerDialog.h
|
gui/dialogs/IconPickerDialog.h
|
||||||
gui/IconPickerDialog.cpp
|
gui/dialogs/IconPickerDialog.cpp
|
||||||
gui/LegacyModEditDialog.h
|
gui/dialogs/LegacyModEditDialog.h
|
||||||
gui/LegacyModEditDialog.cpp
|
gui/dialogs/LegacyModEditDialog.cpp
|
||||||
gui/OneSixModEditDialog.h
|
gui/dialogs/OneSixModEditDialog.h
|
||||||
gui/OneSixModEditDialog.cpp
|
gui/dialogs/OneSixModEditDialog.cpp
|
||||||
gui/ModEditDialogCommon.h
|
gui/dialogs/ModEditDialogCommon.h
|
||||||
gui/ModEditDialogCommon.cpp
|
gui/dialogs/ModEditDialogCommon.cpp
|
||||||
gui/ModListView.h
|
gui/dialogs/EditNotesDialog.h
|
||||||
gui/ModListView.cpp
|
gui/dialogs/EditNotesDialog.cpp
|
||||||
gui/LabeledToolButton.h
|
gui/dialogs/CustomMessageBox.h
|
||||||
gui/LabeledToolButton.cpp
|
gui/dialogs/CustomMessageBox.cpp
|
||||||
gui/EditNotesDialog.h
|
|
||||||
gui/EditNotesDialog.cpp
|
# GUI - widgets
|
||||||
gui/MCModInfoFrame.h
|
gui/widgets/InstanceDelegate.h
|
||||||
gui/MCModInfoFrame.cpp
|
gui/widgets/InstanceDelegate.cpp
|
||||||
gui/CustomMessageBox.h
|
gui/widgets/ModListView.h
|
||||||
gui/CustomMessageBox.cpp
|
gui/widgets/ModListView.cpp
|
||||||
|
gui/widgets/LabeledToolButton.h
|
||||||
|
gui/widgets/LabeledToolButton.cpp
|
||||||
|
gui/widgets/MCModInfoFrame.h
|
||||||
|
gui/widgets/MCModInfoFrame.cpp
|
||||||
|
|
||||||
# Base classes and infrastructure
|
# Base classes and infrastructure
|
||||||
logic/BaseVersion.h
|
logic/BaseVersion.h
|
||||||
@ -332,24 +336,28 @@ logic/NagUtils.cpp
|
|||||||
|
|
||||||
######## UIs ########
|
######## UIs ########
|
||||||
SET(MULTIMC_UIS
|
SET(MULTIMC_UIS
|
||||||
gui/mainwindow.ui
|
|
||||||
gui/settingsdialog.ui
|
|
||||||
gui/CopyInstanceDialog.ui
|
|
||||||
gui/newinstancedialog.ui
|
|
||||||
gui/logindialog.ui
|
|
||||||
gui/aboutdialog.ui
|
|
||||||
gui/consolewindow.ui
|
|
||||||
gui/versionselectdialog.ui
|
|
||||||
gui/lwjglselectdialog.ui
|
|
||||||
gui/instancesettings.ui
|
|
||||||
|
|
||||||
gui/ProgressDialog.ui
|
# Windows
|
||||||
gui/IconPickerDialog.ui
|
gui/MainWindow.ui
|
||||||
gui/LegacyModEditDialog.ui
|
gui/ConsoleWindow.ui
|
||||||
gui/OneSixModEditDialog.ui
|
|
||||||
gui/EditNotesDialog.ui
|
|
||||||
|
|
||||||
gui/MCModInfoFrame.ui
|
# Dialogs
|
||||||
|
gui/dialogs/SettingsDialog.ui
|
||||||
|
gui/dialogs/CopyInstanceDialog.ui
|
||||||
|
gui/dialogs/NewInstanceDialog.ui
|
||||||
|
gui/dialogs/LoginDialog.ui
|
||||||
|
gui/dialogs/AboutDialog.ui
|
||||||
|
gui/dialogs/VersionSelectDialog.ui
|
||||||
|
gui/dialogs/LwjglSelectDialog.ui
|
||||||
|
gui/dialogs/InstanceSettings.ui
|
||||||
|
gui/dialogs/ProgressDialog.ui
|
||||||
|
gui/dialogs/IconPickerDialog.ui
|
||||||
|
gui/dialogs/LegacyModEditDialog.ui
|
||||||
|
gui/dialogs/OneSixModEditDialog.ui
|
||||||
|
gui/dialogs/EditNotesDialog.ui
|
||||||
|
|
||||||
|
# Widgets/other
|
||||||
|
gui/widgets/MCModInfoFrame.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
set (FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${MULTIMC_SOURCES} ${MULTIMC_UIS})
|
set (FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${MULTIMC_SOURCES} ${MULTIMC_UIS})
|
||||||
@ -364,9 +372,9 @@ ENDIF()
|
|||||||
IF(UNIX AND NOT APPLE)
|
IF(UNIX AND NOT APPLE)
|
||||||
SET(MultiMC_QT_ADDITIONAL_MODULES ${MultiMC_QT_ADDITIONAL_MODULES} X11Extras)
|
SET(MultiMC_QT_ADDITIONAL_MODULES ${MultiMC_QT_ADDITIONAL_MODULES} X11Extras)
|
||||||
SET(MultiMC_LINK_ADDITIONAL_LIBS ${MultiMC_LINK_ADDITIONAL_LIBS} xcb)
|
SET(MultiMC_LINK_ADDITIONAL_LIBS ${MultiMC_LINK_ADDITIONAL_LIBS} xcb)
|
||||||
LIST(APPEND MULTIMC_SOURCES gui/platform_x11.cpp)
|
LIST(APPEND MULTIMC_SOURCES gui/Platform_X11.cpp)
|
||||||
ELSE()
|
ELSE()
|
||||||
LIST(APPEND MULTIMC_SOURCES gui/platform_other.cpp)
|
LIST(APPEND MULTIMC_SOURCES gui/Platform_Other.cpp)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "gui/mainwindow.h"
|
#include "gui/MainWindow.h"
|
||||||
#include "gui/versionselectdialog.h"
|
#include "gui/dialogs/VersionSelectDialog.h"
|
||||||
#include "logic/lists/InstanceList.h"
|
#include "logic/lists/InstanceList.h"
|
||||||
#include "logic/lists/IconList.h"
|
#include "logic/lists/IconList.h"
|
||||||
#include "logic/lists/LwjglVersionList.h"
|
#include "logic/lists/LwjglVersionList.h"
|
||||||
@ -24,7 +24,7 @@
|
|||||||
#include "cmdutils.h"
|
#include "cmdutils.h"
|
||||||
#include <inisettingsobject.h>
|
#include <inisettingsobject.h>
|
||||||
#include <setting.h>
|
#include <setting.h>
|
||||||
#include <logger/QsLog.h>
|
#include "logger/QsLog.h"
|
||||||
#include <logger/QsLogDest.h>
|
#include <logger/QsLogDest.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
#ifdef CLASSPARSER_LIBRARY
|
#ifdef CLASSPARSER_LIBRARY
|
||||||
# define CLASSPARSER_EXPORT Q_DECL_EXPORT
|
#define CLASSPARSER_EXPORT Q_DECL_EXPORT
|
||||||
#else
|
#else
|
||||||
# define CLASSPARSER_EXPORT Q_DECL_IMPORT
|
#define CLASSPARSER_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
namespace javautils
|
namespace javautils
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Get the version from a minecraft.jar by parsing its class files. Expensive!
|
* @brief Get the version from a minecraft.jar by parsing its class files. Expensive!
|
||||||
*/
|
*/
|
||||||
QString GetMinecraftJarVersion(QString jar);
|
QString GetMinecraftJarVersion(QString jar);
|
||||||
}
|
}
|
||||||
|
@ -4,80 +4,82 @@
|
|||||||
|
|
||||||
namespace java
|
namespace java
|
||||||
{
|
{
|
||||||
std::string annotation::toString()
|
std::string annotation::toString()
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "Annotation type : " << type_index << " - " << pool[type_index].str_data << std::endl;
|
||||||
|
ss << "Contains " << name_val_pairs.size() << " pairs:" << std::endl;
|
||||||
|
for (unsigned i = 0; i < name_val_pairs.size(); i++)
|
||||||
{
|
{
|
||||||
std::ostringstream ss;
|
std::pair<uint16_t, element_value *> &val = name_val_pairs[i];
|
||||||
ss << "Annotation type : " << type_index << " - " << pool[type_index].str_data << std::endl;
|
auto name_idx = val.first;
|
||||||
ss << "Contains " << name_val_pairs.size() << " pairs:" << std::endl;
|
ss << pool[name_idx].str_data << "(" << name_idx << ")"
|
||||||
for(unsigned i = 0; i < name_val_pairs.size(); i++)
|
<< " = " << val.second->toString() << std::endl;
|
||||||
{
|
|
||||||
std::pair<uint16_t, element_value *> &val = name_val_pairs[i];
|
|
||||||
auto name_idx = val.first;
|
|
||||||
ss << pool[name_idx].str_data << "(" << name_idx << ")" << " = " << val.second->toString() << std::endl;
|
|
||||||
}
|
|
||||||
return ss.str();
|
|
||||||
}
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
annotation * annotation::read (util::membuffer& input, constant_pool& pool)
|
annotation *annotation::read(util::membuffer &input, constant_pool &pool)
|
||||||
|
{
|
||||||
|
uint16_t type_index = 0;
|
||||||
|
input.read_be(type_index);
|
||||||
|
annotation *ann = new annotation(type_index, pool);
|
||||||
|
|
||||||
|
uint16_t num_pairs = 0;
|
||||||
|
input.read_be(num_pairs);
|
||||||
|
while (num_pairs)
|
||||||
{
|
{
|
||||||
uint16_t type_index = 0;
|
uint16_t name_idx = 0;
|
||||||
input.read_be(type_index);
|
// read name index
|
||||||
annotation * ann = new annotation(type_index,pool);
|
input.read_be(name_idx);
|
||||||
|
auto elem = element_value::readElementValue(input, pool);
|
||||||
uint16_t num_pairs = 0;
|
// read value
|
||||||
input.read_be(num_pairs);
|
ann->add_pair(name_idx, elem);
|
||||||
while(num_pairs)
|
num_pairs--;
|
||||||
{
|
|
||||||
uint16_t name_idx = 0;
|
|
||||||
// read name index
|
|
||||||
input.read_be(name_idx);
|
|
||||||
auto elem = element_value::readElementValue(input,pool);
|
|
||||||
// read value
|
|
||||||
ann->add_pair(name_idx, elem);
|
|
||||||
num_pairs --;
|
|
||||||
}
|
|
||||||
return ann;
|
|
||||||
}
|
}
|
||||||
|
return ann;
|
||||||
element_value* element_value::readElementValue ( util::membuffer& input, java::constant_pool& pool )
|
}
|
||||||
|
|
||||||
|
element_value *element_value::readElementValue(util::membuffer &input,
|
||||||
|
java::constant_pool &pool)
|
||||||
|
{
|
||||||
|
element_value_type type = INVALID;
|
||||||
|
input.read(type);
|
||||||
|
uint16_t index = 0;
|
||||||
|
uint16_t index2 = 0;
|
||||||
|
std::vector<element_value *> vals;
|
||||||
|
switch (type)
|
||||||
{
|
{
|
||||||
element_value_type type = INVALID;
|
case PRIMITIVE_BYTE:
|
||||||
input.read(type);
|
case PRIMITIVE_CHAR:
|
||||||
uint16_t index = 0;
|
case PRIMITIVE_DOUBLE:
|
||||||
uint16_t index2 = 0;
|
case PRIMITIVE_FLOAT:
|
||||||
std::vector <element_value *> vals;
|
case PRIMITIVE_INT:
|
||||||
switch (type)
|
case PRIMITIVE_LONG:
|
||||||
|
case PRIMITIVE_SHORT:
|
||||||
|
case PRIMITIVE_BOOLEAN:
|
||||||
|
case STRING:
|
||||||
|
input.read_be(index);
|
||||||
|
return new element_value_simple(type, index, pool);
|
||||||
|
case ENUM_CONSTANT:
|
||||||
|
input.read_be(index);
|
||||||
|
input.read_be(index2);
|
||||||
|
return new element_value_enum(type, index, index2, pool);
|
||||||
|
case CLASS: // Class
|
||||||
|
input.read_be(index);
|
||||||
|
return new element_value_class(type, index, pool);
|
||||||
|
case ANNOTATION: // Annotation
|
||||||
|
// FIXME: runtime visibility info needs to be passed from parent
|
||||||
|
return new element_value_annotation(ANNOTATION, annotation::read(input, pool), pool);
|
||||||
|
case ARRAY: // Array
|
||||||
|
input.read_be(index);
|
||||||
|
for (int i = 0; i < index; i++)
|
||||||
{
|
{
|
||||||
case PRIMITIVE_BYTE:
|
vals.push_back(element_value::readElementValue(input, pool));
|
||||||
case PRIMITIVE_CHAR:
|
|
||||||
case PRIMITIVE_DOUBLE:
|
|
||||||
case PRIMITIVE_FLOAT:
|
|
||||||
case PRIMITIVE_INT:
|
|
||||||
case PRIMITIVE_LONG:
|
|
||||||
case PRIMITIVE_SHORT:
|
|
||||||
case PRIMITIVE_BOOLEAN:
|
|
||||||
case STRING:
|
|
||||||
input.read_be(index);
|
|
||||||
return new element_value_simple(type, index, pool);
|
|
||||||
case ENUM_CONSTANT:
|
|
||||||
input.read_be(index);
|
|
||||||
input.read_be(index2);
|
|
||||||
return new element_value_enum(type, index, index2, pool);
|
|
||||||
case CLASS: // Class
|
|
||||||
input.read_be(index);
|
|
||||||
return new element_value_class(type, index, pool);
|
|
||||||
case ANNOTATION: // Annotation
|
|
||||||
// FIXME: runtime visibility info needs to be passed from parent
|
|
||||||
return new element_value_annotation(ANNOTATION, annotation::read(input, pool), pool);
|
|
||||||
case ARRAY: // Array
|
|
||||||
input.read_be(index);
|
|
||||||
for (int i = 0; i < index; i++)
|
|
||||||
{
|
|
||||||
vals.push_back(element_value::readElementValue(input, pool));
|
|
||||||
}
|
|
||||||
return new element_value_array(ARRAY, vals, pool);
|
|
||||||
default:
|
|
||||||
throw new java::classfile_exception();
|
|
||||||
}
|
}
|
||||||
|
return new element_value_array(ARRAY, vals, pool);
|
||||||
|
default:
|
||||||
|
throw new java::classfile_exception();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -5,248 +5,273 @@
|
|||||||
|
|
||||||
namespace java
|
namespace java
|
||||||
{
|
{
|
||||||
enum element_value_type : uint8_t
|
enum element_value_type : uint8_t
|
||||||
|
{
|
||||||
|
INVALID = 0,
|
||||||
|
STRING = 's',
|
||||||
|
ENUM_CONSTANT = 'e',
|
||||||
|
CLASS = 'c',
|
||||||
|
ANNOTATION = '@',
|
||||||
|
ARRAY = '[', // one array dimension
|
||||||
|
PRIMITIVE_INT = 'I', // integer
|
||||||
|
PRIMITIVE_BYTE = 'B', // signed byte
|
||||||
|
PRIMITIVE_CHAR = 'C', // Unicode character code point in the Basic Multilingual Plane,
|
||||||
|
// encoded with UTF-16
|
||||||
|
PRIMITIVE_DOUBLE = 'D', // double-precision floating-point value
|
||||||
|
PRIMITIVE_FLOAT = 'F', // single-precision floating-point value
|
||||||
|
PRIMITIVE_LONG = 'J', // long integer
|
||||||
|
PRIMITIVE_SHORT = 'S', // signed short
|
||||||
|
PRIMITIVE_BOOLEAN = 'Z' // true or false
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* The element_value structure is a discriminated union representing the value of an
|
||||||
|
*element-value pair.
|
||||||
|
* It is used to represent element values in all attributes that describe annotations
|
||||||
|
* - RuntimeVisibleAnnotations
|
||||||
|
* - RuntimeInvisibleAnnotations
|
||||||
|
* - RuntimeVisibleParameterAnnotations
|
||||||
|
* - RuntimeInvisibleParameterAnnotations).
|
||||||
|
*
|
||||||
|
* The element_value structure has the following format:
|
||||||
|
*/
|
||||||
|
class element_value
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
element_value_type type;
|
||||||
|
constant_pool &pool;
|
||||||
|
|
||||||
|
public:
|
||||||
|
element_value(element_value_type type, constant_pool &pool) : type(type), pool(pool) {};
|
||||||
|
|
||||||
|
element_value_type getElementValueType()
|
||||||
{
|
{
|
||||||
INVALID = 0,
|
return type;
|
||||||
STRING = 's',
|
}
|
||||||
ENUM_CONSTANT = 'e',
|
|
||||||
CLASS = 'c',
|
virtual std::string toString() = 0;
|
||||||
ANNOTATION = '@',
|
|
||||||
ARRAY = '[', // one array dimension
|
static element_value *readElementValue(util::membuffer &input, constant_pool &pool);
|
||||||
PRIMITIVE_INT = 'I', // integer
|
};
|
||||||
PRIMITIVE_BYTE = 'B', // signed byte
|
|
||||||
PRIMITIVE_CHAR = 'C', // Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16
|
/**
|
||||||
PRIMITIVE_DOUBLE = 'D', // double-precision floating-point value
|
* Each value of the annotations table represents a single runtime-visible annotation on a
|
||||||
PRIMITIVE_FLOAT = 'F', // single-precision floating-point value
|
* program element.
|
||||||
PRIMITIVE_LONG = 'J', // long integer
|
* The annotation structure has the following format:
|
||||||
PRIMITIVE_SHORT = 'S', // signed short
|
*/
|
||||||
PRIMITIVE_BOOLEAN = 'Z' // true or false
|
class annotation
|
||||||
};
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<std::pair<uint16_t, element_value *>> value_list;
|
||||||
|
|
||||||
|
protected:
|
||||||
/**
|
/**
|
||||||
* The element_value structure is a discriminated union representing the value of an element-value pair.
|
* The value of the type_index item must be a valid index into the constant_pool table.
|
||||||
* It is used to represent element values in all attributes that describe annotations
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||||||
* - RuntimeVisibleAnnotations
|
* representing a field descriptor representing the annotation type corresponding
|
||||||
* - RuntimeInvisibleAnnotations
|
* to the annotation represented by this annotation structure.
|
||||||
* - RuntimeVisibleParameterAnnotations
|
*/
|
||||||
* - RuntimeInvisibleParameterAnnotations).
|
uint16_t type_index;
|
||||||
|
/**
|
||||||
|
* map between element_name_index and value.
|
||||||
*
|
*
|
||||||
* The element_value structure has the following format:
|
* The value of the element_name_index item must be a valid index into the constant_pool
|
||||||
|
*table.
|
||||||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||||||
|
*representing
|
||||||
|
* a valid field descriptor (§4.3.2) that denotes the name of the annotation type element
|
||||||
|
*represented
|
||||||
|
* by this element_value_pairs entry.
|
||||||
*/
|
*/
|
||||||
class element_value
|
value_list name_val_pairs;
|
||||||
{
|
|
||||||
protected:
|
|
||||||
element_value_type type;
|
|
||||||
constant_pool & pool;
|
|
||||||
|
|
||||||
public:
|
|
||||||
element_value(element_value_type type, constant_pool & pool): type(type), pool(pool) {};
|
|
||||||
|
|
||||||
element_value_type getElementValueType()
|
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string toString() = 0;
|
|
||||||
|
|
||||||
static element_value * readElementValue(util::membuffer & input, constant_pool & pool);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each value of the annotations table represents a single runtime-visible annotation on a program element.
|
* Reference to the parent constant pool
|
||||||
* The annotation structure has the following format:
|
|
||||||
*/
|
*/
|
||||||
class annotation
|
constant_pool &pool;
|
||||||
|
|
||||||
|
public:
|
||||||
|
annotation(uint16_t type_index, constant_pool &pool)
|
||||||
|
: type_index(type_index), pool(pool) {};
|
||||||
|
~annotation()
|
||||||
{
|
{
|
||||||
public:
|
for (unsigned i = 0; i < name_val_pairs.size(); i++)
|
||||||
typedef std::vector< std::pair<uint16_t, element_value * > > value_list;
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* The value of the type_index item must be a valid index into the constant_pool table.
|
|
||||||
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
|
||||||
* representing a field descriptor representing the annotation type corresponding
|
|
||||||
* to the annotation represented by this annotation structure.
|
|
||||||
*/
|
|
||||||
uint16_t type_index;
|
|
||||||
/**
|
|
||||||
* map between element_name_index and value.
|
|
||||||
*
|
|
||||||
* The value of the element_name_index item must be a valid index into the constant_pool table.
|
|
||||||
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure representing
|
|
||||||
* a valid field descriptor (§4.3.2) that denotes the name of the annotation type element represented
|
|
||||||
* by this element_value_pairs entry.
|
|
||||||
*/
|
|
||||||
value_list name_val_pairs;
|
|
||||||
/**
|
|
||||||
* Reference to the parent constant pool
|
|
||||||
*/
|
|
||||||
constant_pool & pool;
|
|
||||||
public:
|
|
||||||
annotation(uint16_t type_index, constant_pool& pool):type_index(type_index), pool(pool) {};
|
|
||||||
~annotation()
|
|
||||||
{
|
{
|
||||||
for(unsigned i = 0 ; i < name_val_pairs.size(); i++)
|
delete name_val_pairs[i].second;
|
||||||
{
|
|
||||||
delete name_val_pairs[i].second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void add_pair(uint16_t key, element_value * value)
|
}
|
||||||
{
|
void add_pair(uint16_t key, element_value *value)
|
||||||
name_val_pairs.push_back(std::make_pair(key, value));
|
|
||||||
};
|
|
||||||
value_list::const_iterator begin()
|
|
||||||
{
|
|
||||||
return name_val_pairs.cbegin();
|
|
||||||
}
|
|
||||||
value_list::const_iterator end()
|
|
||||||
{
|
|
||||||
return name_val_pairs.cend();
|
|
||||||
}
|
|
||||||
std::string toString();
|
|
||||||
static annotation * read(util::membuffer & input, constant_pool & pool);
|
|
||||||
};
|
|
||||||
typedef std::vector<annotation *> annotation_table;
|
|
||||||
|
|
||||||
|
|
||||||
/// type for simple value annotation elements
|
|
||||||
class element_value_simple : public element_value
|
|
||||||
{
|
{
|
||||||
protected:
|
name_val_pairs.push_back(std::make_pair(key, value));
|
||||||
/// index of the constant in the constant pool
|
}
|
||||||
uint16_t index;
|
;
|
||||||
public:
|
value_list::const_iterator begin()
|
||||||
element_value_simple(element_value_type type, uint16_t index , constant_pool& pool):
|
|
||||||
element_value(type, pool), index(index)
|
|
||||||
{
|
|
||||||
// TODO: verify consistency
|
|
||||||
};
|
|
||||||
uint16_t getIndex()
|
|
||||||
{
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
virtual std::string toString()
|
|
||||||
{
|
|
||||||
return pool[index].toString();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/// The enum_const_value item is used if the tag item is 'e'.
|
|
||||||
class element_value_enum : public element_value
|
|
||||||
{
|
{
|
||||||
protected:
|
return name_val_pairs.cbegin();
|
||||||
/**
|
}
|
||||||
* The value of the type_name_index item must be a valid index into the constant_pool table.
|
value_list::const_iterator end()
|
||||||
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
|
||||||
* representing a valid field descriptor (§4.3.2) that denotes the internal form of the binary
|
|
||||||
* name (§4.2.1) of the type of the enum constant represented by this element_value structure.
|
|
||||||
*/
|
|
||||||
uint16_t typeIndex;
|
|
||||||
/**
|
|
||||||
* The value of the const_name_index item must be a valid index into the constant_pool table.
|
|
||||||
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
|
||||||
* representing the simple name of the enum constant represented by this element_value structure.
|
|
||||||
*/
|
|
||||||
uint16_t valueIndex;
|
|
||||||
public:
|
|
||||||
element_value_enum(element_value_type type, uint16_t typeIndex, uint16_t valueIndex, constant_pool& pool):
|
|
||||||
element_value(type, pool), typeIndex(typeIndex), valueIndex(valueIndex)
|
|
||||||
{
|
|
||||||
// TODO: verify consistency
|
|
||||||
}
|
|
||||||
uint16_t getValueIndex()
|
|
||||||
{
|
|
||||||
return valueIndex;
|
|
||||||
}
|
|
||||||
uint16_t getTypeIndex()
|
|
||||||
{
|
|
||||||
return typeIndex;
|
|
||||||
}
|
|
||||||
virtual std::string toString()
|
|
||||||
{
|
|
||||||
return "enum value";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class element_value_class : public element_value
|
|
||||||
{
|
{
|
||||||
protected:
|
return name_val_pairs.cend();
|
||||||
/**
|
}
|
||||||
* The class_info_index item must be a valid index into the constant_pool table.
|
std::string toString();
|
||||||
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
static annotation *read(util::membuffer &input, constant_pool &pool);
|
||||||
* representing the return descriptor (§4.3.3) of the type that is reified by the class
|
};
|
||||||
* represented by this element_value structure.
|
typedef std::vector<annotation *> annotation_table;
|
||||||
*
|
|
||||||
* For example, 'V' for Void.class, 'Ljava/lang/Object;' for Object, etc.
|
/// type for simple value annotation elements
|
||||||
*
|
class element_value_simple : public element_value
|
||||||
* Or in plain english, you can store type information in annotations. Yay.
|
{
|
||||||
*/
|
protected:
|
||||||
uint16_t classIndex;
|
/// index of the constant in the constant pool
|
||||||
public:
|
uint16_t index;
|
||||||
element_value_class(element_value_type type, uint16_t classIndex, constant_pool& pool):
|
|
||||||
element_value(type, pool), classIndex(classIndex)
|
public:
|
||||||
{
|
element_value_simple(element_value_type type, uint16_t index, constant_pool &pool)
|
||||||
// TODO: verify consistency
|
: element_value(type, pool), index(index) {
|
||||||
}
|
// TODO: verify consistency
|
||||||
uint16_t getIndex()
|
};
|
||||||
{
|
uint16_t getIndex()
|
||||||
return classIndex;
|
|
||||||
}
|
|
||||||
virtual std::string toString()
|
|
||||||
{
|
|
||||||
return "class";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/// nested annotations... yay
|
|
||||||
class element_value_annotation : public element_value
|
|
||||||
{
|
{
|
||||||
private:
|
return index;
|
||||||
annotation * nestedAnnotation;
|
}
|
||||||
public:
|
virtual std::string toString()
|
||||||
element_value_annotation(element_value_type type, annotation * nestedAnnotation, constant_pool& pool):
|
|
||||||
element_value(type, pool), nestedAnnotation(nestedAnnotation)
|
|
||||||
{};
|
|
||||||
~element_value_annotation()
|
|
||||||
{
|
|
||||||
if(nestedAnnotation)
|
|
||||||
{
|
|
||||||
delete nestedAnnotation;
|
|
||||||
nestedAnnotation = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual std::string toString()
|
|
||||||
{
|
|
||||||
return "nested annotation";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/// and arrays!
|
|
||||||
class element_value_array : public element_value
|
|
||||||
{
|
{
|
||||||
public:
|
return pool[index].toString();
|
||||||
typedef std::vector <element_value *> elem_vec;
|
}
|
||||||
protected:
|
;
|
||||||
elem_vec values;
|
};
|
||||||
public:
|
/// The enum_const_value item is used if the tag item is 'e'.
|
||||||
element_value_array ( element_value_type type, std::vector <element_value *>& values, constant_pool& pool ):
|
class element_value_enum : public element_value
|
||||||
element_value(type, pool), values(values)
|
{
|
||||||
{};
|
protected:
|
||||||
~element_value_array ()
|
/**
|
||||||
|
* The value of the type_name_index item must be a valid index into the constant_pool table.
|
||||||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||||||
|
* representing a valid field descriptor (§4.3.2) that denotes the internal form of the
|
||||||
|
* binary
|
||||||
|
* name (§4.2.1) of the type of the enum constant represented by this element_value
|
||||||
|
* structure.
|
||||||
|
*/
|
||||||
|
uint16_t typeIndex;
|
||||||
|
/**
|
||||||
|
* The value of the const_name_index item must be a valid index into the constant_pool
|
||||||
|
* table.
|
||||||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||||||
|
* representing the simple name of the enum constant represented by this element_value
|
||||||
|
* structure.
|
||||||
|
*/
|
||||||
|
uint16_t valueIndex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
element_value_enum(element_value_type type, uint16_t typeIndex, uint16_t valueIndex,
|
||||||
|
constant_pool &pool)
|
||||||
|
: element_value(type, pool), typeIndex(typeIndex), valueIndex(valueIndex)
|
||||||
|
{
|
||||||
|
// TODO: verify consistency
|
||||||
|
}
|
||||||
|
uint16_t getValueIndex()
|
||||||
|
{
|
||||||
|
return valueIndex;
|
||||||
|
}
|
||||||
|
uint16_t getTypeIndex()
|
||||||
|
{
|
||||||
|
return typeIndex;
|
||||||
|
}
|
||||||
|
virtual std::string toString()
|
||||||
|
{
|
||||||
|
return "enum value";
|
||||||
|
}
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
class element_value_class : public element_value
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* The class_info_index item must be a valid index into the constant_pool table.
|
||||||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||||||
|
* representing the return descriptor (§4.3.3) of the type that is reified by the class
|
||||||
|
* represented by this element_value structure.
|
||||||
|
*
|
||||||
|
* For example, 'V' for Void.class, 'Ljava/lang/Object;' for Object, etc.
|
||||||
|
*
|
||||||
|
* Or in plain english, you can store type information in annotations. Yay.
|
||||||
|
*/
|
||||||
|
uint16_t classIndex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
element_value_class(element_value_type type, uint16_t classIndex, constant_pool &pool)
|
||||||
|
: element_value(type, pool), classIndex(classIndex)
|
||||||
|
{
|
||||||
|
// TODO: verify consistency
|
||||||
|
}
|
||||||
|
uint16_t getIndex()
|
||||||
|
{
|
||||||
|
return classIndex;
|
||||||
|
}
|
||||||
|
virtual std::string toString()
|
||||||
|
{
|
||||||
|
return "class";
|
||||||
|
}
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// nested annotations... yay
|
||||||
|
class element_value_annotation : public element_value
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
annotation *nestedAnnotation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
element_value_annotation(element_value_type type, annotation *nestedAnnotation,
|
||||||
|
constant_pool &pool)
|
||||||
|
: element_value(type, pool), nestedAnnotation(nestedAnnotation) {};
|
||||||
|
~element_value_annotation()
|
||||||
|
{
|
||||||
|
if (nestedAnnotation)
|
||||||
{
|
{
|
||||||
for(unsigned i = 0; i < values.size();i++)
|
delete nestedAnnotation;
|
||||||
{
|
nestedAnnotation = nullptr;
|
||||||
delete values[i];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
elem_vec::const_iterator begin()
|
|
||||||
{
|
|
||||||
return values.cbegin();
|
|
||||||
}
|
}
|
||||||
elem_vec::const_iterator end()
|
}
|
||||||
|
virtual std::string toString()
|
||||||
|
{
|
||||||
|
return "nested annotation";
|
||||||
|
}
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// and arrays!
|
||||||
|
class element_value_array : public element_value
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<element_value *> elem_vec;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
elem_vec values;
|
||||||
|
|
||||||
|
public:
|
||||||
|
element_value_array(element_value_type type, std::vector<element_value *> &values,
|
||||||
|
constant_pool &pool)
|
||||||
|
: element_value(type, pool), values(values) {};
|
||||||
|
~element_value_array()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < values.size(); i++)
|
||||||
{
|
{
|
||||||
return values.cend();
|
delete values[i];
|
||||||
}
|
}
|
||||||
virtual std::string toString()
|
}
|
||||||
{
|
;
|
||||||
return "array";
|
elem_vec::const_iterator begin()
|
||||||
};
|
{
|
||||||
};
|
return values.cbegin();
|
||||||
|
}
|
||||||
|
elem_vec::const_iterator end()
|
||||||
|
{
|
||||||
|
return values.cend();
|
||||||
|
}
|
||||||
|
virtual std::string toString()
|
||||||
|
{
|
||||||
|
return "array";
|
||||||
|
}
|
||||||
|
;
|
||||||
|
};
|
||||||
}
|
}
|
@ -5,149 +5,152 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
namespace java
|
namespace java
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Class representing a Java .class file
|
* Class representing a Java .class file
|
||||||
*/
|
*/
|
||||||
class classfile : public util::membuffer
|
class classfile : public util::membuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
classfile(char *data, std::size_t size) : membuffer(data, size)
|
||||||
{
|
{
|
||||||
public:
|
valid = false;
|
||||||
classfile(char * data, std::size_t size) : membuffer(data, size)
|
is_synthetic = false;
|
||||||
|
read_be(magic);
|
||||||
|
if (magic != 0xCAFEBABE)
|
||||||
|
throw new classfile_exception();
|
||||||
|
read_be(minor_version);
|
||||||
|
read_be(major_version);
|
||||||
|
constants.load(*this);
|
||||||
|
read_be(access_flags);
|
||||||
|
read_be(this_class);
|
||||||
|
read_be(super_class);
|
||||||
|
|
||||||
|
// Interfaces
|
||||||
|
uint16_t iface_count = 0;
|
||||||
|
read_be(iface_count);
|
||||||
|
while (iface_count)
|
||||||
{
|
{
|
||||||
valid = false;
|
uint16_t iface;
|
||||||
is_synthetic = false;
|
read_be(iface);
|
||||||
read_be(magic);
|
interfaces.push_back(iface);
|
||||||
if(magic != 0xCAFEBABE)
|
iface_count--;
|
||||||
throw new classfile_exception();
|
}
|
||||||
read_be(minor_version);
|
|
||||||
read_be(major_version);
|
|
||||||
constants.load(*this);
|
|
||||||
read_be(access_flags);
|
|
||||||
read_be(this_class);
|
|
||||||
read_be(super_class);
|
|
||||||
|
|
||||||
// Interfaces
|
|
||||||
uint16_t iface_count = 0;
|
|
||||||
read_be(iface_count);
|
|
||||||
while (iface_count)
|
|
||||||
{
|
|
||||||
uint16_t iface;
|
|
||||||
read_be(iface);
|
|
||||||
interfaces.push_back(iface);
|
|
||||||
iface_count --;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fields
|
|
||||||
// read fields (and attributes from inside fields) (and possible inner classes. yay for recursion!)
|
|
||||||
// for now though, we will ignore all attributes
|
|
||||||
/*
|
|
||||||
* field_info
|
|
||||||
* {
|
|
||||||
* u2 access_flags;
|
|
||||||
* u2 name_index;
|
|
||||||
* u2 descriptor_index;
|
|
||||||
* u2 attributes_count;
|
|
||||||
* attribute_info attributes[attributes_count];
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
uint16_t field_count = 0;
|
|
||||||
read_be(field_count);
|
|
||||||
while (field_count)
|
|
||||||
{
|
|
||||||
// skip field stuff
|
|
||||||
skip(6);
|
|
||||||
// and skip field attributes
|
|
||||||
uint16_t attr_count = 0;
|
|
||||||
read_be(attr_count);
|
|
||||||
while(attr_count)
|
|
||||||
{
|
|
||||||
skip(2);
|
|
||||||
uint32_t attr_length = 0;
|
|
||||||
read_be(attr_length);
|
|
||||||
skip(attr_length);
|
|
||||||
attr_count --;
|
|
||||||
}
|
|
||||||
field_count --;
|
|
||||||
}
|
|
||||||
|
|
||||||
// class methods
|
// Fields
|
||||||
/*
|
// read fields (and attributes from inside fields) (and possible inner classes. yay for
|
||||||
* method_info
|
// recursion!)
|
||||||
* {
|
// for now though, we will ignore all attributes
|
||||||
* u2 access_flags;
|
/*
|
||||||
* u2 name_index;
|
* field_info
|
||||||
* u2 descriptor_index;
|
* {
|
||||||
* u2 attributes_count;
|
* u2 access_flags;
|
||||||
* attribute_info attributes[attributes_count];
|
* u2 name_index;
|
||||||
* }
|
* u2 descriptor_index;
|
||||||
*/
|
* u2 attributes_count;
|
||||||
uint16_t method_count = 0;
|
* attribute_info attributes[attributes_count];
|
||||||
read_be(method_count);
|
* }
|
||||||
while( method_count )
|
*/
|
||||||
|
uint16_t field_count = 0;
|
||||||
|
read_be(field_count);
|
||||||
|
while (field_count)
|
||||||
|
{
|
||||||
|
// skip field stuff
|
||||||
|
skip(6);
|
||||||
|
// and skip field attributes
|
||||||
|
uint16_t attr_count = 0;
|
||||||
|
read_be(attr_count);
|
||||||
|
while (attr_count)
|
||||||
{
|
{
|
||||||
skip(6);
|
skip(2);
|
||||||
// and skip method attributes
|
|
||||||
uint16_t attr_count = 0;
|
|
||||||
read_be(attr_count);
|
|
||||||
while(attr_count)
|
|
||||||
{
|
|
||||||
skip(2);
|
|
||||||
uint32_t attr_length = 0;
|
|
||||||
read_be(attr_length);
|
|
||||||
skip(attr_length);
|
|
||||||
attr_count --;
|
|
||||||
}
|
|
||||||
method_count --;
|
|
||||||
}
|
|
||||||
|
|
||||||
// class attributes
|
|
||||||
// there are many kinds of attributes. this is just the generic wrapper structure.
|
|
||||||
// type is decided by attribute name. extensions to the standard are *possible*
|
|
||||||
// class annotations are one kind of a attribute (one per class)
|
|
||||||
/*
|
|
||||||
* attribute_info
|
|
||||||
* {
|
|
||||||
* u2 attribute_name_index;
|
|
||||||
* u4 attribute_length;
|
|
||||||
* u1 info[attribute_length];
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
uint16_t class_attr_count = 0;
|
|
||||||
read_be(class_attr_count);
|
|
||||||
while(class_attr_count)
|
|
||||||
{
|
|
||||||
uint16_t name_idx = 0;
|
|
||||||
read_be(name_idx);
|
|
||||||
uint32_t attr_length = 0;
|
uint32_t attr_length = 0;
|
||||||
read_be(attr_length);
|
read_be(attr_length);
|
||||||
|
skip(attr_length);
|
||||||
auto name = constants[name_idx];
|
attr_count--;
|
||||||
if(name.str_data == "RuntimeVisibleAnnotations")
|
|
||||||
{
|
|
||||||
uint16_t num_annotations = 0;
|
|
||||||
read_be(num_annotations);
|
|
||||||
while (num_annotations)
|
|
||||||
{
|
|
||||||
visible_class_annotations.push_back(annotation::read(*this, constants));
|
|
||||||
num_annotations --;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else skip(attr_length);
|
|
||||||
class_attr_count --;
|
|
||||||
}
|
}
|
||||||
valid = true;
|
field_count--;
|
||||||
};
|
}
|
||||||
bool valid;
|
|
||||||
bool is_synthetic;
|
// class methods
|
||||||
uint32_t magic;
|
/*
|
||||||
uint16_t minor_version;
|
* method_info
|
||||||
uint16_t major_version;
|
* {
|
||||||
constant_pool constants;
|
* u2 access_flags;
|
||||||
uint16_t access_flags;
|
* u2 name_index;
|
||||||
uint16_t this_class;
|
* u2 descriptor_index;
|
||||||
uint16_t super_class;
|
* u2 attributes_count;
|
||||||
// interfaces this class implements ? must be. investigate.
|
* attribute_info attributes[attributes_count];
|
||||||
std::vector<uint16_t> interfaces;
|
* }
|
||||||
// FIXME: doesn't free up memory on delete
|
*/
|
||||||
java::annotation_table visible_class_annotations;
|
uint16_t method_count = 0;
|
||||||
};
|
read_be(method_count);
|
||||||
|
while (method_count)
|
||||||
|
{
|
||||||
|
skip(6);
|
||||||
|
// and skip method attributes
|
||||||
|
uint16_t attr_count = 0;
|
||||||
|
read_be(attr_count);
|
||||||
|
while (attr_count)
|
||||||
|
{
|
||||||
|
skip(2);
|
||||||
|
uint32_t attr_length = 0;
|
||||||
|
read_be(attr_length);
|
||||||
|
skip(attr_length);
|
||||||
|
attr_count--;
|
||||||
|
}
|
||||||
|
method_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// class attributes
|
||||||
|
// there are many kinds of attributes. this is just the generic wrapper structure.
|
||||||
|
// type is decided by attribute name. extensions to the standard are *possible*
|
||||||
|
// class annotations are one kind of a attribute (one per class)
|
||||||
|
/*
|
||||||
|
* attribute_info
|
||||||
|
* {
|
||||||
|
* u2 attribute_name_index;
|
||||||
|
* u4 attribute_length;
|
||||||
|
* u1 info[attribute_length];
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
uint16_t class_attr_count = 0;
|
||||||
|
read_be(class_attr_count);
|
||||||
|
while (class_attr_count)
|
||||||
|
{
|
||||||
|
uint16_t name_idx = 0;
|
||||||
|
read_be(name_idx);
|
||||||
|
uint32_t attr_length = 0;
|
||||||
|
read_be(attr_length);
|
||||||
|
|
||||||
|
auto name = constants[name_idx];
|
||||||
|
if (name.str_data == "RuntimeVisibleAnnotations")
|
||||||
|
{
|
||||||
|
uint16_t num_annotations = 0;
|
||||||
|
read_be(num_annotations);
|
||||||
|
while (num_annotations)
|
||||||
|
{
|
||||||
|
visible_class_annotations.push_back(annotation::read(*this, constants));
|
||||||
|
num_annotations--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
skip(attr_length);
|
||||||
|
class_attr_count--;
|
||||||
|
}
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
bool valid;
|
||||||
|
bool is_synthetic;
|
||||||
|
uint32_t magic;
|
||||||
|
uint16_t minor_version;
|
||||||
|
uint16_t major_version;
|
||||||
|
constant_pool constants;
|
||||||
|
uint16_t access_flags;
|
||||||
|
uint16_t this_class;
|
||||||
|
uint16_t super_class;
|
||||||
|
// interfaces this class implements ? must be. investigate.
|
||||||
|
std::vector<uint16_t> interfaces;
|
||||||
|
// FIXME: doesn't free up memory on delete
|
||||||
|
java::annotation_table visible_class_annotations;
|
||||||
|
};
|
||||||
}
|
}
|
@ -4,209 +4,217 @@
|
|||||||
|
|
||||||
namespace java
|
namespace java
|
||||||
{
|
{
|
||||||
class constant
|
class constant
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum type_t : uint8_t
|
||||||
{
|
{
|
||||||
public:
|
j_hole = 0, // HACK: this is a hole in the array, because java is crazy
|
||||||
enum type_t : uint8_t
|
j_string_data = 1,
|
||||||
{
|
j_int = 3,
|
||||||
j_hole = 0, // HACK: this is a hole in the array, because java is crazy
|
j_float = 4,
|
||||||
j_string_data = 1,
|
j_long = 5,
|
||||||
j_int = 3,
|
j_double = 6,
|
||||||
j_float = 4,
|
j_class = 7,
|
||||||
j_long = 5,
|
j_string = 8,
|
||||||
j_double = 6,
|
j_fieldref = 9,
|
||||||
j_class = 7,
|
j_methodref = 10,
|
||||||
j_string = 8,
|
j_interface_methodref = 11,
|
||||||
j_fieldref = 9,
|
j_nameandtype = 12
|
||||||
j_methodref = 10,
|
} type;
|
||||||
j_interface_methodref = 11,
|
|
||||||
j_nameandtype = 12
|
|
||||||
} type;
|
|
||||||
|
|
||||||
constant(util::membuffer & buf )
|
constant(util::membuffer &buf)
|
||||||
|
{
|
||||||
|
buf.read(type);
|
||||||
|
// invalid constant type!
|
||||||
|
if (type > j_nameandtype || type == (type_t)0 || type == (type_t)2)
|
||||||
|
throw new classfile_exception();
|
||||||
|
|
||||||
|
// load data depending on type
|
||||||
|
switch (type)
|
||||||
{
|
{
|
||||||
buf.read(type);
|
case j_float:
|
||||||
// invalid constant type!
|
case j_int:
|
||||||
if(type > j_nameandtype || type == (type_t)0 || type == (type_t)2)
|
buf.read_be(int_data); // same as float data really
|
||||||
throw new classfile_exception();
|
break;
|
||||||
|
case j_double:
|
||||||
// load data depending on type
|
case j_long:
|
||||||
switch(type)
|
buf.read_be(long_data); // same as double
|
||||||
{
|
break;
|
||||||
case j_float:
|
case j_class:
|
||||||
case j_int:
|
buf.read_be(ref_type.class_idx);
|
||||||
buf.read_be(int_data); // same as float data really
|
break;
|
||||||
break;
|
case j_fieldref:
|
||||||
case j_double:
|
case j_methodref:
|
||||||
case j_long:
|
case j_interface_methodref:
|
||||||
buf.read_be(long_data); // same as double
|
buf.read_be(ref_type.class_idx);
|
||||||
break;
|
buf.read_be(ref_type.name_and_type_idx);
|
||||||
case j_class:
|
break;
|
||||||
buf.read_be(ref_type.class_idx);
|
case j_string:
|
||||||
break;
|
buf.read_be(index);
|
||||||
case j_fieldref:
|
break;
|
||||||
case j_methodref:
|
case j_string_data:
|
||||||
case j_interface_methodref:
|
// HACK HACK: for now, we call these UTF-8 and do no further processing.
|
||||||
buf.read_be(ref_type.class_idx);
|
// Later, we should do some decoding. It's really modified UTF-8
|
||||||
buf.read_be(ref_type.name_and_type_idx);
|
// * U+0000 is represented as 0xC0,0x80 invalid character
|
||||||
break;
|
// * any single zero byte ends the string
|
||||||
case j_string:
|
// * characters above U+10000 are encoded like in CESU-8
|
||||||
buf.read_be(index);
|
buf.read_jstr(str_data);
|
||||||
break;
|
break;
|
||||||
case j_string_data:
|
case j_nameandtype:
|
||||||
// HACK HACK: for now, we call these UTF-8 and do no further processing.
|
buf.read_be(name_and_type.name_index);
|
||||||
// Later, we should do some decoding. It's really modified UTF-8
|
buf.read_be(name_and_type.descriptor_index);
|
||||||
// * U+0000 is represented as 0xC0,0x80 invalid character
|
break;
|
||||||
// * any single zero byte ends the string
|
|
||||||
// * characters above U+10000 are encoded like in CESU-8
|
|
||||||
buf.read_jstr(str_data);
|
|
||||||
break;
|
|
||||||
case j_nameandtype:
|
|
||||||
buf.read_be(name_and_type.name_index);
|
|
||||||
buf.read_be(name_and_type.descriptor_index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constant(int fake)
|
constant(int fake)
|
||||||
|
{
|
||||||
|
type = j_hole;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString()
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
switch (type)
|
||||||
{
|
{
|
||||||
type = j_hole;
|
case j_hole:
|
||||||
|
ss << "Fake legacy entry";
|
||||||
|
break;
|
||||||
|
case j_float:
|
||||||
|
ss << "Float: " << float_data;
|
||||||
|
break;
|
||||||
|
case j_double:
|
||||||
|
ss << "Double: " << double_data;
|
||||||
|
break;
|
||||||
|
case j_int:
|
||||||
|
ss << "Int: " << int_data;
|
||||||
|
break;
|
||||||
|
case j_long:
|
||||||
|
ss << "Long: " << long_data;
|
||||||
|
break;
|
||||||
|
case j_string_data:
|
||||||
|
ss << "StrData: " << str_data;
|
||||||
|
break;
|
||||||
|
case j_string:
|
||||||
|
ss << "Str: " << index;
|
||||||
|
break;
|
||||||
|
case j_fieldref:
|
||||||
|
ss << "FieldRef: " << ref_type.class_idx << " " << ref_type.name_and_type_idx;
|
||||||
|
break;
|
||||||
|
case j_methodref:
|
||||||
|
ss << "MethodRef: " << ref_type.class_idx << " " << ref_type.name_and_type_idx;
|
||||||
|
break;
|
||||||
|
case j_interface_methodref:
|
||||||
|
ss << "IfMethodRef: " << ref_type.class_idx << " " << ref_type.name_and_type_idx;
|
||||||
|
break;
|
||||||
|
case j_class:
|
||||||
|
ss << "Class: " << ref_type.class_idx;
|
||||||
|
break;
|
||||||
|
case j_nameandtype:
|
||||||
|
ss << "NameAndType: " << name_and_type.name_index << " "
|
||||||
|
<< name_and_type.descriptor_index;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string toString()
|
std::string str_data; /** String data in 'modified utf-8'.*/
|
||||||
|
// store everything here.
|
||||||
|
union
|
||||||
|
{
|
||||||
|
int32_t int_data;
|
||||||
|
int64_t long_data;
|
||||||
|
float float_data;
|
||||||
|
double double_data;
|
||||||
|
uint16_t index;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
std::ostringstream ss;
|
/**
|
||||||
switch(type)
|
* Class reference:
|
||||||
{
|
* an index within the constant pool to a UTF-8 string containing
|
||||||
case j_hole:
|
* the fully qualified class name (in internal format)
|
||||||
ss << "Fake legacy entry";
|
* Used for j_class, j_fieldref, j_methodref and j_interface_methodref
|
||||||
break;
|
*/
|
||||||
case j_float:
|
uint16_t class_idx;
|
||||||
ss << "Float: " << float_data;
|
// used for j_fieldref, j_methodref and j_interface_methodref
|
||||||
break;
|
uint16_t name_and_type_idx;
|
||||||
case j_double:
|
} ref_type;
|
||||||
ss << "Double: " << double_data;
|
struct
|
||||||
break;
|
|
||||||
case j_int:
|
|
||||||
ss << "Int: " << int_data;
|
|
||||||
break;
|
|
||||||
case j_long:
|
|
||||||
ss << "Long: " << long_data;
|
|
||||||
break;
|
|
||||||
case j_string_data:
|
|
||||||
ss << "StrData: " << str_data;
|
|
||||||
break;
|
|
||||||
case j_string:
|
|
||||||
ss << "Str: " << index;
|
|
||||||
break;
|
|
||||||
case j_fieldref:
|
|
||||||
ss << "FieldRef: " << ref_type.class_idx << " " << ref_type.name_and_type_idx;
|
|
||||||
break;
|
|
||||||
case j_methodref:
|
|
||||||
ss << "MethodRef: " << ref_type.class_idx << " " << ref_type.name_and_type_idx;
|
|
||||||
break;
|
|
||||||
case j_interface_methodref:
|
|
||||||
ss << "IfMethodRef: " << ref_type.class_idx << " " << ref_type.name_and_type_idx;
|
|
||||||
break;
|
|
||||||
case j_class:
|
|
||||||
ss << "Class: " << ref_type.class_idx;
|
|
||||||
break;
|
|
||||||
case j_nameandtype:
|
|
||||||
ss << "NameAndType: " << name_and_type.name_index << " " << name_and_type.descriptor_index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string str_data; /** String data in 'modified utf-8'.*/
|
|
||||||
// store everything here.
|
|
||||||
union
|
|
||||||
{
|
{
|
||||||
int32_t int_data;
|
uint16_t name_index;
|
||||||
int64_t long_data;
|
uint16_t descriptor_index;
|
||||||
float float_data;
|
} name_and_type;
|
||||||
double double_data;
|
|
||||||
uint16_t index;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Class reference:
|
|
||||||
* an index within the constant pool to a UTF-8 string containing
|
|
||||||
* the fully qualified class name (in internal format)
|
|
||||||
* Used for j_class, j_fieldref, j_methodref and j_interface_methodref
|
|
||||||
*/
|
|
||||||
uint16_t class_idx;
|
|
||||||
// used for j_fieldref, j_methodref and j_interface_methodref
|
|
||||||
uint16_t name_and_type_idx;
|
|
||||||
} ref_type;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t name_index;
|
|
||||||
uint16_t descriptor_index;
|
|
||||||
} name_and_type;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper class that represents the custom container used in Java class file for storage of
|
||||||
|
* constants
|
||||||
|
*/
|
||||||
|
class constant_pool
|
||||||
|
{
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* A helper class that represents the custom container used in Java class file for storage of constants
|
* Create a pool of constants
|
||||||
*/
|
*/
|
||||||
class constant_pool
|
constant_pool()
|
||||||
{
|
{
|
||||||
public:
|
}
|
||||||
/**
|
/**
|
||||||
* Create a pool of constants
|
* Load a java constant pool
|
||||||
*/
|
*/
|
||||||
constant_pool(){}
|
void load(util::membuffer &buf)
|
||||||
/**
|
{
|
||||||
* Load a java constant pool
|
uint16_t length = 0;
|
||||||
*/
|
buf.read_be(length);
|
||||||
void load(util::membuffer & buf)
|
length--;
|
||||||
|
uint16_t index = 1;
|
||||||
|
const constant *last_constant = nullptr;
|
||||||
|
while (length)
|
||||||
{
|
{
|
||||||
uint16_t length = 0;
|
const constant &cnst = constant(buf);
|
||||||
buf.read_be(length);
|
constants.push_back(cnst);
|
||||||
length --;
|
last_constant = &constants[constants.size() - 1];
|
||||||
uint16_t index = 1;
|
if (last_constant->type == constant::j_double ||
|
||||||
const constant * last_constant = nullptr;
|
last_constant->type == constant::j_long)
|
||||||
while(length)
|
|
||||||
{
|
{
|
||||||
const constant & cnst = constant(buf);
|
// push in a fake constant to preserve indexing
|
||||||
constants.push_back(cnst);
|
constants.push_back(constant(0));
|
||||||
last_constant = &constants[constants.size() - 1];
|
length -= 2;
|
||||||
if(last_constant->type == constant::j_double || last_constant->type == constant::j_long)
|
index += 2;
|
||||||
{
|
}
|
||||||
// push in a fake constant to preserve indexing
|
else
|
||||||
constants.push_back(constant(0));
|
{
|
||||||
length-=2;
|
length--;
|
||||||
index+=2;
|
index++;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length--;
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typedef std::vector<java::constant> container_type;
|
}
|
||||||
/**
|
typedef std::vector<java::constant> container_type;
|
||||||
* Access constants based on jar file index numbers (index of the first element is 1)
|
/**
|
||||||
*/
|
* Access constants based on jar file index numbers (index of the first element is 1)
|
||||||
java::constant & operator[](std::size_t constant_index)
|
*/
|
||||||
|
java::constant &operator[](std::size_t constant_index)
|
||||||
|
{
|
||||||
|
if (constant_index == 0 || constant_index > constants.size())
|
||||||
{
|
{
|
||||||
if(constant_index == 0 || constant_index > constants.size())
|
throw new classfile_exception();
|
||||||
{
|
|
||||||
throw new classfile_exception();
|
|
||||||
}
|
|
||||||
return constants[constant_index - 1];
|
|
||||||
};
|
|
||||||
container_type::const_iterator begin() const
|
|
||||||
{
|
|
||||||
return constants.begin();
|
|
||||||
};
|
|
||||||
container_type::const_iterator end() const
|
|
||||||
{
|
|
||||||
return constants.end();
|
|
||||||
}
|
}
|
||||||
private:
|
return constants[constant_index - 1];
|
||||||
container_type constants;
|
}
|
||||||
};
|
;
|
||||||
|
container_type::const_iterator begin() const
|
||||||
|
{
|
||||||
|
return constants.begin();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
container_type::const_iterator end() const
|
||||||
|
{
|
||||||
|
return constants.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
container_type constants;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
namespace java
|
namespace java
|
||||||
{
|
{
|
||||||
class classfile_exception : public std::exception {};
|
class classfile_exception : public std::exception
|
||||||
|
{
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,53 +10,67 @@ namespace util
|
|||||||
inline uint64_t bigswap(uint64_t x)
|
inline uint64_t bigswap(uint64_t x)
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline uint32_t bigswap(uint32_t x)
|
inline uint32_t bigswap(uint32_t x)
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline uint16_t bigswap(uint16_t x)
|
inline uint16_t bigswap(uint16_t x)
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline int64_t bigswap(int64_t x)
|
inline int64_t bigswap(int64_t x)
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline int32_t bigswap(int32_t x)
|
inline int32_t bigswap(int32_t x)
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline int16_t bigswap(int16_t x)
|
inline int16_t bigswap(int16_t x)
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
};
|
}
|
||||||
|
;
|
||||||
#else
|
#else
|
||||||
inline uint64_t bigswap(uint64_t x)
|
inline uint64_t bigswap(uint64_t x)
|
||||||
{
|
{
|
||||||
return (x>>56) | ((x<<40) & 0x00FF000000000000) | ((x<<24) & 0x0000FF0000000000) | ((x<<8) & 0x000000FF00000000) |
|
return (x >> 56) | ((x << 40) & 0x00FF000000000000) | ((x << 24) & 0x0000FF0000000000) |
|
||||||
((x>>8) & 0x00000000FF000000) | ((x>>24) & 0x0000000000FF0000) | ((x>>40) & 0x000000000000FF00) | (x<<56);
|
((x << 8) & 0x000000FF00000000) | ((x >> 8) & 0x00000000FF000000) |
|
||||||
};
|
((x >> 24) & 0x0000000000FF0000) | ((x >> 40) & 0x000000000000FF00) | (x << 56);
|
||||||
|
}
|
||||||
|
;
|
||||||
inline uint32_t bigswap(uint32_t x)
|
inline uint32_t bigswap(uint32_t x)
|
||||||
{
|
{
|
||||||
return (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24);
|
return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline uint16_t bigswap(uint16_t x)
|
inline uint16_t bigswap(uint16_t x)
|
||||||
{
|
{
|
||||||
return (x>>8) | (x<<8);
|
return (x >> 8) | (x << 8);
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline int64_t bigswap(int64_t x)
|
inline int64_t bigswap(int64_t x)
|
||||||
{
|
{
|
||||||
return (x>>56) | ((x<<40) & 0x00FF000000000000) | ((x<<24) & 0x0000FF0000000000) | ((x<<8) & 0x000000FF00000000) |
|
return (x >> 56) | ((x << 40) & 0x00FF000000000000) | ((x << 24) & 0x0000FF0000000000) |
|
||||||
((x>>8) & 0x00000000FF000000) | ((x>>24) & 0x0000000000FF0000) | ((x>>40) & 0x000000000000FF00) | (x<<56);
|
((x << 8) & 0x000000FF00000000) | ((x >> 8) & 0x00000000FF000000) |
|
||||||
};
|
((x >> 24) & 0x0000000000FF0000) | ((x >> 40) & 0x000000000000FF00) | (x << 56);
|
||||||
|
}
|
||||||
|
;
|
||||||
inline int32_t bigswap(int32_t x)
|
inline int32_t bigswap(int32_t x)
|
||||||
{
|
{
|
||||||
return (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24);
|
return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
|
||||||
};
|
}
|
||||||
|
;
|
||||||
inline int16_t bigswap(int16_t x)
|
inline int16_t bigswap(int16_t x)
|
||||||
{
|
{
|
||||||
return (x>>8) | (x<<8);
|
return (x >> 8) | (x << 8);
|
||||||
};
|
}
|
||||||
|
;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -49,24 +49,28 @@ QString GetMinecraftJarVersion(QString jarName)
|
|||||||
Minecraft.read(classfile, size);
|
Minecraft.read(classfile, size);
|
||||||
|
|
||||||
// parse Minecraft.class
|
// parse Minecraft.class
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
char *temp = classfile;
|
char *temp = classfile;
|
||||||
java::classfile MinecraftClass(temp, size);
|
java::classfile MinecraftClass(temp, size);
|
||||||
java::constant_pool constants = MinecraftClass.constants;
|
java::constant_pool constants = MinecraftClass.constants;
|
||||||
for(java::constant_pool::container_type::const_iterator iter=constants.begin();
|
for (java::constant_pool::container_type::const_iterator iter = constants.begin();
|
||||||
iter != constants.end(); iter++)
|
iter != constants.end(); iter++)
|
||||||
{
|
{
|
||||||
const java::constant & constant = *iter;
|
const java::constant &constant = *iter;
|
||||||
if (constant.type != java::constant::j_string_data)
|
if (constant.type != java::constant::j_string_data)
|
||||||
continue;
|
continue;
|
||||||
const std::string & str = constant.str_data;
|
const std::string &str = constant.str_data;
|
||||||
if (str.compare(0, 20, "Minecraft Minecraft ") == 0)
|
if (str.compare(0, 20, "Minecraft Minecraft ") == 0)
|
||||||
{
|
{
|
||||||
version = str.substr(20).data();
|
version = str.substr(20).data();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(java::classfile_exception &) {}
|
}
|
||||||
|
catch (java::classfile_exception &)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
delete[] classfile;
|
delete[] classfile;
|
||||||
@ -76,5 +80,4 @@ QString GetMinecraftJarVersion(QString jarName)
|
|||||||
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,58 +7,57 @@
|
|||||||
|
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
class membuffer
|
class membuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
membuffer(char *buffer, std::size_t size)
|
||||||
{
|
{
|
||||||
public:
|
current = start = buffer;
|
||||||
membuffer(char * buffer, std::size_t size)
|
end = start + size;
|
||||||
{
|
}
|
||||||
current = start = buffer;
|
~membuffer()
|
||||||
end = start + size;
|
{
|
||||||
}
|
// maybe? possibly? left out to avoid confusion. for now.
|
||||||
~membuffer()
|
// delete start;
|
||||||
{
|
}
|
||||||
// maybe? possibly? left out to avoid confusion. for now.
|
/**
|
||||||
//delete start;
|
* Read some value. That's all ;)
|
||||||
}
|
*/
|
||||||
/**
|
template <class T> void read(T &val)
|
||||||
* Read some value. That's all ;)
|
{
|
||||||
*/
|
val = *(T *)current;
|
||||||
template <class T>
|
current += sizeof(T);
|
||||||
void read(T& val)
|
}
|
||||||
{
|
/**
|
||||||
val = *(T *)current;
|
* Read a big-endian number
|
||||||
current += sizeof(T);
|
* valid for 2-byte, 4-byte and 8-byte variables
|
||||||
}
|
*/
|
||||||
/**
|
template <class T> void read_be(T &val)
|
||||||
* Read a big-endian number
|
{
|
||||||
* valid for 2-byte, 4-byte and 8-byte variables
|
val = util::bigswap(*(T *)current);
|
||||||
*/
|
current += sizeof(T);
|
||||||
template <class T>
|
}
|
||||||
void read_be(T& val)
|
/**
|
||||||
{
|
* Read a string in the format:
|
||||||
val = util::bigswap(*(T *)current);
|
* 2B length (big endian, unsigned)
|
||||||
current += sizeof(T);
|
* length bytes data
|
||||||
}
|
*/
|
||||||
/**
|
void read_jstr(std::string &str)
|
||||||
* Read a string in the format:
|
{
|
||||||
* 2B length (big endian, unsigned)
|
uint16_t length = 0;
|
||||||
* length bytes data
|
read_be(length);
|
||||||
*/
|
str.append(current, length);
|
||||||
void read_jstr(std::string & str)
|
current += length;
|
||||||
{
|
}
|
||||||
uint16_t length = 0;
|
/**
|
||||||
read_be(length);
|
* Skip N bytes
|
||||||
str.append(current,length);
|
*/
|
||||||
current += length;
|
void skip(std::size_t N)
|
||||||
}
|
{
|
||||||
/**
|
current += N;
|
||||||
* Skip N bytes
|
}
|
||||||
*/
|
|
||||||
void skip (std::size_t N)
|
private:
|
||||||
{
|
char *start, *end, *current;
|
||||||
current += N;
|
};
|
||||||
}
|
|
||||||
private:
|
|
||||||
char * start, *end, *current;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2012 MultiMC Contributors
|
// Copyright 2012 MultiMC Contributors
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// You may obtain a copy of the License at
|
// You may obtain a copy of the License at
|
||||||
//
|
//
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -30,94 +30,85 @@ import java.awt.image.BufferedImage;
|
|||||||
|
|
||||||
public class MCFrame extends Frame implements WindowListener
|
public class MCFrame extends Frame implements WindowListener
|
||||||
{
|
{
|
||||||
private Launcher appletWrap = null;
|
private Launcher appletWrap = null;
|
||||||
public MCFrame(String title)
|
public MCFrame ( String title )
|
||||||
{
|
{
|
||||||
super(title);
|
super ( title );
|
||||||
BufferedImage image = null;
|
BufferedImage image = null;
|
||||||
try
|
try {
|
||||||
{
|
image = ImageIO.read ( new File ( "icon.png" ) );
|
||||||
image = ImageIO.read(new File("icon.png"));
|
setIconImage ( image );
|
||||||
setIconImage(image);
|
} catch ( IOException e ) {
|
||||||
}
|
e.printStackTrace();
|
||||||
catch (IOException e)
|
}
|
||||||
{
|
this.addWindowListener ( this );
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
|
||||||
this.addWindowListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(Applet mcApplet, String user, String session, Dimension winSize, boolean maximize)
|
public void start ( Applet mcApplet, String user, String session, Dimension winSize, boolean maximize )
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
appletWrap = new Launcher ( mcApplet, new URL ( "http://www.minecraft.net/game" ) );
|
||||||
appletWrap = new Launcher(mcApplet, new URL("http://www.minecraft.net/game"));
|
} catch ( MalformedURLException ignored ) {}
|
||||||
}
|
|
||||||
catch (MalformedURLException ignored){}
|
|
||||||
|
|
||||||
appletWrap.setParameter("username", user);
|
|
||||||
appletWrap.setParameter("sessionid", session);
|
|
||||||
appletWrap.setParameter("stand-alone", "true"); // Show the quit button.
|
|
||||||
mcApplet.setStub(appletWrap);
|
|
||||||
|
|
||||||
this.add(appletWrap);
|
|
||||||
appletWrap.setPreferredSize(winSize);
|
|
||||||
this.pack();
|
|
||||||
this.setLocationRelativeTo(null);
|
|
||||||
this.setResizable(true);
|
|
||||||
if (maximize)
|
|
||||||
this.setExtendedState(MAXIMIZED_BOTH);
|
|
||||||
|
|
||||||
validate();
|
|
||||||
appletWrap.init();
|
|
||||||
appletWrap.start();
|
|
||||||
setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
appletWrap.setParameter ( "username", user );
|
||||||
public void windowActivated(WindowEvent e) {}
|
appletWrap.setParameter ( "sessionid", session );
|
||||||
|
appletWrap.setParameter ( "stand-alone", "true" ); // Show the quit button.
|
||||||
|
mcApplet.setStub ( appletWrap );
|
||||||
|
|
||||||
@Override
|
this.add ( appletWrap );
|
||||||
public void windowClosed(WindowEvent e) {}
|
appletWrap.setPreferredSize ( winSize );
|
||||||
|
this.pack();
|
||||||
|
this.setLocationRelativeTo ( null );
|
||||||
|
this.setResizable ( true );
|
||||||
|
if ( maximize ) {
|
||||||
|
this.setExtendedState ( MAXIMIZED_BOTH );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
validate();
|
||||||
public void windowClosing(WindowEvent e)
|
appletWrap.init();
|
||||||
{
|
appletWrap.start();
|
||||||
new Thread()
|
setVisible ( true );
|
||||||
{
|
}
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.sleep(30000L);
|
|
||||||
} catch (InterruptedException localInterruptedException)
|
|
||||||
{
|
|
||||||
localInterruptedException.printStackTrace();
|
|
||||||
}
|
|
||||||
System.out.println("FORCING EXIT!");
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.start();
|
|
||||||
|
|
||||||
if (appletWrap != null)
|
@Override
|
||||||
{
|
public void windowActivated ( WindowEvent e ) {}
|
||||||
appletWrap.stop();
|
|
||||||
appletWrap.destroy();
|
|
||||||
}
|
|
||||||
// old minecraft versions can hang without this >_<
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowDeactivated(WindowEvent e) {}
|
public void windowClosed ( WindowEvent e ) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowDeiconified(WindowEvent e) {}
|
public void windowClosing ( WindowEvent e )
|
||||||
|
{
|
||||||
|
new Thread() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep ( 30000L );
|
||||||
|
} catch ( InterruptedException localInterruptedException ) {
|
||||||
|
localInterruptedException.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.println ( "FORCING EXIT!" );
|
||||||
|
System.exit ( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.start();
|
||||||
|
|
||||||
@Override
|
if ( appletWrap != null ) {
|
||||||
public void windowIconified(WindowEvent e) {}
|
appletWrap.stop();
|
||||||
|
appletWrap.destroy();
|
||||||
|
}
|
||||||
|
// old minecraft versions can hang without this >_<
|
||||||
|
System.exit ( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void windowOpened(WindowEvent e) {}
|
public void windowDeactivated ( WindowEvent e ) {}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public void windowDeiconified ( WindowEvent e ) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowIconified ( WindowEvent e ) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void windowOpened ( WindowEvent e ) {}
|
||||||
|
}
|
||||||
|
@ -1523,8 +1523,8 @@ band **unpacker::attr_definitions::buildBands(unpacker::layout_definition *lo)
|
|||||||
call.le_body[0] = &cble;
|
call.le_body[0] = &cble;
|
||||||
// Distinguish backward calls and callables:
|
// Distinguish backward calls and callables:
|
||||||
assert(cble.le_kind == EK_CBLE);
|
assert(cble.le_kind == EK_CBLE);
|
||||||
//FIXME: hit this one
|
// FIXME: hit this one
|
||||||
//assert(cble.le_len == call_num);
|
// assert(cble.le_len == call_num);
|
||||||
cble.le_back |= call.le_back;
|
cble.le_back |= call.le_back;
|
||||||
}
|
}
|
||||||
calls_to_link.popTo(0);
|
calls_to_link.popTo(0);
|
||||||
@ -2778,8 +2778,8 @@ void unpacker::putlayout(band **body)
|
|||||||
{
|
{
|
||||||
band &cble = *b.le_body[0];
|
band &cble = *b.le_body[0];
|
||||||
assert(cble.le_kind == EK_CBLE);
|
assert(cble.le_kind == EK_CBLE);
|
||||||
//FIXME: hit this one
|
// FIXME: hit this one
|
||||||
//assert(cble.le_len == b.le_len);
|
// assert(cble.le_len == b.le_len);
|
||||||
putlayout(cble.le_body);
|
putlayout(cble.le_body);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BASICSETTINGSOBJECT_H
|
#pragma once
|
||||||
#define BASICSETTINGSOBJECT_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
@ -31,14 +30,13 @@ class LIBSETTINGS_EXPORT BasicSettingsObject : public SettingsObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit BasicSettingsObject(QObject *parent = 0);
|
explicit BasicSettingsObject(QObject *parent = 0);
|
||||||
|
|
||||||
protected slots:
|
protected
|
||||||
|
slots:
|
||||||
virtual void changeSetting(const Setting &setting, QVariant value);
|
virtual void changeSetting(const Setting &setting, QVariant value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QVariant retrieveValue(const Setting &setting);
|
virtual QVariant retrieveValue(const Setting &setting);
|
||||||
|
|
||||||
QSettings config;
|
QSettings config;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BASICSETTINGSOBJECT_H
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
@ -25,11 +26,11 @@ class LIBSETTINGS_EXPORT INIFile : public QMap<QString, QVariant>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit INIFile();
|
explicit INIFile();
|
||||||
|
|
||||||
bool loadFile(QByteArray file);
|
bool loadFile(QByteArray file);
|
||||||
bool loadFile(QString fileName);
|
bool loadFile(QString fileName);
|
||||||
bool saveFile(QString fileName);
|
bool saveFile(QString fileName);
|
||||||
|
|
||||||
QVariant get(QString key, QVariant def) const;
|
QVariant get(QString key, QVariant def) const;
|
||||||
void set(QString key, QVariant val);
|
void set(QString key, QVariant val);
|
||||||
QString unescape(QString orig);
|
QString unescape(QString orig);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INISETTINGSOBJECT_H
|
#pragma once
|
||||||
#define INISETTINGSOBJECT_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@ -22,7 +21,7 @@
|
|||||||
|
|
||||||
#include "settingsobject.h"
|
#include "settingsobject.h"
|
||||||
|
|
||||||
#include "libutil_config.h"
|
#include "libsettings_config.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A settings object that stores its settings in an INIFile.
|
* \brief A settings object that stores its settings in an INIFile.
|
||||||
@ -32,29 +31,31 @@ class LIBSETTINGS_EXPORT INISettingsObject : public SettingsObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit INISettingsObject(const QString &path, QObject *parent = 0);
|
explicit INISettingsObject(const QString &path, QObject *parent = 0);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the path to the INI file.
|
* \brief Gets the path to the INI file.
|
||||||
* \return The path to the INI file.
|
* \return The path to the INI file.
|
||||||
*/
|
*/
|
||||||
virtual QString filePath() const { return m_filePath; }
|
virtual QString filePath() const
|
||||||
|
{
|
||||||
|
return m_filePath;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the path to the INI file and reloads it.
|
* \brief Sets the path to the INI file and reloads it.
|
||||||
* \param filePath The INI file's new path.
|
* \param filePath The INI file's new path.
|
||||||
*/
|
*/
|
||||||
virtual void setFilePath(const QString &filePath);
|
virtual void setFilePath(const QString &filePath);
|
||||||
|
|
||||||
protected slots:
|
protected
|
||||||
|
slots:
|
||||||
virtual void changeSetting(const Setting &setting, QVariant value);
|
virtual void changeSetting(const Setting &setting, QVariant value);
|
||||||
virtual void resetSetting ( const Setting& setting );
|
virtual void resetSetting(const Setting &setting);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QVariant retrieveValue(const Setting &setting);
|
virtual QVariant retrieveValue(const Setting &setting);
|
||||||
|
|
||||||
INIFile m_ini;
|
INIFile m_ini;
|
||||||
|
|
||||||
QString m_filePath;
|
QString m_filePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INISETTINGSOBJECT_H
|
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KEYRING_H
|
#pragma once
|
||||||
#define KEYRING_H
|
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
@ -79,14 +78,15 @@ public:
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual void removeStoredAccount(QString service, QString username) = 0;
|
virtual void removeStoredAccount(QString service, QString username) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// fall back to StubKeyring if false
|
/// fall back to StubKeyring if false
|
||||||
virtual bool isValid() { return false; }
|
virtual bool isValid()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Keyring *m_instance;
|
static Keyring *m_instance;
|
||||||
static void destroy();
|
static void destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEYRING_H
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -18,11 +18,11 @@
|
|||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
#ifdef LIBSETTINGS_STATIC
|
#ifdef LIBSETTINGS_STATIC
|
||||||
#define LIBSETTINGS_EXPORT
|
#define LIBSETTINGS_EXPORT
|
||||||
#else
|
#else
|
||||||
#ifdef LIBSETTINGS_LIBRARY
|
#ifdef LIBSETTINGS_LIBRARY
|
||||||
#define LIBSETTINGS_EXPORT Q_DECL_EXPORT
|
#define LIBSETTINGS_EXPORT Q_DECL_EXPORT
|
||||||
#else
|
#else
|
||||||
#define LIBSETTINGS_EXPORT Q_DECL_IMPORT
|
#define LIBSETTINGS_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef OVERRIDESETTING_H
|
#pragma once
|
||||||
#define OVERRIDESETTING_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@ -25,7 +24,7 @@
|
|||||||
/*!
|
/*!
|
||||||
* \brief A setting that 'overrides another.'
|
* \brief A setting that 'overrides another.'
|
||||||
* This means that the setting's default value will be the value of another setting.
|
* This means that the setting's default value will be the value of another setting.
|
||||||
* The other setting can be (and usually is) a part of a different SettingsObject
|
* The other setting can be (and usually is) a part of a different SettingsObject
|
||||||
* than this one.
|
* than this one.
|
||||||
*/
|
*/
|
||||||
class LIBSETTINGS_EXPORT OverrideSetting : public Setting
|
class LIBSETTINGS_EXPORT OverrideSetting : public Setting
|
||||||
@ -33,11 +32,9 @@ class LIBSETTINGS_EXPORT OverrideSetting : public Setting
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit OverrideSetting(const QString &name, Setting *other, QObject *parent = 0);
|
explicit OverrideSetting(const QString &name, Setting *other, QObject *parent = 0);
|
||||||
|
|
||||||
virtual QVariant defValue() const;
|
virtual QVariant defValue() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Setting *m_other;
|
Setting *m_other;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OVERRIDESETTING_H
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SETTING_H
|
#pragma once
|
||||||
#define SETTING_H
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@ -24,7 +23,7 @@
|
|||||||
class SettingsObject;
|
class SettingsObject;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class LIBSETTINGS_EXPORT Setting : public QObject
|
class LIBSETTINGS_EXPORT Setting : public QObject
|
||||||
{
|
{
|
||||||
@ -35,23 +34,30 @@ public:
|
|||||||
* \param parent The Setting's parent object.
|
* \param parent The Setting's parent object.
|
||||||
*/
|
*/
|
||||||
explicit Setting(QString id, QVariant defVal = QVariant(), QObject *parent = 0);
|
explicit Setting(QString id, QVariant defVal = QVariant(), QObject *parent = 0);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets this setting's ID.
|
* \brief Gets this setting's ID.
|
||||||
* This is used to refer to the setting within the application.
|
* This is used to refer to the setting within the application.
|
||||||
* \warning Changing the ID while the setting is registered with a SettingsObject results in undefined behavior.
|
* \warning Changing the ID while the setting is registered with a SettingsObject results in
|
||||||
|
* undefined behavior.
|
||||||
* \return The ID of the setting.
|
* \return The ID of the setting.
|
||||||
*/
|
*/
|
||||||
virtual QString id() const { return m_id; }
|
virtual QString id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets this setting's config file key.
|
* \brief Gets this setting's config file key.
|
||||||
* This is used to store the setting's value in the config file. It is usually
|
* This is used to store the setting's value in the config file. It is usually
|
||||||
* the same as the setting's ID, but it can be different.
|
* the same as the setting's ID, but it can be different.
|
||||||
* \return The setting's config file key.
|
* \return The setting's config file key.
|
||||||
*/
|
*/
|
||||||
virtual QString configKey() const { return id(); }
|
virtual QString configKey() const
|
||||||
|
{
|
||||||
|
return id();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets this setting's value as a QVariant.
|
* \brief Gets this setting's value as a QVariant.
|
||||||
* This is done by calling the SettingsObject's retrieveValue() function.
|
* This is done by calling the SettingsObject's retrieveValue() function.
|
||||||
@ -60,22 +66,23 @@ public:
|
|||||||
* \sa value()
|
* \sa value()
|
||||||
*/
|
*/
|
||||||
virtual QVariant get() const;
|
virtual QVariant get() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets this setting's actual value (I.E. not as a QVariant).
|
* \brief Gets this setting's actual value (I.E. not as a QVariant).
|
||||||
* This function is just shorthand for get().value<T>()
|
* This function is just shorthand for get().value<T>()
|
||||||
* \return The setting's actual value.
|
* \return The setting's actual value.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template <typename T> inline T value() const
|
||||||
inline T value() const { return get().value<T>(); }
|
{
|
||||||
|
return get().value<T>();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets this setting's default value.
|
* \brief Gets this setting's default value.
|
||||||
* \return The default value of this setting.
|
* \return The default value of this setting.
|
||||||
*/
|
*/
|
||||||
virtual QVariant defValue() const;
|
virtual QVariant defValue() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/*!
|
/*!
|
||||||
* \brief Signal emitted when this Setting object's value changes.
|
* \brief Signal emitted when this Setting object's value changes.
|
||||||
@ -83,14 +90,15 @@ signals:
|
|||||||
* \param value This Setting object's new value.
|
* \param value This Setting object's new value.
|
||||||
*/
|
*/
|
||||||
void settingChanged(const Setting &setting, QVariant value);
|
void settingChanged(const Setting &setting, QVariant value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Signal emitted when this Setting object's value resets to default.
|
* \brief Signal emitted when this Setting object's value resets to default.
|
||||||
* \param setting A reference to the Setting that changed.
|
* \param setting A reference to the Setting that changed.
|
||||||
*/
|
*/
|
||||||
void settingReset(const Setting &setting);
|
void settingReset(const Setting &setting);
|
||||||
|
|
||||||
public slots:
|
public
|
||||||
|
slots:
|
||||||
/*!
|
/*!
|
||||||
* \brief Changes the setting's value.
|
* \brief Changes the setting's value.
|
||||||
* This is done by emitting the settingChanged() signal which will then be
|
* This is done by emitting the settingChanged() signal which will then be
|
||||||
@ -98,7 +106,7 @@ public slots:
|
|||||||
* \param value The new value.
|
* \param value The new value.
|
||||||
*/
|
*/
|
||||||
virtual void set(QVariant value);
|
virtual void set(QVariant value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Reset the setting to default
|
* \brief Reset the setting to default
|
||||||
* This is done by emitting the settingReset() signal which will then be
|
* This is done by emitting the settingReset() signal which will then be
|
||||||
@ -106,9 +114,8 @@ public slots:
|
|||||||
* \param value The new value.
|
* \param value The new value.
|
||||||
*/
|
*/
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString m_id;
|
QString m_id;
|
||||||
QVariant m_defVal;
|
QVariant m_defVal;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SETTING_H
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -23,9 +23,10 @@
|
|||||||
class Setting;
|
class Setting;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The SettingsObject handles communicating settings between the application and a settings file.
|
* \brief The SettingsObject handles communicating settings between the application and a
|
||||||
|
*settings file.
|
||||||
* The class keeps a list of Setting objects. Each Setting object represents one
|
* The class keeps a list of Setting objects. Each Setting object represents one
|
||||||
* of the application's settings. These Setting objects are registered with
|
* of the application's settings. These Setting objects are registered with
|
||||||
* a SettingsObject and can be managed similarly to the way a list works.
|
* a SettingsObject and can be managed similarly to the way a list works.
|
||||||
*
|
*
|
||||||
* \author Andrew Okin
|
* \author Andrew Okin
|
||||||
@ -38,9 +39,10 @@ class LIBSETTINGS_EXPORT SettingsObject : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SettingsObject(QObject *parent = 0);
|
explicit SettingsObject(QObject *parent = 0);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Registers the given setting with this SettingsObject and connects the necessary signals.
|
* \brief Registers the given setting with this SettingsObject and connects the necessary
|
||||||
|
* signals.
|
||||||
* This will fail if there is already a setting with the same ID as
|
* This will fail if there is already a setting with the same ID as
|
||||||
* the one that is being registered.
|
* the one that is being registered.
|
||||||
* \note Registering a setting object causes the SettingsObject to take ownership
|
* \note Registering a setting object causes the SettingsObject to take ownership
|
||||||
@ -52,36 +54,38 @@ public:
|
|||||||
* \return True if successful. False if registry failed.
|
* \return True if successful. False if registry failed.
|
||||||
*/
|
*/
|
||||||
virtual bool registerSetting(Setting *setting);
|
virtual bool registerSetting(Setting *setting);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Unregisters the given setting from this SettingsObject and disconnects its signals.
|
* \brief Unregisters the given setting from this SettingsObject and disconnects its
|
||||||
* \note This does not delete the setting. Furthermore, when the setting is
|
* signals.
|
||||||
|
* \note This does not delete the setting. Furthermore, when the setting is
|
||||||
* unregistered, the SettingsObject drops ownership of the setting. This means
|
* unregistered, the SettingsObject drops ownership of the setting. This means
|
||||||
* that if you unregister a setting, its parent is set to null and you become
|
* that if you unregister a setting, its parent is set to null and you become
|
||||||
* responsible for freeing its memory.
|
* responsible for freeing its memory.
|
||||||
* \param setting The setting to unregister.
|
* \param setting The setting to unregister.
|
||||||
*/
|
*/
|
||||||
virtual void unregisterSetting(Setting *setting);
|
virtual void unregisterSetting(Setting *setting);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the setting with the given ID.
|
* \brief Gets the setting with the given ID.
|
||||||
* \param id The ID of the setting to get.
|
* \param id The ID of the setting to get.
|
||||||
* \return A pointer to the setting with the given ID.
|
* \return A pointer to the setting with the given ID.
|
||||||
* Returns null if there is no setting with the given ID.
|
* Returns null if there is no setting with the given ID.
|
||||||
* \sa operator []()
|
* \sa operator []()
|
||||||
*/
|
*/
|
||||||
virtual Setting *getSetting(const QString &id) const;
|
virtual Setting *getSetting(const QString &id) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Same as getSetting()
|
* \brief Same as getSetting()
|
||||||
* \param id The ID of the setting to get.
|
* \param id The ID of the setting to get.
|
||||||
* \return A pointer to the setting with the given ID.
|
* \return A pointer to the setting with the given ID.
|
||||||
* \sa getSetting()
|
* \sa getSetting()
|
||||||
*/
|
*/
|
||||||
inline Setting *operator [](const QString &id) { return getSetting(id); }
|
inline Setting *operator[](const QString &id)
|
||||||
|
{
|
||||||
|
return getSetting(id);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets the value of the setting with the given ID.
|
* \brief Gets the value of the setting with the given ID.
|
||||||
* \param id The ID of the setting to get.
|
* \param id The ID of the setting to get.
|
||||||
@ -89,7 +93,7 @@ public:
|
|||||||
* If no setting with the given ID exists, returns an invalid QVariant.
|
* If no setting with the given ID exists, returns an invalid QVariant.
|
||||||
*/
|
*/
|
||||||
virtual QVariant get(const QString &id) const;
|
virtual QVariant get(const QString &id) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the value of the setting with the given ID.
|
* \brief Sets the value of the setting with the given ID.
|
||||||
* If no setting with the given ID exists, returns false and logs to qDebug
|
* If no setting with the given ID exists, returns false and logs to qDebug
|
||||||
@ -98,87 +102,88 @@ public:
|
|||||||
* \return True if successful, false if it failed.
|
* \return True if successful, false if it failed.
|
||||||
*/
|
*/
|
||||||
virtual bool set(const QString &id, QVariant value);
|
virtual bool set(const QString &id, QVariant value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Reverts the setting with the given ID to default.
|
* \brief Reverts the setting with the given ID to default.
|
||||||
* \param id The ID of the setting to reset.
|
* \param id The ID of the setting to reset.
|
||||||
*/
|
*/
|
||||||
virtual void reset(const QString &id) const;
|
virtual void reset(const QString &id) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets a QList with pointers to all of the registered settings.
|
* \brief Gets a QList with pointers to all of the registered settings.
|
||||||
* The order of the entries in the list is undefined.
|
* The order of the entries in the list is undefined.
|
||||||
* \return A QList with pointers to all registered settings.
|
* \return A QList with pointers to all registered settings.
|
||||||
*/
|
*/
|
||||||
virtual QList<Setting *> getSettings();
|
virtual QList<Setting *> getSettings();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Checks if this SettingsObject contains a setting with the given ID.
|
* \brief Checks if this SettingsObject contains a setting with the given ID.
|
||||||
* \param id The ID to check for.
|
* \param id The ID to check for.
|
||||||
* \return True if the SettingsObject has a setting with the given ID.
|
* \return True if the SettingsObject has a setting with the given ID.
|
||||||
*/
|
*/
|
||||||
virtual bool contains(const QString &id);
|
virtual bool contains(const QString &id);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/*!
|
/*!
|
||||||
* \brief Signal emitted when one of this SettingsObject object's settings changes.
|
* \brief Signal emitted when one of this SettingsObject object's settings changes.
|
||||||
* This is usually just connected directly to each Setting object's
|
* This is usually just connected directly to each Setting object's
|
||||||
* settingChanged() signals.
|
* settingChanged() signals.
|
||||||
* \param setting A reference to the Setting object that changed.
|
* \param setting A reference to the Setting object that changed.
|
||||||
* \param value The Setting object's new value.
|
* \param value The Setting object's new value.
|
||||||
*/
|
*/
|
||||||
void settingChanged(const Setting &setting, QVariant value);
|
void settingChanged(const Setting &setting, QVariant value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Signal emitted when one of this SettingsObject object's settings resets.
|
* \brief Signal emitted when one of this SettingsObject object's settings resets.
|
||||||
* This is usually just connected directly to each Setting object's
|
* This is usually just connected directly to each Setting object's
|
||||||
* settingReset() signals.
|
* settingReset() signals.
|
||||||
* \param setting A reference to the Setting object that changed.
|
* \param setting A reference to the Setting object that changed.
|
||||||
*/
|
*/
|
||||||
void settingReset(const Setting &setting);
|
void settingReset(const Setting &setting);
|
||||||
|
|
||||||
protected slots:
|
protected
|
||||||
|
slots:
|
||||||
/*!
|
/*!
|
||||||
* \brief Changes a setting.
|
* \brief Changes a setting.
|
||||||
* This slot is usually connected to each Setting object's
|
* This slot is usually connected to each Setting object's
|
||||||
* settingChanged() signal. The signal is emitted, causing this slot
|
* settingChanged() signal. The signal is emitted, causing this slot
|
||||||
* to update the setting's value in the config file.
|
* to update the setting's value in the config file.
|
||||||
* \param setting A reference to the Setting object that changed.
|
* \param setting A reference to the Setting object that changed.
|
||||||
* \param value The setting's new value.
|
* \param value The setting's new value.
|
||||||
*/
|
*/
|
||||||
virtual void changeSetting(const Setting &setting, QVariant value) = 0;
|
virtual void changeSetting(const Setting &setting, QVariant value) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Resets a setting.
|
* \brief Resets a setting.
|
||||||
* This slot is usually connected to each Setting object's
|
* This slot is usually connected to each Setting object's
|
||||||
* settingReset() signal. The signal is emitted, causing this slot
|
* settingReset() signal. The signal is emitted, causing this slot
|
||||||
* to update the setting's value in the config file.
|
* to update the setting's value in the config file.
|
||||||
* \param setting A reference to the Setting object that changed.
|
* \param setting A reference to the Setting object that changed.
|
||||||
*/
|
*/
|
||||||
virtual void resetSetting(const Setting &setting) = 0;
|
virtual void resetSetting(const Setting &setting) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
* \brief Connects the necessary signals to the given Setting.
|
* \brief Connects the necessary signals to the given Setting.
|
||||||
* \param setting The setting to connect.
|
* \param setting The setting to connect.
|
||||||
*/
|
*/
|
||||||
virtual void connectSignals(const Setting &setting);
|
virtual void connectSignals(const Setting &setting);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Disconnects signals from the given Setting.
|
* \brief Disconnects signals from the given Setting.
|
||||||
* \param setting The setting to disconnect.
|
* \param setting The setting to disconnect.
|
||||||
*/
|
*/
|
||||||
virtual void disconnectSignals(const Setting &setting);
|
virtual void disconnectSignals(const Setting &setting);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Function used by Setting objects to get their values from the SettingsObject.
|
* \brief Function used by Setting objects to get their values from the SettingsObject.
|
||||||
* \param setting The
|
* \param setting The
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
virtual QVariant retrieveValue(const Setting &setting) = 0;
|
virtual QVariant retrieveValue(const Setting &setting) = 0;
|
||||||
|
|
||||||
friend class Setting;
|
friend class Setting;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QString, Setting *> m_settings;
|
QMap<QString, Setting *> m_settings;
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -16,17 +16,15 @@
|
|||||||
#include "include/basicsettingsobject.h"
|
#include "include/basicsettingsobject.h"
|
||||||
#include "include/setting.h"
|
#include "include/setting.h"
|
||||||
|
|
||||||
BasicSettingsObject::BasicSettingsObject(QObject *parent) :
|
BasicSettingsObject::BasicSettingsObject(QObject *parent) : SettingsObject(parent)
|
||||||
SettingsObject(parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicSettingsObject::changeSetting(const Setting &setting, QVariant value)
|
void BasicSettingsObject::changeSetting(const Setting &setting, QVariant value)
|
||||||
{
|
{
|
||||||
if (contains(setting.id()))
|
if (contains(setting.id()))
|
||||||
{
|
{
|
||||||
if(value.isValid())
|
if (value.isValid())
|
||||||
config.setValue(setting.configKey(), value);
|
config.setValue(setting.configKey(), value);
|
||||||
else
|
else
|
||||||
config.remove(setting.configKey());
|
config.remove(setting.configKey());
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -19,10 +19,8 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
|
|
||||||
INIFile::INIFile()
|
INIFile::INIFile()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString INIFile::unescape(QString orig)
|
QString INIFile::unescape(QString orig)
|
||||||
@ -47,50 +45,50 @@ bool INIFile::saveFile(QString fileName)
|
|||||||
file.open(QIODevice::WriteOnly);
|
file.open(QIODevice::WriteOnly);
|
||||||
QTextStream out(&file);
|
QTextStream out(&file);
|
||||||
out.setCodec("UTF-8");
|
out.setCodec("UTF-8");
|
||||||
|
|
||||||
for (Iterator iter = begin(); iter != end(); iter++)
|
for (Iterator iter = begin(); iter != end(); iter++)
|
||||||
{
|
{
|
||||||
QString value = iter.value().toString();
|
QString value = iter.value().toString();
|
||||||
value = escape(value);
|
value = escape(value);
|
||||||
out << iter.key() << "=" << value << "\n";
|
out << iter.key() << "=" << value << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool INIFile::loadFile(QString fileName)
|
bool INIFile::loadFile(QString fileName)
|
||||||
{
|
{
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if(!file.open(QIODevice::ReadOnly))
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
return false;
|
return false;
|
||||||
bool success = loadFile(file.readAll());
|
bool success = loadFile(file.readAll());
|
||||||
file.close();
|
file.close();
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
bool INIFile::loadFile( QByteArray file )
|
bool INIFile::loadFile(QByteArray file)
|
||||||
{
|
{
|
||||||
QTextStream in(file);
|
QTextStream in(file);
|
||||||
in.setCodec("UTF-8");
|
in.setCodec("UTF-8");
|
||||||
|
|
||||||
QStringList lines = in.readAll().split('\n');
|
QStringList lines = in.readAll().split('\n');
|
||||||
for (int i = 0; i < lines.count(); i++)
|
for (int i = 0; i < lines.count(); i++)
|
||||||
{
|
{
|
||||||
QString & lineRaw = lines[i];
|
QString &lineRaw = lines[i];
|
||||||
// Ignore comments.
|
// Ignore comments.
|
||||||
QString line = lineRaw.left(lineRaw.indexOf('#')).trimmed();
|
QString line = lineRaw.left(lineRaw.indexOf('#')).trimmed();
|
||||||
|
|
||||||
int eqPos = line.indexOf('=');
|
int eqPos = line.indexOf('=');
|
||||||
if(eqPos == -1)
|
if (eqPos == -1)
|
||||||
continue;
|
continue;
|
||||||
QString key = line.left(eqPos).trimmed();
|
QString key = line.left(eqPos).trimmed();
|
||||||
QString valueStr = line.right(line.length() - eqPos - 1).trimmed();
|
QString valueStr = line.right(line.length() - eqPos - 1).trimmed();
|
||||||
|
|
||||||
valueStr = unescape(valueStr);
|
valueStr = unescape(valueStr);
|
||||||
|
|
||||||
QVariant value(valueStr);
|
QVariant value(valueStr);
|
||||||
this->operator [](key) = value;
|
this->operator[](key) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,10 +97,10 @@ QVariant INIFile::get(QString key, QVariant def) const
|
|||||||
if (!this->contains(key))
|
if (!this->contains(key))
|
||||||
return def;
|
return def;
|
||||||
else
|
else
|
||||||
return this->operator [](key);
|
return this->operator[](key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void INIFile::set(QString key, QVariant val)
|
void INIFile::set(QString key, QVariant val)
|
||||||
{
|
{
|
||||||
this->operator [](key) = val;
|
this->operator[](key) = val;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -16,8 +16,8 @@
|
|||||||
#include "include/inisettingsobject.h"
|
#include "include/inisettingsobject.h"
|
||||||
#include "include/setting.h"
|
#include "include/setting.h"
|
||||||
|
|
||||||
INISettingsObject::INISettingsObject(const QString &path, QObject *parent) :
|
INISettingsObject::INISettingsObject(const QString &path, QObject *parent)
|
||||||
SettingsObject(parent)
|
: SettingsObject(parent)
|
||||||
{
|
{
|
||||||
m_filePath = path;
|
m_filePath = path;
|
||||||
m_ini.loadFile(path);
|
m_ini.loadFile(path);
|
||||||
@ -32,7 +32,7 @@ void INISettingsObject::changeSetting(const Setting &setting, QVariant value)
|
|||||||
{
|
{
|
||||||
if (contains(setting.id()))
|
if (contains(setting.id()))
|
||||||
{
|
{
|
||||||
if(value.isValid())
|
if (value.isValid())
|
||||||
m_ini.set(setting.configKey(), value);
|
m_ini.set(setting.configKey(), value);
|
||||||
else
|
else
|
||||||
m_ini.remove(setting.configKey());
|
m_ini.remove(setting.configKey());
|
||||||
@ -40,7 +40,7 @@ void INISettingsObject::changeSetting(const Setting &setting, QVariant value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void INISettingsObject::resetSetting ( const Setting& setting )
|
void INISettingsObject::resetSetting(const Setting &setting)
|
||||||
{
|
{
|
||||||
if (contains(setting.id()))
|
if (contains(setting.id()))
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
#include "include/overridesetting.h"
|
#include "include/overridesetting.h"
|
||||||
|
|
||||||
OverrideSetting::OverrideSetting(const QString &name, Setting *other, QObject *parent) :
|
OverrideSetting::OverrideSetting(const QString &name, Setting *other, QObject *parent)
|
||||||
Setting(name, QVariant(), parent)
|
: Setting(name, QVariant(), parent)
|
||||||
{
|
{
|
||||||
m_other = other;
|
m_other = other;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -16,10 +16,9 @@
|
|||||||
#include "include/setting.h"
|
#include "include/setting.h"
|
||||||
#include "include/settingsobject.h"
|
#include "include/settingsobject.h"
|
||||||
|
|
||||||
Setting::Setting(QString id, QVariant defVal, QObject *parent) :
|
Setting::Setting(QString id, QVariant defVal, QObject *parent)
|
||||||
QObject(parent), m_id(id), m_defVal(defVal)
|
: QObject(parent), m_id(id), m_defVal(defVal)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant Setting::get() const
|
QVariant Setting::get() const
|
||||||
@ -32,7 +31,7 @@ QVariant Setting::get() const
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
QVariant test = sbase->retrieveValue(*this);
|
QVariant test = sbase->retrieveValue(*this);
|
||||||
if(!test.isValid())
|
if (!test.isValid())
|
||||||
return defValue();
|
return defValue();
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -18,10 +18,8 @@
|
|||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
SettingsObject::SettingsObject(QObject *parent) :
|
SettingsObject::SettingsObject(QObject *parent) : QObject(parent)
|
||||||
QObject(parent)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsObject::registerSetting(Setting *setting)
|
bool SettingsObject::registerSetting(Setting *setting)
|
||||||
@ -29,24 +27,26 @@ bool SettingsObject::registerSetting(Setting *setting)
|
|||||||
// Check if setting is null or we already have a setting with the same ID.
|
// Check if setting is null or we already have a setting with the same ID.
|
||||||
if (!setting)
|
if (!setting)
|
||||||
{
|
{
|
||||||
qDebug(QString("Failed to register setting. Setting is null.").
|
qDebug(QString("Failed to register setting. Setting is null.")
|
||||||
arg(setting->id()).toUtf8());
|
.arg(setting->id())
|
||||||
|
.toUtf8());
|
||||||
return false; // Fail
|
return false; // Fail
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contains(setting->id()))
|
if (contains(setting->id()))
|
||||||
{
|
{
|
||||||
qDebug(QString("Failed to register setting %1. ID already exists.").
|
qDebug(QString("Failed to register setting %1. ID already exists.")
|
||||||
arg(setting->id()).toUtf8());
|
.arg(setting->id())
|
||||||
|
.toUtf8());
|
||||||
return false; // Fail
|
return false; // Fail
|
||||||
}
|
}
|
||||||
|
|
||||||
m_settings.insert(setting->id(), setting);
|
m_settings.insert(setting->id(), setting);
|
||||||
setting->setParent(this); // Take ownership.
|
setting->setParent(this); // Take ownership.
|
||||||
|
|
||||||
// Connect signals.
|
// Connect signals.
|
||||||
connectSignals(*setting);
|
connectSignals(*setting);
|
||||||
|
|
||||||
// qDebug(QString("Registered setting %1.").arg(setting->id()).toUtf8());
|
// qDebug(QString("Registered setting %1.").arg(setting->id()).toUtf8());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -55,22 +55,21 @@ void SettingsObject::unregisterSetting(Setting *setting)
|
|||||||
{
|
{
|
||||||
if (!setting || !m_settings.contains(setting->id()))
|
if (!setting || !m_settings.contains(setting->id()))
|
||||||
return; // We can't unregister something that's not registered.
|
return; // We can't unregister something that's not registered.
|
||||||
|
|
||||||
m_settings.remove(setting->id());
|
m_settings.remove(setting->id());
|
||||||
|
|
||||||
// Disconnect signals.
|
// Disconnect signals.
|
||||||
disconnectSignals(*setting);
|
disconnectSignals(*setting);
|
||||||
|
|
||||||
setting->setParent(NULL); // Drop ownership.
|
setting->setParent(NULL); // Drop ownership.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Setting *SettingsObject::getSetting(const QString &id) const
|
Setting *SettingsObject::getSetting(const QString &id) const
|
||||||
{
|
{
|
||||||
// Make sure there is a setting with the given ID.
|
// Make sure there is a setting with the given ID.
|
||||||
if (!m_settings.contains(id))
|
if (!m_settings.contains(id))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return m_settings[id];
|
return m_settings[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +84,7 @@ bool SettingsObject::set(const QString &id, QVariant value)
|
|||||||
Setting *setting = getSetting(id);
|
Setting *setting = getSetting(id);
|
||||||
if (!setting)
|
if (!setting)
|
||||||
{
|
{
|
||||||
qDebug(QString("Error changing setting %1. Setting doesn't exist.").
|
qDebug(QString("Error changing setting %1. Setting doesn't exist.").arg(id).toUtf8());
|
||||||
arg(id).toUtf8());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -99,11 +97,10 @@ bool SettingsObject::set(const QString &id, QVariant value)
|
|||||||
void SettingsObject::reset(const QString &id) const
|
void SettingsObject::reset(const QString &id) const
|
||||||
{
|
{
|
||||||
Setting *setting = getSetting(id);
|
Setting *setting = getSetting(id);
|
||||||
if(setting)
|
if (setting)
|
||||||
setting->reset();
|
setting->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QList<Setting *> SettingsObject::getSettings()
|
QList<Setting *> SettingsObject::getSettings()
|
||||||
{
|
{
|
||||||
return m_settings.values();
|
return m_settings.values();
|
||||||
@ -114,29 +111,26 @@ bool SettingsObject::contains(const QString &id)
|
|||||||
return m_settings.contains(id);
|
return m_settings.contains(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SettingsObject::connectSignals(const Setting &setting)
|
void SettingsObject::connectSignals(const Setting &setting)
|
||||||
{
|
{
|
||||||
connect(&setting, SIGNAL(settingChanged(const Setting &, QVariant)),
|
connect(&setting, SIGNAL(settingChanged(const Setting &, QVariant)),
|
||||||
SLOT(changeSetting(const Setting &, QVariant)));
|
SLOT(changeSetting(const Setting &, QVariant)));
|
||||||
connect(&setting, SIGNAL(settingChanged(const Setting &, QVariant)),
|
connect(&setting, SIGNAL(settingChanged(const Setting &, QVariant)),
|
||||||
SIGNAL(settingChanged(const Setting &, QVariant)));
|
SIGNAL(settingChanged(const Setting &, QVariant)));
|
||||||
|
|
||||||
connect(&setting, SIGNAL(settingReset(Setting)),
|
connect(&setting, SIGNAL(settingReset(Setting)), SLOT(resetSetting(const Setting &)));
|
||||||
SLOT(resetSetting(const Setting &)));
|
connect(&setting, SIGNAL(settingReset(Setting)), SIGNAL(settingReset(const Setting &)));
|
||||||
connect(&setting, SIGNAL(settingReset(Setting)),
|
|
||||||
SIGNAL(settingReset(const Setting &)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsObject::disconnectSignals(const Setting &setting)
|
void SettingsObject::disconnectSignals(const Setting &setting)
|
||||||
{
|
{
|
||||||
setting.disconnect(SIGNAL(settingChanged(const Setting &, QVariant)),
|
setting.disconnect(SIGNAL(settingChanged(const Setting &, QVariant)), this,
|
||||||
this, SLOT(changeSetting(const Setting &, QVariant)));
|
SLOT(changeSetting(const Setting &, QVariant)));
|
||||||
setting.disconnect(SIGNAL(settingChanged(const Setting &, QVariant)),
|
setting.disconnect(SIGNAL(settingChanged(const Setting &, QVariant)), this,
|
||||||
this, SIGNAL(settingChanged(const Setting &, QVariant)));
|
SIGNAL(settingChanged(const Setting &, QVariant)));
|
||||||
|
|
||||||
setting.disconnect(SIGNAL(settingReset(const Setting &, QVariant)),
|
setting.disconnect(SIGNAL(settingReset(const Setting &, QVariant)), this,
|
||||||
this, SLOT(resetSetting(const Setting &, QVariant)));
|
SLOT(resetSetting(const Setting &, QVariant)));
|
||||||
setting.disconnect(SIGNAL(settingReset(const Setting &, QVariant)),
|
setting.disconnect(SIGNAL(settingReset(const Setting &, QVariant)), this,
|
||||||
this, SIGNAL(settingReset(const Setting &, QVariant)));
|
SIGNAL(settingReset(const Setting &, QVariant)));
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ QString scramble(QString in_)
|
|||||||
{
|
{
|
||||||
QByteArray in = in_.toUtf8();
|
QByteArray in = in_.toUtf8();
|
||||||
QByteArray out;
|
QByteArray out;
|
||||||
for (int i = 0; i<in.length(); i++)
|
for (int i = 0; i < in.length(); i++)
|
||||||
out.append(in.at(i) ^ scrambler);
|
out.append(in.at(i) ^ scrambler);
|
||||||
return QString::fromUtf8(out);
|
return QString::fromUtf8(out);
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ QStringList StubKeyring::getStoredAccounts(QString service)
|
|||||||
QStringList out;
|
QStringList out;
|
||||||
QStringList in(m_settings.allKeys());
|
QStringList in(m_settings.allKeys());
|
||||||
QStringListIterator it(in);
|
QStringListIterator it(in);
|
||||||
while(it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
QString c = it.next();
|
QString c = it.next();
|
||||||
if (c.startsWith(service))
|
if (c.startsWith(service))
|
||||||
@ -90,15 +90,16 @@ QStringList StubKeyring::getStoredAccounts(QString service)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StubKeyring::removeStoredAccount ( QString service, QString username )
|
void StubKeyring::removeStoredAccount(QString service, QString username)
|
||||||
{
|
{
|
||||||
QString key = generateKey(service, username);
|
QString key = generateKey(service, username);
|
||||||
m_settings.remove(key);
|
m_settings.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: this needs tweaking/changes for user account level storage
|
// FIXME: this needs tweaking/changes for user account level storage
|
||||||
StubKeyring::StubKeyring() :
|
StubKeyring::StubKeyring()
|
||||||
// m_settings(QSettings::UserScope, "Orochimarufan", "Keyring")
|
:
|
||||||
m_settings("keyring.cfg", QSettings::IniFormat)
|
// m_settings(QSettings::UserScope, "Orochimarufan", "Keyring")
|
||||||
|
m_settings("keyring.cfg", QSettings::IniFormat)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STUBKEYRING_H
|
#pragma once
|
||||||
#define STUBKEYRING_H
|
|
||||||
|
|
||||||
#include "include/keyring.h"
|
#include "include/keyring.h"
|
||||||
|
|
||||||
@ -30,12 +29,14 @@ public:
|
|||||||
virtual bool hasPassword(QString service, QString username);
|
virtual bool hasPassword(QString service, QString username);
|
||||||
virtual QStringList getStoredAccounts(QString service);
|
virtual QStringList getStoredAccounts(QString service);
|
||||||
virtual void removeStoredAccount(QString service, QString username);
|
virtual void removeStoredAccount(QString service, QString username);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Keyring;
|
friend class Keyring;
|
||||||
explicit StubKeyring();
|
explicit StubKeyring();
|
||||||
virtual bool isValid() { return true; }
|
virtual bool isValid()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QSettings m_settings;
|
QSettings m_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STUBKEYRING_H
|
|
||||||
|
@ -22,21 +22,18 @@ find_package(Qt5Core REQUIRED)
|
|||||||
include_directories(${Qt5Base_INCLUDE_DIRS})
|
include_directories(${Qt5Base_INCLUDE_DIRS})
|
||||||
# include_directories(${Qt5Network_INCLUDE_DIRS})
|
# include_directories(${Qt5Network_INCLUDE_DIRS})
|
||||||
|
|
||||||
SET(LIBUTIL_HEADERS
|
SET(LIBUTIL_SOURCES
|
||||||
include/libutil_config.h
|
include/libutil_config.h
|
||||||
|
|
||||||
include/apputils.h
|
|
||||||
|
|
||||||
include/pathutils.h
|
include/pathutils.h
|
||||||
include/osutils.h
|
|
||||||
include/userutils.h
|
|
||||||
include/cmdutils.h
|
|
||||||
)
|
|
||||||
|
|
||||||
SET(LIBUTIL_SOURCES
|
|
||||||
src/pathutils.cpp
|
src/pathutils.cpp
|
||||||
src/osutils.cpp
|
|
||||||
|
include/osutils.h
|
||||||
|
|
||||||
|
include/userutils.h
|
||||||
src/userutils.cpp
|
src/userutils.cpp
|
||||||
|
|
||||||
|
include/cmdutils.h
|
||||||
src/cmdutils.cpp
|
src/cmdutils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -50,7 +47,7 @@ add_definitions(-DLIBUTIL_LIBRARY)
|
|||||||
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
add_library(libUtil STATIC ${LIBUTIL_SOURCES} ${LIBUTIL_HEADERS})
|
add_library(libUtil STATIC ${LIBUTIL_SOURCES})
|
||||||
# qt5_use_modules(libUtil Core Network)
|
# qt5_use_modules(libUtil Core Network)
|
||||||
qt5_use_modules(libUtil Core)
|
qt5_use_modules(libUtil Core)
|
||||||
target_link_libraries(libUtil)
|
target_link_libraries(libUtil)
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CMDUTILS_H
|
#pragma once
|
||||||
#define CMDUTILS_H
|
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -33,8 +32,10 @@
|
|||||||
* @brief commandline parsing and processing utilities
|
* @brief commandline parsing and processing utilities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Util {
|
namespace Util
|
||||||
namespace Commandline {
|
{
|
||||||
|
namespace Commandline
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief split a string into argv items like a shell would do
|
* @brief split a string into argv items like a shell would do
|
||||||
@ -52,13 +53,13 @@ namespace FlagStyle
|
|||||||
{
|
{
|
||||||
enum Enum
|
enum Enum
|
||||||
{
|
{
|
||||||
GNU, /**< --option and -o (GNU Style) */
|
GNU, /**< --option and -o (GNU Style) */
|
||||||
Unix, /**< -option and -o (Unix Style) */
|
Unix, /**< -option and -o (Unix Style) */
|
||||||
Windows, /**< /option and /o (Windows Style) */
|
Windows, /**< /option and /o (Windows Style) */
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
Default = Windows
|
Default = Windows
|
||||||
#else
|
#else
|
||||||
Default = GNU
|
Default = GNU
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -66,17 +67,17 @@ enum Enum
|
|||||||
/**
|
/**
|
||||||
* @brief The ArgumentStyle enum
|
* @brief The ArgumentStyle enum
|
||||||
*/
|
*/
|
||||||
namespace ArgumentStyle
|
namespace ArgumentStyle
|
||||||
{
|
{
|
||||||
enum Enum
|
enum Enum
|
||||||
{
|
{
|
||||||
Space, /**< --option=value */
|
Space, /**< --option=value */
|
||||||
Equals, /**< --option value */
|
Equals, /**< --option value */
|
||||||
SpaceAndEquals, /**< --option[= ]value */
|
SpaceAndEquals, /**< --option[= ]value */
|
||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
Default = Equals
|
Default = Equals
|
||||||
#else
|
#else
|
||||||
Default = SpaceAndEquals
|
Default = SpaceAndEquals
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -101,47 +102,47 @@ public:
|
|||||||
* @param flagStyle the FlagStyle to use in this Parser
|
* @param flagStyle the FlagStyle to use in this Parser
|
||||||
* @param argStyle the ArgumentStyle to use in this Parser
|
* @param argStyle the ArgumentStyle to use in this Parser
|
||||||
*/
|
*/
|
||||||
Parser(FlagStyle::Enum flagStyle = FlagStyle::Default,
|
Parser(FlagStyle::Enum flagStyle = FlagStyle::Default,
|
||||||
ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
|
ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief set the flag style
|
* @brief set the flag style
|
||||||
* @param style
|
* @param style
|
||||||
*/
|
*/
|
||||||
void setFlagStyle(FlagStyle::Enum style);
|
void setFlagStyle(FlagStyle::Enum style);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get the flag style
|
* @brief get the flag style
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
FlagStyle::Enum flagStyle();
|
FlagStyle::Enum flagStyle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief set the argument style
|
* @brief set the argument style
|
||||||
* @param style
|
* @param style
|
||||||
*/
|
*/
|
||||||
void setArgumentStyle(ArgumentStyle::Enum style);
|
void setArgumentStyle(ArgumentStyle::Enum style);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get the argument style
|
* @brief get the argument style
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ArgumentStyle::Enum argumentStyle();
|
ArgumentStyle::Enum argumentStyle();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief define a boolean switch
|
* @brief define a boolean switch
|
||||||
* @param name the parameter name
|
* @param name the parameter name
|
||||||
* @param def the default value
|
* @param def the default value
|
||||||
*/
|
*/
|
||||||
void addSwitch(QString name, bool def = false);
|
void addSwitch(QString name, bool def = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief define an option that takes an additional argument
|
* @brief define an option that takes an additional argument
|
||||||
* @param name the parameter name
|
* @param name the parameter name
|
||||||
* @param def the default value
|
* @param def the default value
|
||||||
*/
|
*/
|
||||||
void addOption(QString name, QVariant def = QVariant());
|
void addOption(QString name, QVariant def = QVariant());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief define a positional argument
|
* @brief define a positional argument
|
||||||
* @param name the parameter name
|
* @param name the parameter name
|
||||||
@ -149,7 +150,7 @@ public:
|
|||||||
* @param def the default value
|
* @param def the default value
|
||||||
*/
|
*/
|
||||||
void addArgument(QString name, bool required = true, QVariant def = QVariant());
|
void addArgument(QString name, bool required = true, QVariant def = QVariant());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief adds a flag to an existing parameter
|
* @brief adds a flag to an existing parameter
|
||||||
* @param name the (existing) parameter name
|
* @param name the (existing) parameter name
|
||||||
@ -158,7 +159,7 @@ public:
|
|||||||
* Note: any one parameter can only have one flag
|
* Note: any one parameter can only have one flag
|
||||||
*/
|
*/
|
||||||
void addShortOpt(QString name, QChar flag);
|
void addShortOpt(QString name, QChar flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief adds documentation to a Parameter
|
* @brief adds documentation to a Parameter
|
||||||
* @param name the parameter name
|
* @param name the parameter name
|
||||||
@ -168,7 +169,7 @@ public:
|
|||||||
* on options , metavar replaces the value placeholder
|
* on options , metavar replaces the value placeholder
|
||||||
*/
|
*/
|
||||||
void addDocumentation(QString name, QString doc, QString metavar = QString());
|
void addDocumentation(QString name, QString doc, QString metavar = QString());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief generate a help message
|
* @brief generate a help message
|
||||||
* @param progName the program name to use in the help message
|
* @param progName the program name to use in the help message
|
||||||
@ -177,7 +178,7 @@ public:
|
|||||||
* @return a help message
|
* @return a help message
|
||||||
*/
|
*/
|
||||||
QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
|
QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief generate a short usage message
|
* @brief generate a short usage message
|
||||||
* @param progName the program name to use in the usage message
|
* @param progName the program name to use in the usage message
|
||||||
@ -185,21 +186,21 @@ public:
|
|||||||
* @return a usage message
|
* @return a usage message
|
||||||
*/
|
*/
|
||||||
QString compileUsage(QString progName, bool useFlags = true);
|
QString compileUsage(QString progName, bool useFlags = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief parse
|
* @brief parse
|
||||||
* @param argv a QStringList containing the program ARGV
|
* @param argv a QStringList containing the program ARGV
|
||||||
* @return a QHash mapping argument names to their values
|
* @return a QHash mapping argument names to their values
|
||||||
*/
|
*/
|
||||||
QHash<QString, QVariant> parse(QStringList argv);
|
QHash<QString, QVariant> parse(QStringList argv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief clear all definitions
|
* @brief clear all definitions
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FlagStyle::Enum m_flagStyle;
|
FlagStyle::Enum m_flagStyle;
|
||||||
ArgumentStyle::Enum m_argStyle;
|
ArgumentStyle::Enum m_argStyle;
|
||||||
@ -209,16 +210,18 @@ private:
|
|||||||
otSwitch,
|
otSwitch,
|
||||||
otOption
|
otOption
|
||||||
};
|
};
|
||||||
|
|
||||||
// Important: the common part MUST BE COMMON ON ALL THREE structs
|
// Important: the common part MUST BE COMMON ON ALL THREE structs
|
||||||
struct CommonDef {
|
struct CommonDef
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString doc;
|
QString doc;
|
||||||
QString metavar;
|
QString metavar;
|
||||||
QVariant def;
|
QVariant def;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OptionDef {
|
struct OptionDef
|
||||||
|
{
|
||||||
// common
|
// common
|
||||||
QString name;
|
QString name;
|
||||||
QString doc;
|
QString doc;
|
||||||
@ -228,8 +231,9 @@ private:
|
|||||||
OptionType type;
|
OptionType type;
|
||||||
QChar flag;
|
QChar flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PositionalDef {
|
struct PositionalDef
|
||||||
|
{
|
||||||
// common
|
// common
|
||||||
QString name;
|
QString name;
|
||||||
QString doc;
|
QString doc;
|
||||||
@ -238,17 +242,14 @@ private:
|
|||||||
// positional
|
// positional
|
||||||
bool required;
|
bool required;
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<QString, OptionDef *> m_options;
|
QHash<QString, OptionDef *> m_options;
|
||||||
QHash<QChar, OptionDef *> m_flags;
|
QHash<QChar, OptionDef *> m_flags;
|
||||||
QHash<QString, CommonDef *> m_params;
|
QHash<QString, CommonDef *> m_params;
|
||||||
QList<PositionalDef *> m_positionals;
|
QList<PositionalDef *> m_positionals;
|
||||||
QList<OptionDef *> m_optionList;
|
QList<OptionDef *> m_optionList;
|
||||||
|
|
||||||
void getPrefix(QString &opt, QString &flag);
|
void getPrefix(QString &opt, QString &flag);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CMDUTILS_H
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -18,12 +18,11 @@
|
|||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
#ifdef LIBUTIL_STATIC
|
#ifdef LIBUTIL_STATIC
|
||||||
#define LIBUTIL_EXPORT
|
#define LIBUTIL_EXPORT
|
||||||
#else
|
#else
|
||||||
#ifdef LIBUTIL_LIBRARY
|
#ifdef LIBUTIL_LIBRARY
|
||||||
#define LIBUTIL_EXPORT Q_DECL_EXPORT
|
#define LIBUTIL_EXPORT Q_DECL_EXPORT
|
||||||
#else
|
#else
|
||||||
#define LIBUTIL_EXPORT Q_DECL_IMPORT
|
#define LIBUTIL_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,17 +13,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef OSUTILS_H
|
#pragma once
|
||||||
#define OSUTILS_H
|
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#if defined _WIN32 | defined _WIN64
|
#if defined _WIN32 | defined _WIN64
|
||||||
#define WINDOWS 1
|
#define WINDOWS 1
|
||||||
#elif __APPLE__ & __MACH__
|
#elif __APPLE__ &__MACH__
|
||||||
#define OSX 1
|
#define OSX 1
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
#define LINUX 1
|
#define LINUX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // OSUTILS_H
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PATHUTILS_H
|
#pragma once
|
||||||
#define PATHUTILS_H
|
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
@ -27,10 +26,10 @@ LIBUTIL_EXPORT QString AbsolutePath(QString path);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize path
|
* Normalize path
|
||||||
*
|
*
|
||||||
* Any paths inside the current directory will be normalized to relative paths (to current)
|
* Any paths inside the current directory will be normalized to relative paths (to current)
|
||||||
* Other paths will be made absolute
|
* Other paths will be made absolute
|
||||||
*
|
*
|
||||||
* Returns false if the path logic somehow filed (and normalizedPath in invalid)
|
* Returns false if the path logic somehow filed (and normalizedPath in invalid)
|
||||||
*/
|
*/
|
||||||
QString NormalizePath(QString path);
|
QString NormalizePath(QString path);
|
||||||
@ -54,9 +53,7 @@ LIBUTIL_EXPORT bool ensureFolderPathExists(QString filenamepath);
|
|||||||
LIBUTIL_EXPORT bool copyPath(QString src, QString dst);
|
LIBUTIL_EXPORT bool copyPath(QString src, QString dst);
|
||||||
|
|
||||||
/// Opens the given file in the default application.
|
/// Opens the given file in the default application.
|
||||||
LIBUTIL_EXPORT void openFileInDefaultProgram ( QString filename );
|
LIBUTIL_EXPORT void openFileInDefaultProgram(QString filename);
|
||||||
|
|
||||||
/// Opens the given directory in the default application.
|
/// Opens the given directory in the default application.
|
||||||
LIBUTIL_EXPORT void openDirInDefaultProgram ( QString dirpath, bool ensureExists = false );
|
LIBUTIL_EXPORT void openDirInDefaultProgram(QString dirpath, bool ensureExists = false);
|
||||||
|
|
||||||
#endif // PATHUTILS_H
|
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
/* Copyright 2013 MultiMC Contributors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SIGLIST_H
|
|
||||||
#define SIGLIST_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QList>
|
|
||||||
|
|
||||||
// A QList that allows emitting signals when the list changes.
|
|
||||||
// Since QObject doesn't support templates, to use this class with a
|
|
||||||
// certain type, you should create a class deriving from SigList<T> and then
|
|
||||||
// call the DEFINE_SIGLIST_SIGNALS(T) and SETUP_SIGLIST_SIGNALS(T) macros.
|
|
||||||
template <typename T>
|
|
||||||
class SigList : public QList<T>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SigList() : QList<T>() {}
|
|
||||||
|
|
||||||
virtual void append(const T &value);
|
|
||||||
virtual void append(const QList<T> &other);
|
|
||||||
|
|
||||||
virtual void clear();
|
|
||||||
|
|
||||||
virtual void erase(typename QList<T>::iterator pos);
|
|
||||||
virtual void erase(typename QList<T>::iterator first, typename QList<T>::iterator last);
|
|
||||||
|
|
||||||
virtual void insert(int i, const T &t);
|
|
||||||
virtual void insert(typename QList<T>::iterator before, const T &t);
|
|
||||||
|
|
||||||
virtual void move(int from, int to);
|
|
||||||
|
|
||||||
virtual void pop_back() { takeLast(); }
|
|
||||||
virtual void pop_front() { takeFirst(); }
|
|
||||||
|
|
||||||
virtual void push_back(const T &t) { append(t); }
|
|
||||||
virtual void push_front(const T &t) { prepend(t); }
|
|
||||||
|
|
||||||
virtual void prepend(const T &t);
|
|
||||||
|
|
||||||
virtual int removeAll(const T &t);
|
|
||||||
virtual bool removeOne(const T &t);
|
|
||||||
|
|
||||||
virtual void removeAt(int i) { takeAt(i); }
|
|
||||||
virtual void removeFirst() { takeFirst(); }
|
|
||||||
virtual void removeLast() { takeLast(); }
|
|
||||||
|
|
||||||
virtual void swap(QList<T> &other);
|
|
||||||
virtual void swap(int i, int j);
|
|
||||||
|
|
||||||
virtual T takeAt(int i);
|
|
||||||
virtual T takeFirst();
|
|
||||||
virtual T takeLast();
|
|
||||||
|
|
||||||
virtual QList<T> &operator +=(const QList<T> &other) { append(other); return *this; }
|
|
||||||
virtual QList<T> &operator +=(const T &value) { append(value); return *this; }
|
|
||||||
virtual QList<T> &operator <<(const QList<T> &other) { append(other); return *this; }
|
|
||||||
virtual QList<T> &operator <<(const T &value) { append(value); return *this; }
|
|
||||||
|
|
||||||
virtual QList<T> &operator =(const QList<T> &other);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Signal emitted after an item is added to the list.
|
|
||||||
// Contains a reference to item and the item's new index.
|
|
||||||
virtual void onItemAdded(const T &item, int index) = 0;
|
|
||||||
|
|
||||||
// Signal emitted after multiple items are added to the list at once.
|
|
||||||
// The items parameter is a const reference to a QList of the items that
|
|
||||||
// were added.
|
|
||||||
// The firstIndex parameter is the new index of the first item added.
|
|
||||||
virtual void onItemsAdded(const QList<T> &items, int firstIndex) = 0;
|
|
||||||
|
|
||||||
// Signal emitted after an item is removed to the list.
|
|
||||||
// Contains a reference to the item and the item's old index.
|
|
||||||
virtual void onItemRemoved(const T &item, int index) = 0;
|
|
||||||
|
|
||||||
// Signal emitted after multiple items are removed from the list at once.
|
|
||||||
// The items parameter is a const reference to a QList of the items that
|
|
||||||
// were added.
|
|
||||||
// The firstIndex parameter is the new index of the first item added.
|
|
||||||
virtual void onItemsRemoved(const QList<T> &items, int firstIndex) = 0;
|
|
||||||
|
|
||||||
// Signal emitted after an item is moved to another index.
|
|
||||||
// Contains the item, the old index, and the new index.
|
|
||||||
virtual void onItemMoved(const T &item, int oldIndex, int newIndex) = 0;
|
|
||||||
|
|
||||||
// Signal emitted after an operation that changes the whole list occurs.
|
|
||||||
// This signal should be treated as if all data in the entire list was cleared
|
|
||||||
// and new data added in its place.
|
|
||||||
virtual void onInvalidated() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Defines the signals for a SigList
|
|
||||||
#define DEFINE_SIGLIST_SIGNALS(TYPE) \
|
|
||||||
Q_SIGNAL void itemAdded(TYPE const &item, int index);\
|
|
||||||
Q_SIGNAL void itemsAdded(const QList<TYPE> &items, int firstIndex);\
|
|
||||||
Q_SIGNAL void itemRemoved(TYPE const &item, int index);\
|
|
||||||
Q_SIGNAL void itemsRemoved(const QList<TYPE> &items, int firstIndex);\
|
|
||||||
Q_SIGNAL void itemMoved(TYPE const &item, int oldIndex, int newIndex);\
|
|
||||||
Q_SIGNAL void invalidated();
|
|
||||||
|
|
||||||
// Overrides the onItem* functions and causes them to emit their corresponding
|
|
||||||
// signals.
|
|
||||||
#define SETUP_SIGLIST_SIGNALS(TYPE) \
|
|
||||||
virtual void onItemAdded(TYPE const &item, int index)\
|
|
||||||
{ emit itemAdded(item, index); }\
|
|
||||||
virtual void onItemsAdded(const QList<TYPE> &items, int firstIndex)\
|
|
||||||
{ emit itemsAdded(items, firstIndex); }\
|
|
||||||
virtual void onItemRemoved(TYPE const &item, int index)\
|
|
||||||
{ emit itemRemoved(item, index); }\
|
|
||||||
virtual void onItemsRemoved(const QList<TYPE> &items, int firstIndex)\
|
|
||||||
{ emit itemsRemoved(items, firstIndex); }\
|
|
||||||
virtual void onItemMoved(TYPE const &item, int oldIndex, int newIndex)\
|
|
||||||
{ emit itemMoved(item, oldIndex, newIndex); }\
|
|
||||||
virtual void onInvalidated() { emit invalidated(); }
|
|
||||||
|
|
||||||
#endif // SIGLIST_H
|
|
@ -1,156 +0,0 @@
|
|||||||
/* Copyright 2013 MultiMC Contributors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "siglist.h"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::append(const T &value)
|
|
||||||
{
|
|
||||||
QList<T>::append(value);
|
|
||||||
onItemAdded(value, QList<T>::length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::prepend(const T &value)
|
|
||||||
{
|
|
||||||
QList<T>::prepend(value);
|
|
||||||
onItemAdded(value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::append(const QList<T> &other)
|
|
||||||
{
|
|
||||||
int index = QList<T>::length();
|
|
||||||
QList<T>::append(other);
|
|
||||||
onItemsAdded(other, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::clear()
|
|
||||||
{
|
|
||||||
QList<T>::clear();
|
|
||||||
onInvalidated();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::erase(typename QList<T>::iterator pos)
|
|
||||||
{
|
|
||||||
T value = *pos;
|
|
||||||
int index = QList<T>::indexOf(*pos);
|
|
||||||
QList<T>::erase(pos);
|
|
||||||
onItemRemoved(value, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::erase(typename QList<T>::iterator first, typename QList<T>::iterator last)
|
|
||||||
{
|
|
||||||
QList<T> removedValues;
|
|
||||||
int firstIndex = QList<T>::indexOf(*first);
|
|
||||||
|
|
||||||
for (auto iter = first; iter < last; iter++)
|
|
||||||
{
|
|
||||||
removedValues << *iter;
|
|
||||||
QList<T>::erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
onItemsRemoved(removedValues, firstIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::insert(int i, const T &t)
|
|
||||||
{
|
|
||||||
QList<T>::insert(i, t);
|
|
||||||
onItemAdded(t, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::insert(typename QList<T>::iterator before, const T &t)
|
|
||||||
{
|
|
||||||
QList<T>::insert(before, t);
|
|
||||||
onItemAdded(t, QList<T>::indexOf(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::move(int from, int to)
|
|
||||||
{
|
|
||||||
const T &item = QList<T>::at(from);
|
|
||||||
QList<T>::move(from, to);
|
|
||||||
onItemMoved(item, from, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
int SigList<T>::removeAll(const T &t)
|
|
||||||
{
|
|
||||||
int retVal = QList<T>::removeAll(t);
|
|
||||||
onInvalidated();
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool SigList<T>::removeOne(const T &t)
|
|
||||||
{
|
|
||||||
int index = QList<T>::indexOf(t);
|
|
||||||
if (QList<T>::removeOne(t))
|
|
||||||
{
|
|
||||||
onItemRemoved(t, index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::swap(QList<T> &other)
|
|
||||||
{
|
|
||||||
QList<T>::swap(other);
|
|
||||||
onInvalidated();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SigList<T>::swap(int i, int j)
|
|
||||||
{
|
|
||||||
const T &item1 = QList<T>::at(i);
|
|
||||||
const T &item2 = QList<T>::at(j);
|
|
||||||
QList<T>::swap(i, j);
|
|
||||||
onItemMoved(item1, i, j);
|
|
||||||
onItemMoved(item2, j, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T SigList<T>::takeAt(int i)
|
|
||||||
{
|
|
||||||
T val = QList<T>::takeAt(i);
|
|
||||||
onItemRemoved(val, i);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T SigList<T>::takeFirst()
|
|
||||||
{
|
|
||||||
return takeAt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T SigList<T>::takeLast()
|
|
||||||
{
|
|
||||||
return takeAt(QList<T>::length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
QList<T> &SigList<T>::operator =(const QList<T> &other)
|
|
||||||
{
|
|
||||||
QList<T>::operator =(other);
|
|
||||||
onInvalidated();
|
|
||||||
return *this;
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef USERUTILS_H
|
#pragma once
|
||||||
#define USERUTILS_H
|
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ LIBUTIL_EXPORT QString getDesktopDir();
|
|||||||
// Create a shortcut at *location*, pointing to *dest* called with the arguments *args*
|
// Create a shortcut at *location*, pointing to *dest* called with the arguments *args*
|
||||||
// call it *name* and assign it the icon *icon*
|
// call it *name* and assign it the icon *icon*
|
||||||
// return true if operation succeeded
|
// return true if operation succeeded
|
||||||
LIBUTIL_EXPORT bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation);
|
LIBUTIL_EXPORT bool createShortCut(QString location, QString dest, QStringList args,
|
||||||
|
QString name, QString iconLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USERUTILS_H
|
|
||||||
|
@ -21,8 +21,10 @@
|
|||||||
* @file libutil/src/cmdutils.cpp
|
* @file libutil/src/cmdutils.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Util {
|
namespace Util
|
||||||
namespace Commandline {
|
{
|
||||||
|
namespace Commandline
|
||||||
|
{
|
||||||
|
|
||||||
// commandline splitter
|
// commandline splitter
|
||||||
QStringList splitArgs(QString args)
|
QStringList splitArgs(QString args)
|
||||||
@ -31,10 +33,10 @@ QStringList splitArgs(QString args)
|
|||||||
QString current;
|
QString current;
|
||||||
bool escape = false;
|
bool escape = false;
|
||||||
QChar inquotes;
|
QChar inquotes;
|
||||||
for (int i=0; i<args.length(); i++)
|
for (int i = 0; i < args.length(); i++)
|
||||||
{
|
{
|
||||||
QChar cchar = args.at(i);
|
QChar cchar = args.at(i);
|
||||||
|
|
||||||
// \ escaped
|
// \ escaped
|
||||||
if (escape)
|
if (escape)
|
||||||
{
|
{
|
||||||
@ -73,7 +75,6 @@ QStringList splitArgs(QString args)
|
|||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Parser::Parser(FlagStyle::Enum flagStyle, ArgumentStyle::Enum argStyle)
|
Parser::Parser(FlagStyle::Enum flagStyle, ArgumentStyle::Enum argStyle)
|
||||||
{
|
{
|
||||||
m_flagStyle = flagStyle;
|
m_flagStyle = flagStyle;
|
||||||
@ -104,13 +105,13 @@ void Parser::addSwitch(QString name, bool def)
|
|||||||
{
|
{
|
||||||
if (m_params.contains(name))
|
if (m_params.contains(name))
|
||||||
throw "Name not unique";
|
throw "Name not unique";
|
||||||
|
|
||||||
OptionDef *param = new OptionDef;
|
OptionDef *param = new OptionDef;
|
||||||
param->type = otSwitch;
|
param->type = otSwitch;
|
||||||
param->name = name;
|
param->name = name;
|
||||||
param->metavar = QString("<%1>").arg(name);
|
param->metavar = QString("<%1>").arg(name);
|
||||||
param->def = def;
|
param->def = def;
|
||||||
|
|
||||||
m_options[name] = param;
|
m_options[name] = param;
|
||||||
m_params[name] = (CommonDef *)param;
|
m_params[name] = (CommonDef *)param;
|
||||||
m_optionList.append(param);
|
m_optionList.append(param);
|
||||||
@ -120,13 +121,13 @@ void Parser::addOption(QString name, QVariant def)
|
|||||||
{
|
{
|
||||||
if (m_params.contains(name))
|
if (m_params.contains(name))
|
||||||
throw "Name not unique";
|
throw "Name not unique";
|
||||||
|
|
||||||
OptionDef *param = new OptionDef;
|
OptionDef *param = new OptionDef;
|
||||||
param->type = otOption;
|
param->type = otOption;
|
||||||
param->name = name;
|
param->name = name;
|
||||||
param->metavar = QString("<%1>").arg(name);
|
param->metavar = QString("<%1>").arg(name);
|
||||||
param->def = def;
|
param->def = def;
|
||||||
|
|
||||||
m_options[name] = param;
|
m_options[name] = param;
|
||||||
m_params[name] = (CommonDef *)param;
|
m_params[name] = (CommonDef *)param;
|
||||||
m_optionList.append(param);
|
m_optionList.append(param);
|
||||||
@ -136,13 +137,13 @@ void Parser::addArgument(QString name, bool required, QVariant def)
|
|||||||
{
|
{
|
||||||
if (m_params.contains(name))
|
if (m_params.contains(name))
|
||||||
throw "Name not unique";
|
throw "Name not unique";
|
||||||
|
|
||||||
PositionalDef *param = new PositionalDef;
|
PositionalDef *param = new PositionalDef;
|
||||||
param->name = name;
|
param->name = name;
|
||||||
param->def = def;
|
param->def = def;
|
||||||
param->required = required;
|
param->required = required;
|
||||||
param->metavar = name;
|
param->metavar = name;
|
||||||
|
|
||||||
m_positionals.append(param);
|
m_positionals.append(param);
|
||||||
m_params[name] = (CommonDef *)param;
|
m_params[name] = (CommonDef *)param;
|
||||||
}
|
}
|
||||||
@ -151,7 +152,7 @@ void Parser::addDocumentation(QString name, QString doc, QString metavar)
|
|||||||
{
|
{
|
||||||
if (!m_params.contains(name))
|
if (!m_params.contains(name))
|
||||||
throw "Name does not exist";
|
throw "Name does not exist";
|
||||||
|
|
||||||
CommonDef *param = m_params[name];
|
CommonDef *param = m_params[name];
|
||||||
param->doc = doc;
|
param->doc = doc;
|
||||||
if (!metavar.isNull())
|
if (!metavar.isNull())
|
||||||
@ -164,7 +165,7 @@ void Parser::addShortOpt(QString name, QChar flag)
|
|||||||
throw "Name does not exist";
|
throw "Name does not exist";
|
||||||
if (!m_options.contains(name))
|
if (!m_options.contains(name))
|
||||||
throw "Name is not an Option or Swtich";
|
throw "Name is not an Option or Swtich";
|
||||||
|
|
||||||
OptionDef *param = m_options[name];
|
OptionDef *param = m_options[name];
|
||||||
m_flags[flag] = param;
|
m_flags[flag] = param;
|
||||||
param->flag = flag;
|
param->flag = flag;
|
||||||
@ -175,14 +176,14 @@ QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
|
|||||||
{
|
{
|
||||||
QStringList help;
|
QStringList help;
|
||||||
help << compileUsage(progName, useFlags) << "\r\n";
|
help << compileUsage(progName, useFlags) << "\r\n";
|
||||||
|
|
||||||
// positionals
|
// positionals
|
||||||
if (!m_positionals.isEmpty())
|
if (!m_positionals.isEmpty())
|
||||||
{
|
{
|
||||||
help << "\r\n";
|
help << "\r\n";
|
||||||
help << "Positional arguments:\r\n";
|
help << "Positional arguments:\r\n";
|
||||||
QListIterator<PositionalDef *> it2(m_positionals);
|
QListIterator<PositionalDef *> it2(m_positionals);
|
||||||
while(it2.hasNext())
|
while (it2.hasNext())
|
||||||
{
|
{
|
||||||
PositionalDef *param = it2.next();
|
PositionalDef *param = it2.next();
|
||||||
help << " " << param->metavar;
|
help << " " << param->metavar;
|
||||||
@ -190,17 +191,17 @@ QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
|
|||||||
help << param->doc << "\r\n";
|
help << param->doc << "\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
if (!m_optionList.isEmpty())
|
if (!m_optionList.isEmpty())
|
||||||
{
|
{
|
||||||
help << "\r\n";
|
help << "\r\n";
|
||||||
QString optPrefix, flagPrefix;
|
QString optPrefix, flagPrefix;
|
||||||
getPrefix(optPrefix, flagPrefix);
|
getPrefix(optPrefix, flagPrefix);
|
||||||
|
|
||||||
help << "Options & Switches:\r\n";
|
help << "Options & Switches:\r\n";
|
||||||
QListIterator<OptionDef *> it(m_optionList);
|
QListIterator<OptionDef *> it(m_optionList);
|
||||||
while(it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
OptionDef *option = it.next();
|
OptionDef *option = it.next();
|
||||||
help << " ";
|
help << " ";
|
||||||
@ -213,7 +214,8 @@ QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
|
|||||||
help << optPrefix << option->name;
|
help << optPrefix << option->name;
|
||||||
if (option->type == otOption)
|
if (option->type == otOption)
|
||||||
{
|
{
|
||||||
QString arg = QString("%1%2").arg(((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
|
QString arg = QString("%1%2").arg(
|
||||||
|
((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
|
||||||
nameLength += arg.length();
|
nameLength += arg.length();
|
||||||
help << arg;
|
help << arg;
|
||||||
}
|
}
|
||||||
@ -221,7 +223,7 @@ QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
|
|||||||
help << option->doc << "\r\n";
|
help << option->doc << "\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return help.join("");
|
return help.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,13 +231,13 @@ QString Parser::compileUsage(QString progName, bool useFlags)
|
|||||||
{
|
{
|
||||||
QStringList usage;
|
QStringList usage;
|
||||||
usage << "Usage: " << progName;
|
usage << "Usage: " << progName;
|
||||||
|
|
||||||
QString optPrefix, flagPrefix;
|
QString optPrefix, flagPrefix;
|
||||||
getPrefix(optPrefix, flagPrefix);
|
getPrefix(optPrefix, flagPrefix);
|
||||||
|
|
||||||
// options
|
// options
|
||||||
QListIterator<OptionDef *> it(m_optionList);
|
QListIterator<OptionDef *> it(m_optionList);
|
||||||
while(it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
OptionDef *option = it.next();
|
OptionDef *option = it.next();
|
||||||
usage << " [";
|
usage << " [";
|
||||||
@ -244,20 +246,20 @@ QString Parser::compileUsage(QString progName, bool useFlags)
|
|||||||
else
|
else
|
||||||
usage << optPrefix << option->name;
|
usage << optPrefix << option->name;
|
||||||
if (option->type == otOption)
|
if (option->type == otOption)
|
||||||
usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar;
|
usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar;
|
||||||
usage << "]";
|
usage << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
// arguments
|
// arguments
|
||||||
QListIterator<PositionalDef *> it2(m_positionals);
|
QListIterator<PositionalDef *> it2(m_positionals);
|
||||||
while(it2.hasNext())
|
while (it2.hasNext())
|
||||||
{
|
{
|
||||||
PositionalDef *param = it2.next();
|
PositionalDef *param = it2.next();
|
||||||
usage << " " << (param->required ? "<" : "[");
|
usage << " " << (param->required ? "<" : "[");
|
||||||
usage << param->metavar;
|
usage << param->metavar;
|
||||||
usage << (param->required ? ">" : "]");
|
usage << (param->required ? ">" : "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
return usage.join("");
|
return usage.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,59 +267,63 @@ QString Parser::compileUsage(QString progName, bool useFlags)
|
|||||||
QHash<QString, QVariant> Parser::parse(QStringList argv)
|
QHash<QString, QVariant> Parser::parse(QStringList argv)
|
||||||
{
|
{
|
||||||
QHash<QString, QVariant> map;
|
QHash<QString, QVariant> map;
|
||||||
|
|
||||||
QStringListIterator it(argv);
|
QStringListIterator it(argv);
|
||||||
QString programName = it.next();
|
QString programName = it.next();
|
||||||
|
|
||||||
QString optionPrefix;
|
QString optionPrefix;
|
||||||
QString flagPrefix;
|
QString flagPrefix;
|
||||||
QListIterator<PositionalDef *> positionals(m_positionals);
|
QListIterator<PositionalDef *> positionals(m_positionals);
|
||||||
QStringList expecting;
|
QStringList expecting;
|
||||||
|
|
||||||
getPrefix(optionPrefix, flagPrefix);
|
getPrefix(optionPrefix, flagPrefix);
|
||||||
|
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
QString arg = it.next();
|
QString arg = it.next();
|
||||||
|
|
||||||
if (!expecting.isEmpty())
|
if (!expecting.isEmpty())
|
||||||
// we were expecting an argument
|
// we were expecting an argument
|
||||||
{
|
{
|
||||||
QString name = expecting.first();
|
QString name = expecting.first();
|
||||||
|
|
||||||
if (map.contains(name))
|
if (map.contains(name))
|
||||||
throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
|
throw ParsingError(
|
||||||
|
QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
|
||||||
|
|
||||||
map[name] = QVariant(arg);
|
map[name] = QVariant(arg);
|
||||||
|
|
||||||
expecting.removeFirst();
|
expecting.removeFirst();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg.startsWith(optionPrefix))
|
if (arg.startsWith(optionPrefix))
|
||||||
// we have an option
|
// we have an option
|
||||||
{
|
{
|
||||||
//qDebug("Found option %s", qPrintable(arg));
|
// qDebug("Found option %s", qPrintable(arg));
|
||||||
|
|
||||||
QString name = arg.mid(optionPrefix.length());
|
QString name = arg.mid(optionPrefix.length());
|
||||||
QString equals;
|
QString equals;
|
||||||
|
|
||||||
if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && name.contains("="))
|
if ((m_argStyle == ArgumentStyle::Equals ||
|
||||||
|
m_argStyle == ArgumentStyle::SpaceAndEquals) &&
|
||||||
|
name.contains("="))
|
||||||
{
|
{
|
||||||
int i = name.indexOf("=");
|
int i = name.indexOf("=");
|
||||||
equals = name.mid(i+1);
|
equals = name.mid(i + 1);
|
||||||
name = name.left(i);
|
name = name.left(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_options.contains(name))
|
if (m_options.contains(name))
|
||||||
{
|
{
|
||||||
if (map.contains(name))
|
if (map.contains(name))
|
||||||
throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
|
throw ParsingError(QString("Option %2%1 was given multiple times")
|
||||||
|
.arg(name, optionPrefix));
|
||||||
|
|
||||||
OptionDef *option = m_options[name];
|
OptionDef *option = m_options[name];
|
||||||
if (option->type == otSwitch)
|
if (option->type == otSwitch)
|
||||||
map[name] = true;
|
map[name] = true;
|
||||||
else //if (option->type == otOption)
|
else // if (option->type == otOption)
|
||||||
{
|
{
|
||||||
if (m_argStyle == ArgumentStyle::Space)
|
if (m_argStyle == ArgumentStyle::Space)
|
||||||
expecting.append(name);
|
expecting.append(name);
|
||||||
@ -326,85 +332,94 @@ QHash<QString, QVariant> Parser::parse(QStringList argv)
|
|||||||
else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
|
else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
|
||||||
expecting.append(name);
|
expecting.append(name);
|
||||||
else
|
else
|
||||||
throw ParsingError(QString("Option %2%1 reqires an argument.").arg(name, optionPrefix));
|
throw ParsingError(QString("Option %2%1 reqires an argument.")
|
||||||
|
.arg(name, optionPrefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
|
throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg.startsWith(flagPrefix))
|
if (arg.startsWith(flagPrefix))
|
||||||
// we have (a) flag(s)
|
// we have (a) flag(s)
|
||||||
{
|
{
|
||||||
//qDebug("Found flags %s", qPrintable(arg));
|
// qDebug("Found flags %s", qPrintable(arg));
|
||||||
|
|
||||||
QString flags = arg.mid(flagPrefix.length());
|
QString flags = arg.mid(flagPrefix.length());
|
||||||
QString equals;
|
QString equals;
|
||||||
|
|
||||||
if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && flags.contains("="))
|
if ((m_argStyle == ArgumentStyle::Equals ||
|
||||||
|
m_argStyle == ArgumentStyle::SpaceAndEquals) &&
|
||||||
|
flags.contains("="))
|
||||||
{
|
{
|
||||||
int i = flags.indexOf("=");
|
int i = flags.indexOf("=");
|
||||||
equals = flags.mid(i+1);
|
equals = flags.mid(i + 1);
|
||||||
flags = flags.left(i);
|
flags = flags.left(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < flags.length(); i++)
|
for (int i = 0; i < flags.length(); i++)
|
||||||
{
|
{
|
||||||
QChar flag = flags.at(i);
|
QChar flag = flags.at(i);
|
||||||
|
|
||||||
if (!m_flags.contains(flag))
|
if (!m_flags.contains(flag))
|
||||||
throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
|
throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
|
||||||
|
|
||||||
OptionDef *option = m_flags[flag];
|
OptionDef *option = m_flags[flag];
|
||||||
|
|
||||||
if (map.contains(option->name))
|
if (map.contains(option->name))
|
||||||
throw ParsingError(QString("Option %2%1 was given multiple times").arg(option->name, optionPrefix));
|
throw ParsingError(QString("Option %2%1 was given multiple times")
|
||||||
|
.arg(option->name, optionPrefix));
|
||||||
|
|
||||||
if (option->type == otSwitch)
|
if (option->type == otSwitch)
|
||||||
map[option->name] = true;
|
map[option->name] = true;
|
||||||
else //if (option->type == otOption)
|
else // if (option->type == otOption)
|
||||||
{
|
{
|
||||||
if (m_argStyle == ArgumentStyle::Space)
|
if (m_argStyle == ArgumentStyle::Space)
|
||||||
expecting.append(option->name);
|
expecting.append(option->name);
|
||||||
else if (!equals.isNull())
|
else if (!equals.isNull())
|
||||||
if (i == flags.length()-1)
|
if (i == flags.length() - 1)
|
||||||
map[option->name] = equals;
|
map[option->name] = equals;
|
||||||
else
|
else
|
||||||
throw ParsingError(QString("Flag %4%2 of Argument-requiring Option %1 not last flag in %4%3").arg(option->name, flag, flags, flagPrefix));
|
throw ParsingError(QString("Flag %4%2 of Argument-requiring Option "
|
||||||
|
"%1 not last flag in %4%3")
|
||||||
|
.arg(option->name, flag, flags, flagPrefix));
|
||||||
else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
|
else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
|
||||||
expecting.append(option->name);
|
expecting.append(option->name);
|
||||||
else
|
else
|
||||||
throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)").arg(option->name, flag, flagPrefix));
|
throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)")
|
||||||
|
.arg(option->name, flag, flagPrefix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// must be a positional argument
|
// must be a positional argument
|
||||||
if (!positionals.hasNext())
|
if (!positionals.hasNext())
|
||||||
throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
|
throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
|
||||||
|
|
||||||
PositionalDef *param = positionals.next();
|
PositionalDef *param = positionals.next();
|
||||||
|
|
||||||
map[param->name] = arg;
|
map[param->name] = arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we're missing something
|
// check if we're missing something
|
||||||
if (!expecting.isEmpty())
|
if (!expecting.isEmpty())
|
||||||
throw ParsingError(QString("Was still expecting arguments for %2%1").arg(expecting.join(QString(", ")+optionPrefix), optionPrefix));
|
throw ParsingError(QString("Was still expecting arguments for %2%1").arg(
|
||||||
|
expecting.join(QString(", ") + optionPrefix), optionPrefix));
|
||||||
|
|
||||||
while (positionals.hasNext())
|
while (positionals.hasNext())
|
||||||
{
|
{
|
||||||
PositionalDef *param = positionals.next();
|
PositionalDef *param = positionals.next();
|
||||||
if (param->required)
|
if (param->required)
|
||||||
throw ParsingError(QString("Missing required positional argument '%1'").arg(param->name));
|
throw ParsingError(
|
||||||
|
QString("Missing required positional argument '%1'").arg(param->name));
|
||||||
else
|
else
|
||||||
map[param->name] = param->def;
|
map[param->name] = param->def;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill out gaps
|
// fill out gaps
|
||||||
QListIterator<OptionDef *> iter(m_optionList);
|
QListIterator<OptionDef *> iter(m_optionList);
|
||||||
while (iter.hasNext())
|
while (iter.hasNext())
|
||||||
@ -413,27 +428,27 @@ QHash<QString, QVariant> Parser::parse(QStringList argv)
|
|||||||
if (!map.contains(option->name))
|
if (!map.contains(option->name))
|
||||||
map[option->name] = option->def;
|
map[option->name] = option->def;
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
//clear defs
|
// clear defs
|
||||||
void Parser::clear()
|
void Parser::clear()
|
||||||
{
|
{
|
||||||
m_flags.clear();
|
m_flags.clear();
|
||||||
m_params.clear();
|
m_params.clear();
|
||||||
m_options.clear();
|
m_options.clear();
|
||||||
|
|
||||||
QMutableListIterator<OptionDef *> it(m_optionList);
|
QMutableListIterator<OptionDef *> it(m_optionList);
|
||||||
while(it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
OptionDef *option = it.next();
|
OptionDef *option = it.next();
|
||||||
it.remove();
|
it.remove();
|
||||||
delete option;
|
delete option;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutableListIterator<PositionalDef *> it2(m_positionals);
|
QMutableListIterator<PositionalDef *> it2(m_positionals);
|
||||||
while(it2.hasNext())
|
while (it2.hasNext())
|
||||||
{
|
{
|
||||||
PositionalDef *arg = it2.next();
|
PositionalDef *arg = it2.next();
|
||||||
it2.remove();
|
it2.remove();
|
||||||
@ -441,31 +456,30 @@ void Parser::clear()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Destructor
|
// Destructor
|
||||||
Parser::~Parser()
|
Parser::~Parser()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//getPrefix
|
// getPrefix
|
||||||
void Parser::getPrefix(QString &opt, QString &flag)
|
void Parser::getPrefix(QString &opt, QString &flag)
|
||||||
{
|
{
|
||||||
if (m_flagStyle == FlagStyle::Windows)
|
if (m_flagStyle == FlagStyle::Windows)
|
||||||
opt = flag = "/";
|
opt = flag = "/";
|
||||||
else if (m_flagStyle == FlagStyle::Unix)
|
else if (m_flagStyle == FlagStyle::Unix)
|
||||||
opt = flag = "-";
|
opt = flag = "-";
|
||||||
//else if (m_flagStyle == FlagStyle::GNU)
|
// else if (m_flagStyle == FlagStyle::GNU)
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
opt = "--";
|
opt = "--";
|
||||||
flag = "-";
|
flag = "-";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParsingError
|
// ParsingError
|
||||||
ParsingError::ParsingError(const QString &what)
|
ParsingError::ParsingError(const QString &what) : std::runtime_error(what.toStdString())
|
||||||
:std::runtime_error(what.toStdString())
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -41,7 +41,7 @@ QString AbsolutePath(QString path)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize path
|
* Normalize path
|
||||||
*
|
*
|
||||||
* Any paths inside the current directory will be normalized to relative paths (to current)
|
* Any paths inside the current directory will be normalized to relative paths (to current)
|
||||||
* Other paths will be made absolute
|
* Other paths will be made absolute
|
||||||
*/
|
*/
|
||||||
@ -85,7 +85,7 @@ QString DirNameFromString(QString string, QString inDir)
|
|||||||
{
|
{
|
||||||
num++;
|
num++;
|
||||||
dirName = RemoveInvalidFilenameChars(dirName, '-') + QString::number(num);
|
dirName = RemoveInvalidFilenameChars(dirName, '-') + QString::number(num);
|
||||||
|
|
||||||
// If it's over 9000
|
// If it's over 9000
|
||||||
if (num > 9000)
|
if (num > 9000)
|
||||||
return "";
|
return "";
|
||||||
@ -95,59 +95,56 @@ QString DirNameFromString(QString string, QString inDir)
|
|||||||
|
|
||||||
bool ensureFilePathExists(QString filenamepath)
|
bool ensureFilePathExists(QString filenamepath)
|
||||||
{
|
{
|
||||||
QFileInfo a ( filenamepath );
|
QFileInfo a(filenamepath);
|
||||||
QDir dir;
|
QDir dir;
|
||||||
QString ensuredPath = a.path();
|
QString ensuredPath = a.path();
|
||||||
bool success = dir.mkpath ( ensuredPath );
|
bool success = dir.mkpath(ensuredPath);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ensureFolderPathExists(QString foldernamepath)
|
bool ensureFolderPathExists(QString foldernamepath)
|
||||||
{
|
{
|
||||||
QFileInfo a ( foldernamepath );
|
QFileInfo a(foldernamepath);
|
||||||
QDir dir;
|
QDir dir;
|
||||||
QString ensuredPath = a.filePath();
|
QString ensuredPath = a.filePath();
|
||||||
bool success = dir.mkpath ( ensuredPath );
|
bool success = dir.mkpath(ensuredPath);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool copyPath(QString src, QString dst)
|
bool copyPath(QString src, QString dst)
|
||||||
{
|
{
|
||||||
QDir dir(src);
|
QDir dir(src);
|
||||||
if (!dir.exists())
|
if (!dir.exists())
|
||||||
return false;
|
return false;
|
||||||
if(!ensureFolderPathExists(dst))
|
if (!ensureFolderPathExists(dst))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
|
foreach(QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
|
||||||
{
|
{
|
||||||
QString inner_src = src + QDir::separator() + d;
|
QString inner_src = src + QDir::separator() + d;
|
||||||
QString inner_dst = dst + QDir::separator() + d;
|
QString inner_dst = dst + QDir::separator() + d;
|
||||||
copyPath(inner_src, inner_dst);
|
copyPath(inner_src, inner_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (QString f, dir.entryList(QDir::Files))
|
foreach(QString f, dir.entryList(QDir::Files))
|
||||||
{
|
{
|
||||||
QFile::copy(src + QDir::separator() + f, dst + QDir::separator() + f);
|
QFile::copy(src + QDir::separator() + f, dst + QDir::separator() + f);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void openDirInDefaultProgram ( QString path, bool ensureExists )
|
void openDirInDefaultProgram(QString path, bool ensureExists)
|
||||||
{
|
{
|
||||||
QDir parentPath;
|
QDir parentPath;
|
||||||
QDir dir( path );
|
QDir dir(path);
|
||||||
if(!dir.exists())
|
if (!dir.exists())
|
||||||
{
|
{
|
||||||
parentPath.mkpath(dir.absolutePath());
|
parentPath.mkpath(dir.absolutePath());
|
||||||
}
|
}
|
||||||
QDesktopServices::openUrl ( "file:///" + dir.absolutePath() );
|
QDesktopServices::openUrl("file:///" + dir.absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void openFileInDefaultProgram ( QString filename )
|
void openFileInDefaultProgram(QString filename)
|
||||||
{
|
{
|
||||||
QDesktopServices::openUrl ( "file:///" + QFileInfo ( filename ).absolutePath() );
|
QDesktopServices::openUrl("file:///" + QFileInfo(filename).absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,37 +23,37 @@ bool called_coinit = false;
|
|||||||
HRESULT CreateLink(LPCSTR linkPath, LPCSTR targetPath, LPCSTR args)
|
HRESULT CreateLink(LPCSTR linkPath, LPCSTR targetPath, LPCSTR args)
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if (!called_coinit)
|
if (!called_coinit)
|
||||||
{
|
{
|
||||||
hres = CoInitialize(NULL);
|
hres = CoInitialize(NULL);
|
||||||
called_coinit = true;
|
called_coinit = true;
|
||||||
|
|
||||||
if (!SUCCEEDED(hres))
|
if (!SUCCEEDED(hres))
|
||||||
{
|
{
|
||||||
qWarning("Failed to initialize COM. Error 0x%08X", hres);
|
qWarning("Failed to initialize COM. Error 0x%08X", hres);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IShellLink *link;
|
||||||
IShellLink* link;
|
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,
|
||||||
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&link);
|
(LPVOID *)&link);
|
||||||
|
|
||||||
if (SUCCEEDED(hres))
|
if (SUCCEEDED(hres))
|
||||||
{
|
{
|
||||||
IPersistFile* persistFile;
|
IPersistFile *persistFile;
|
||||||
|
|
||||||
link->SetPath(targetPath);
|
link->SetPath(targetPath);
|
||||||
link->SetArguments(args);
|
link->SetArguments(args);
|
||||||
|
|
||||||
hres = link->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile);
|
hres = link->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
|
||||||
if (SUCCEEDED(hres))
|
if (SUCCEEDED(hres))
|
||||||
{
|
{
|
||||||
WCHAR wstr[MAX_PATH];
|
WCHAR wstr[MAX_PATH];
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
|
MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
|
||||||
|
|
||||||
hres = persistFile->Save(wstr, TRUE);
|
hres = persistFile->Save(wstr, TRUE);
|
||||||
persistFile->Release();
|
persistFile->Release();
|
||||||
}
|
}
|
||||||
@ -70,51 +70,55 @@ QString Util::getDesktopDir()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cross-platform Shortcut creation
|
// Cross-platform Shortcut creation
|
||||||
bool Util::createShortCut(QString location, QString dest, QStringList args, QString name, QString icon)
|
bool Util::createShortCut(QString location, QString dest, QStringList args, QString name,
|
||||||
|
QString icon)
|
||||||
{
|
{
|
||||||
#if LINUX
|
#if LINUX
|
||||||
location = PathCombine(location, name + ".desktop");
|
location = PathCombine(location, name + ".desktop");
|
||||||
qDebug("location: %s", qPrintable(location));
|
qDebug("location: %s", qPrintable(location));
|
||||||
|
|
||||||
QFile f(location);
|
QFile f(location);
|
||||||
f.open(QIODevice::WriteOnly | QIODevice::Text);
|
f.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
QTextStream stream(&f);
|
QTextStream stream(&f);
|
||||||
|
|
||||||
QString argstring;
|
QString argstring;
|
||||||
if (!args.empty())
|
if (!args.empty())
|
||||||
argstring = " '" + args.join("' '") + "'";
|
argstring = " '" + args.join("' '") + "'";
|
||||||
|
|
||||||
stream << "[Desktop Entry]" << "\n";
|
stream << "[Desktop Entry]"
|
||||||
stream << "Type=Application" << "\n";
|
<< "\n";
|
||||||
|
stream << "Type=Application"
|
||||||
|
<< "\n";
|
||||||
stream << "TryExec=" << dest.toLocal8Bit() << "\n";
|
stream << "TryExec=" << dest.toLocal8Bit() << "\n";
|
||||||
stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
|
stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
|
||||||
stream << "Name=" << name.toLocal8Bit() << "\n";
|
stream << "Name=" << name.toLocal8Bit() << "\n";
|
||||||
stream << "Icon=" << icon.toLocal8Bit() << "\n";
|
stream << "Icon=" << icon.toLocal8Bit() << "\n";
|
||||||
|
|
||||||
stream.flush();
|
stream.flush();
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther);
|
f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup |
|
||||||
|
QFileDevice::ExeOther);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#elif WINDOWS
|
#elif WINDOWS
|
||||||
// TODO: Fix
|
// TODO: Fix
|
||||||
// QFile file(PathCombine(location, name + ".lnk"));
|
// QFile file(PathCombine(location, name + ".lnk"));
|
||||||
// WCHAR *file_w;
|
// WCHAR *file_w;
|
||||||
// WCHAR *dest_w;
|
// WCHAR *dest_w;
|
||||||
// WCHAR *args_w;
|
// WCHAR *args_w;
|
||||||
// file.fileName().toWCharArray(file_w);
|
// file.fileName().toWCharArray(file_w);
|
||||||
// dest.toWCharArray(dest_w);
|
// dest.toWCharArray(dest_w);
|
||||||
|
|
||||||
// QString argStr;
|
// QString argStr;
|
||||||
// for (int i = 0; i < args.count(); i++)
|
// for (int i = 0; i < args.count(); i++)
|
||||||
// {
|
// {
|
||||||
// argStr.append(args[i]);
|
// argStr.append(args[i]);
|
||||||
// argStr.append(" ");
|
// argStr.append(" ");
|
||||||
// }
|
// }
|
||||||
// argStr.toWCharArray(args_w);
|
// argStr.toWCharArray(args_w);
|
||||||
|
|
||||||
// return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
|
// return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
qWarning("Desktop Shortcuts not supported on your platform!");
|
qWarning("Desktop Shortcuts not supported on your platform!");
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
#define XZ_H
|
#define XZ_H
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
# include <linux/stddef.h>
|
#include <linux/stddef.h>
|
||||||
# include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#else
|
#else
|
||||||
# include <stddef.h>
|
#include <stddef.h>
|
||||||
# include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -37,10 +37,9 @@ extern "C" {
|
|||||||
#define XZ_DEC_SPARC
|
#define XZ_DEC_SPARC
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* In Linux, this is used to make extern functions static when needed. */
|
/* In Linux, this is used to make extern functions static when needed. */
|
||||||
#ifndef XZ_EXTERN
|
#ifndef XZ_EXTERN
|
||||||
# define XZ_EXTERN extern
|
#define XZ_EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,7 +67,8 @@ extern "C" {
|
|||||||
* with support for all operation modes, but the preboot code may
|
* with support for all operation modes, but the preboot code may
|
||||||
* be built with fewer features to minimize code size.
|
* be built with fewer features to minimize code size.
|
||||||
*/
|
*/
|
||||||
enum xz_mode {
|
enum xz_mode
|
||||||
|
{
|
||||||
XZ_SINGLE,
|
XZ_SINGLE,
|
||||||
XZ_PREALLOC,
|
XZ_PREALLOC,
|
||||||
XZ_DYNALLOC
|
XZ_DYNALLOC
|
||||||
@ -124,7 +124,8 @@ enum xz_mode {
|
|||||||
* (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR
|
* (relatively) clear that the compressed input is truncated, XZ_DATA_ERROR
|
||||||
* is used instead of XZ_BUF_ERROR.
|
* is used instead of XZ_BUF_ERROR.
|
||||||
*/
|
*/
|
||||||
enum xz_ret {
|
enum xz_ret
|
||||||
|
{
|
||||||
XZ_OK,
|
XZ_OK,
|
||||||
XZ_STREAM_END,
|
XZ_STREAM_END,
|
||||||
XZ_UNSUPPORTED_CHECK,
|
XZ_UNSUPPORTED_CHECK,
|
||||||
@ -152,7 +153,8 @@ enum xz_ret {
|
|||||||
* Only the contents of the output buffer from out[out_pos] onward, and
|
* Only the contents of the output buffer from out[out_pos] onward, and
|
||||||
* the variables in_pos and out_pos are modified by the XZ code.
|
* the variables in_pos and out_pos are modified by the XZ code.
|
||||||
*/
|
*/
|
||||||
struct xz_buf {
|
struct xz_buf
|
||||||
|
{
|
||||||
const uint8_t *in;
|
const uint8_t *in;
|
||||||
size_t in_pos;
|
size_t in_pos;
|
||||||
size_t in_size;
|
size_t in_size;
|
||||||
@ -259,11 +261,11 @@ XZ_EXTERN void xz_dec_end(struct xz_dec *s);
|
|||||||
* care about the functions below.
|
* care about the functions below.
|
||||||
*/
|
*/
|
||||||
#ifndef XZ_INTERNAL_CRC32
|
#ifndef XZ_INTERNAL_CRC32
|
||||||
# ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
# define XZ_INTERNAL_CRC32 0
|
#define XZ_INTERNAL_CRC32 0
|
||||||
# else
|
#else
|
||||||
# define XZ_INTERNAL_CRC32 1
|
#define XZ_INTERNAL_CRC32 1
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -271,15 +273,15 @@ XZ_EXTERN void xz_dec_end(struct xz_dec *s);
|
|||||||
* implementation is needed too.
|
* implementation is needed too.
|
||||||
*/
|
*/
|
||||||
#ifndef XZ_USE_CRC64
|
#ifndef XZ_USE_CRC64
|
||||||
# undef XZ_INTERNAL_CRC64
|
#undef XZ_INTERNAL_CRC64
|
||||||
# define XZ_INTERNAL_CRC64 0
|
#define XZ_INTERNAL_CRC64 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef XZ_INTERNAL_CRC64
|
#ifndef XZ_INTERNAL_CRC64
|
||||||
# ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
# error Using CRC64 in the kernel has not been implemented.
|
#error Using CRC64 in the kernel has not been implemented.
|
||||||
# else
|
#else
|
||||||
# define XZ_INTERNAL_CRC64 1
|
#define XZ_INTERNAL_CRC64 1
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XZ_INTERNAL_CRC32
|
#if XZ_INTERNAL_CRC32
|
||||||
|
@ -27,11 +27,11 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
typedef unsigned char bool;
|
typedef unsigned char bool;
|
||||||
# define true 1
|
#define true 1
|
||||||
# define false 0
|
#define false 0
|
||||||
# define inline __inline
|
#define inline __inline
|
||||||
#else
|
#else
|
||||||
# include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -48,7 +48,7 @@ typedef unsigned char bool;
|
|||||||
#define memzero(buf, size) memset(buf, 0, size)
|
#define memzero(buf, size) memset(buf, 0, size)
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
# define min(x, y) ((x) < (y) ? (x) : (y))
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
#endif
|
#endif
|
||||||
#define min_t(type, x, y) min(x, y)
|
#define min_t(type, x, y) min(x, y)
|
||||||
|
|
||||||
@ -63,32 +63,27 @@ typedef unsigned char bool;
|
|||||||
* so if you want to change it, you need to #undef it first.
|
* so if you want to change it, you need to #undef it first.
|
||||||
*/
|
*/
|
||||||
#ifndef __always_inline
|
#ifndef __always_inline
|
||||||
# ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define __always_inline \
|
#define __always_inline inline __attribute__((__always_inline__))
|
||||||
inline __attribute__((__always_inline__))
|
#else
|
||||||
# else
|
#define __always_inline inline
|
||||||
# define __always_inline inline
|
#endif
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Inline functions to access unaligned unsigned 32-bit integers */
|
/* Inline functions to access unaligned unsigned 32-bit integers */
|
||||||
#ifndef get_unaligned_le32
|
#ifndef get_unaligned_le32
|
||||||
static inline uint32_t get_unaligned_le32(const uint8_t *buf)
|
static inline uint32_t get_unaligned_le32(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
return (uint32_t)buf[0]
|
return (uint32_t)buf[0] | ((uint32_t)buf[1] << 8) | ((uint32_t)buf[2] << 16) |
|
||||||
| ((uint32_t)buf[1] << 8)
|
((uint32_t)buf[3] << 24);
|
||||||
| ((uint32_t)buf[2] << 16)
|
|
||||||
| ((uint32_t)buf[3] << 24);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef get_unaligned_be32
|
#ifndef get_unaligned_be32
|
||||||
static inline uint32_t get_unaligned_be32(const uint8_t *buf)
|
static inline uint32_t get_unaligned_be32(const uint8_t *buf)
|
||||||
{
|
{
|
||||||
return (uint32_t)(buf[0] << 24)
|
return (uint32_t)(buf[0] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) |
|
||||||
| ((uint32_t)buf[1] << 16)
|
(uint32_t)buf[3];
|
||||||
| ((uint32_t)buf[2] << 8)
|
|
||||||
| (uint32_t)buf[3];
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -118,7 +113,7 @@ static inline void put_unaligned_be32(uint32_t val, uint8_t *buf)
|
|||||||
* could save a few bytes in code size.
|
* could save a few bytes in code size.
|
||||||
*/
|
*/
|
||||||
#ifndef get_le32
|
#ifndef get_le32
|
||||||
# define get_le32 get_unaligned_le32
|
#define get_le32 get_unaligned_le32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* See <linux/decompress/mm.h> for details.
|
* See <linux/decompress/mm.h> for details.
|
||||||
*/
|
*/
|
||||||
#ifndef STATIC_RW_DATA
|
#ifndef STATIC_RW_DATA
|
||||||
# define STATIC_RW_DATA static
|
#define STATIC_RW_DATA static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATIC_RW_DATA uint32_t xz_crc32_table[256];
|
STATIC_RW_DATA uint32_t xz_crc32_table[256];
|
||||||
@ -35,7 +35,8 @@ XZ_EXTERN void xz_crc32_init(void)
|
|||||||
uint32_t j;
|
uint32_t j;
|
||||||
uint32_t r;
|
uint32_t r;
|
||||||
|
|
||||||
for (i = 0; i < 256; ++i) {
|
for (i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
r = i;
|
r = i;
|
||||||
for (j = 0; j < 8; ++j)
|
for (j = 0; j < 8; ++j)
|
||||||
r = (r >> 1) ^ (poly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (poly & ~((r & 1) - 1));
|
||||||
@ -50,7 +51,8 @@ XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
|
|||||||
{
|
{
|
||||||
crc = ~crc;
|
crc = ~crc;
|
||||||
|
|
||||||
while (size != 0) {
|
while (size != 0)
|
||||||
|
{
|
||||||
crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
|
crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
|
||||||
--size;
|
--size;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include "xz_private.h"
|
#include "xz_private.h"
|
||||||
|
|
||||||
#ifndef STATIC_RW_DATA
|
#ifndef STATIC_RW_DATA
|
||||||
# define STATIC_RW_DATA static
|
#define STATIC_RW_DATA static
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATIC_RW_DATA uint64_t xz_crc64_table[256];
|
STATIC_RW_DATA uint64_t xz_crc64_table[256];
|
||||||
@ -26,7 +26,8 @@ XZ_EXTERN void xz_crc64_init(void)
|
|||||||
uint32_t j;
|
uint32_t j;
|
||||||
uint64_t r;
|
uint64_t r;
|
||||||
|
|
||||||
for (i = 0; i < 256; ++i) {
|
for (i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
r = i;
|
r = i;
|
||||||
for (j = 0; j < 8; ++j)
|
for (j = 0; j < 8; ++j)
|
||||||
r = (r >> 1) ^ (poly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (poly & ~((r & 1) - 1));
|
||||||
@ -41,7 +42,8 @@ XZ_EXTERN uint64_t xz_crc64(const uint8_t *buf, size_t size, uint64_t crc)
|
|||||||
{
|
{
|
||||||
crc = ~crc;
|
crc = ~crc;
|
||||||
|
|
||||||
while (size != 0) {
|
while (size != 0)
|
||||||
|
{
|
||||||
crc = xz_crc64_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
|
crc = xz_crc64_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
|
||||||
--size;
|
--size;
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,17 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef XZ_DEC_BCJ
|
#ifdef XZ_DEC_BCJ
|
||||||
|
|
||||||
struct xz_dec_bcj {
|
struct xz_dec_bcj
|
||||||
|
{
|
||||||
/* Type of the BCJ filter being used */
|
/* Type of the BCJ filter being used */
|
||||||
enum {
|
enum
|
||||||
BCJ_X86 = 4, /* x86 or x86-64 */
|
{
|
||||||
BCJ_POWERPC = 5, /* Big endian only */
|
BCJ_X86 = 4, /* x86 or x86-64 */
|
||||||
BCJ_IA64 = 6, /* Big or little endian */
|
BCJ_POWERPC = 5, /* Big endian only */
|
||||||
BCJ_ARM = 7, /* Little endian only */
|
BCJ_IA64 = 6, /* Big or little endian */
|
||||||
BCJ_ARMTHUMB = 8, /* Little endian only */
|
BCJ_ARM = 7, /* Little endian only */
|
||||||
BCJ_SPARC = 9 /* Big or little endian */
|
BCJ_ARMTHUMB = 8, /* Little endian only */
|
||||||
|
BCJ_SPARC = 9 /* Big or little endian */
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -52,7 +54,8 @@ struct xz_dec_bcj {
|
|||||||
size_t out_pos;
|
size_t out_pos;
|
||||||
size_t out_size;
|
size_t out_size;
|
||||||
|
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
/* Amount of already filtered data in the beginning of buf */
|
/* Amount of already filtered data in the beginning of buf */
|
||||||
size_t filtered;
|
size_t filtered;
|
||||||
|
|
||||||
@ -87,13 +90,13 @@ static inline int bcj_x86_test_msbyte(uint8_t b)
|
|||||||
|
|
||||||
static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
||||||
{
|
{
|
||||||
static const bool mask_to_allowed_status[8]
|
static const bool mask_to_allowed_status[8] = {true, true, true, false,
|
||||||
= { true, true, true, false, true, false, false, false };
|
true, false, false, false};
|
||||||
|
|
||||||
static const uint8_t mask_to_bit_num[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
|
static const uint8_t mask_to_bit_num[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t prev_pos = (size_t)-1;
|
size_t prev_pos = (size_t) - 1;
|
||||||
uint32_t prev_mask = s->x86_prev_mask;
|
uint32_t prev_mask = s->x86_prev_mask;
|
||||||
uint32_t src;
|
uint32_t src;
|
||||||
uint32_t dest;
|
uint32_t dest;
|
||||||
@ -104,19 +107,24 @@ static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
size -= 4;
|
size -= 4;
|
||||||
for (i = 0; i < size; ++i) {
|
for (i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
if ((buf[i] & 0xFE) != 0xE8)
|
if ((buf[i] & 0xFE) != 0xE8)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
prev_pos = i - prev_pos;
|
prev_pos = i - prev_pos;
|
||||||
if (prev_pos > 3) {
|
if (prev_pos > 3)
|
||||||
|
{
|
||||||
prev_mask = 0;
|
prev_mask = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
prev_mask = (prev_mask << (prev_pos - 1)) & 7;
|
prev_mask = (prev_mask << (prev_pos - 1)) & 7;
|
||||||
if (prev_mask != 0) {
|
if (prev_mask != 0)
|
||||||
|
{
|
||||||
b = buf[i + 4 - mask_to_bit_num[prev_mask]];
|
b = buf[i + 4 - mask_to_bit_num[prev_mask]];
|
||||||
if (!mask_to_allowed_status[prev_mask]
|
if (!mask_to_allowed_status[prev_mask] || bcj_x86_test_msbyte(b))
|
||||||
|| bcj_x86_test_msbyte(b)) {
|
{
|
||||||
prev_pos = i;
|
prev_pos = i;
|
||||||
prev_mask = (prev_mask << 1) | 1;
|
prev_mask = (prev_mask << 1) | 1;
|
||||||
continue;
|
continue;
|
||||||
@ -126,9 +134,11 @@ static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
|
|
||||||
prev_pos = i;
|
prev_pos = i;
|
||||||
|
|
||||||
if (bcj_x86_test_msbyte(buf[i + 4])) {
|
if (bcj_x86_test_msbyte(buf[i + 4]))
|
||||||
|
{
|
||||||
src = get_unaligned_le32(buf + i + 1);
|
src = get_unaligned_le32(buf + i + 1);
|
||||||
while (true) {
|
while (true)
|
||||||
|
{
|
||||||
dest = src - (s->pos + (uint32_t)i + 5);
|
dest = src - (s->pos + (uint32_t)i + 5);
|
||||||
if (prev_mask == 0)
|
if (prev_mask == 0)
|
||||||
break;
|
break;
|
||||||
@ -145,7 +155,9 @@ static size_t bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
dest |= (uint32_t)0 - (dest & 0x01000000);
|
dest |= (uint32_t)0 - (dest & 0x01000000);
|
||||||
put_unaligned_le32(dest, buf + i + 1);
|
put_unaligned_le32(dest, buf + i + 1);
|
||||||
i += 4;
|
i += 4;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
prev_mask = (prev_mask << 1) | 1;
|
prev_mask = (prev_mask << 1) | 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,9 +174,11 @@ static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
size_t i;
|
size_t i;
|
||||||
uint32_t instr;
|
uint32_t instr;
|
||||||
|
|
||||||
for (i = 0; i + 4 <= size; i += 4) {
|
for (i = 0; i + 4 <= size; i += 4)
|
||||||
|
{
|
||||||
instr = get_unaligned_be32(buf + i);
|
instr = get_unaligned_be32(buf + i);
|
||||||
if ((instr & 0xFC000003) == 0x48000001) {
|
if ((instr & 0xFC000003) == 0x48000001)
|
||||||
|
{
|
||||||
instr &= 0x03FFFFFC;
|
instr &= 0x03FFFFFC;
|
||||||
instr -= s->pos + (uint32_t)i;
|
instr -= s->pos + (uint32_t)i;
|
||||||
instr &= 0x03FFFFFC;
|
instr &= 0x03FFFFFC;
|
||||||
@ -180,12 +194,8 @@ static size_t bcj_powerpc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
#ifdef XZ_DEC_IA64
|
#ifdef XZ_DEC_IA64
|
||||||
static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
||||||
{
|
{
|
||||||
static const uint8_t branch_table[32] = {
|
static const uint8_t branch_table[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
4, 4, 6, 6, 0, 0, 7, 7, 4, 4, 0, 0, 4, 4, 0, 0};
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
4, 4, 6, 6, 0, 0, 7, 7,
|
|
||||||
4, 4, 0, 0, 4, 4, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The local variables take a little bit stack space, but it's less
|
* The local variables take a little bit stack space, but it's less
|
||||||
@ -219,9 +229,11 @@ static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
/* Instruction normalized with bit_res for easier manipulation */
|
/* Instruction normalized with bit_res for easier manipulation */
|
||||||
uint64_t norm;
|
uint64_t norm;
|
||||||
|
|
||||||
for (i = 0; i + 16 <= size; i += 16) {
|
for (i = 0; i + 16 <= size; i += 16)
|
||||||
|
{
|
||||||
mask = branch_table[buf[i] & 0x1F];
|
mask = branch_table[buf[i] & 0x1F];
|
||||||
for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41) {
|
for (slot = 0, bit_pos = 5; slot < 3; ++slot, bit_pos += 41)
|
||||||
|
{
|
||||||
if (((mask >> slot) & 1) == 0)
|
if (((mask >> slot) & 1) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -229,13 +241,12 @@ static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
bit_res = bit_pos & 7;
|
bit_res = bit_pos & 7;
|
||||||
instr = 0;
|
instr = 0;
|
||||||
for (j = 0; j < 6; ++j)
|
for (j = 0; j < 6; ++j)
|
||||||
instr |= (uint64_t)(buf[i + j + byte_pos])
|
instr |= (uint64_t)(buf[i + j + byte_pos]) << (8 * j);
|
||||||
<< (8 * j);
|
|
||||||
|
|
||||||
norm = instr >> bit_res;
|
norm = instr >> bit_res;
|
||||||
|
|
||||||
if (((norm >> 37) & 0x0F) == 0x05
|
if (((norm >> 37) & 0x0F) == 0x05 && ((norm >> 9) & 0x07) == 0)
|
||||||
&& ((norm >> 9) & 0x07) == 0) {
|
{
|
||||||
addr = (norm >> 13) & 0x0FFFFF;
|
addr = (norm >> 13) & 0x0FFFFF;
|
||||||
addr |= ((uint32_t)(norm >> 36) & 1) << 20;
|
addr |= ((uint32_t)(norm >> 36) & 1) << 20;
|
||||||
addr <<= 4;
|
addr <<= 4;
|
||||||
@ -244,15 +255,13 @@ static size_t bcj_ia64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
|
|
||||||
norm &= ~((uint64_t)0x8FFFFF << 13);
|
norm &= ~((uint64_t)0x8FFFFF << 13);
|
||||||
norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
|
norm |= (uint64_t)(addr & 0x0FFFFF) << 13;
|
||||||
norm |= (uint64_t)(addr & 0x100000)
|
norm |= (uint64_t)(addr & 0x100000) << (36 - 20);
|
||||||
<< (36 - 20);
|
|
||||||
|
|
||||||
instr &= (1 << bit_res) - 1;
|
instr &= (1 << bit_res) - 1;
|
||||||
instr |= norm << bit_res;
|
instr |= norm << bit_res;
|
||||||
|
|
||||||
for (j = 0; j < 6; j++)
|
for (j = 0; j < 6; j++)
|
||||||
buf[i + j + byte_pos]
|
buf[i + j + byte_pos] = (uint8_t)(instr >> (8 * j));
|
||||||
= (uint8_t)(instr >> (8 * j));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,10 +276,12 @@ static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
size_t i;
|
size_t i;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
|
|
||||||
for (i = 0; i + 4 <= size; i += 4) {
|
for (i = 0; i + 4 <= size; i += 4)
|
||||||
if (buf[i + 3] == 0xEB) {
|
{
|
||||||
addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8)
|
if (buf[i + 3] == 0xEB)
|
||||||
| ((uint32_t)buf[i + 2] << 16);
|
{
|
||||||
|
addr =
|
||||||
|
(uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) | ((uint32_t)buf[i + 2] << 16);
|
||||||
addr <<= 2;
|
addr <<= 2;
|
||||||
addr -= s->pos + (uint32_t)i + 8;
|
addr -= s->pos + (uint32_t)i + 8;
|
||||||
addr >>= 2;
|
addr >>= 2;
|
||||||
@ -290,13 +301,12 @@ static size_t bcj_armthumb(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
size_t i;
|
size_t i;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
|
|
||||||
for (i = 0; i + 4 <= size; i += 2) {
|
for (i = 0; i + 4 <= size; i += 2)
|
||||||
if ((buf[i + 1] & 0xF8) == 0xF0
|
{
|
||||||
&& (buf[i + 3] & 0xF8) == 0xF8) {
|
if ((buf[i + 1] & 0xF8) == 0xF0 && (buf[i + 3] & 0xF8) == 0xF8)
|
||||||
addr = (((uint32_t)buf[i + 1] & 0x07) << 19)
|
{
|
||||||
| ((uint32_t)buf[i] << 11)
|
addr = (((uint32_t)buf[i + 1] & 0x07) << 19) | ((uint32_t)buf[i] << 11) |
|
||||||
| (((uint32_t)buf[i + 3] & 0x07) << 8)
|
(((uint32_t)buf[i + 3] & 0x07) << 8) | (uint32_t)buf[i + 2];
|
||||||
| (uint32_t)buf[i + 2];
|
|
||||||
addr <<= 1;
|
addr <<= 1;
|
||||||
addr -= s->pos + (uint32_t)i + 4;
|
addr -= s->pos + (uint32_t)i + 4;
|
||||||
addr >>= 1;
|
addr >>= 1;
|
||||||
@ -318,14 +328,16 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
size_t i;
|
size_t i;
|
||||||
uint32_t instr;
|
uint32_t instr;
|
||||||
|
|
||||||
for (i = 0; i + 4 <= size; i += 4) {
|
for (i = 0; i + 4 <= size; i += 4)
|
||||||
|
{
|
||||||
instr = get_unaligned_be32(buf + i);
|
instr = get_unaligned_be32(buf + i);
|
||||||
if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF) {
|
if ((instr >> 22) == 0x100 || (instr >> 22) == 0x1FF)
|
||||||
|
{
|
||||||
instr <<= 2;
|
instr <<= 2;
|
||||||
instr -= s->pos + (uint32_t)i;
|
instr -= s->pos + (uint32_t)i;
|
||||||
instr >>= 2;
|
instr >>= 2;
|
||||||
instr = ((uint32_t)0x40000000 - (instr & 0x400000))
|
instr =
|
||||||
| 0x40000000 | (instr & 0x3FFFFF);
|
((uint32_t)0x40000000 - (instr & 0x400000)) | 0x40000000 | (instr & 0x3FFFFF);
|
||||||
put_unaligned_be32(instr, buf + i);
|
put_unaligned_be32(instr, buf + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,15 +354,15 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
|
|||||||
* pointers, which could be problematic in the kernel boot code, which must
|
* pointers, which could be problematic in the kernel boot code, which must
|
||||||
* avoid pointers to static data (at least on x86).
|
* avoid pointers to static data (at least on x86).
|
||||||
*/
|
*/
|
||||||
static void bcj_apply(struct xz_dec_bcj *s,
|
static void bcj_apply(struct xz_dec_bcj *s, uint8_t *buf, size_t *pos, size_t size)
|
||||||
uint8_t *buf, size_t *pos, size_t size)
|
|
||||||
{
|
{
|
||||||
size_t filtered;
|
size_t filtered;
|
||||||
|
|
||||||
buf += *pos;
|
buf += *pos;
|
||||||
size -= *pos;
|
size -= *pos;
|
||||||
|
|
||||||
switch (s->type) {
|
switch (s->type)
|
||||||
|
{
|
||||||
#ifdef XZ_DEC_X86
|
#ifdef XZ_DEC_X86
|
||||||
case BCJ_X86:
|
case BCJ_X86:
|
||||||
filtered = bcj_x86(s, buf, size);
|
filtered = bcj_x86(s, buf, size);
|
||||||
@ -414,9 +426,8 @@ static void bcj_flush(struct xz_dec_bcj *s, struct xz_buf *b)
|
|||||||
* data in chunks of 1-16 bytes. To hide this issue, this function does
|
* data in chunks of 1-16 bytes. To hide this issue, this function does
|
||||||
* some buffering.
|
* some buffering.
|
||||||
*/
|
*/
|
||||||
XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
|
XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2,
|
||||||
struct xz_dec_lzma2 *lzma2,
|
struct xz_buf *b)
|
||||||
struct xz_buf *b)
|
|
||||||
{
|
{
|
||||||
size_t out_start;
|
size_t out_start;
|
||||||
|
|
||||||
@ -425,7 +436,8 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
|
|||||||
* immediatelly if we couldn't flush everything, or if the next
|
* immediatelly if we couldn't flush everything, or if the next
|
||||||
* filter in the chain had already returned XZ_STREAM_END.
|
* filter in the chain had already returned XZ_STREAM_END.
|
||||||
*/
|
*/
|
||||||
if (s->temp.filtered > 0) {
|
if (s->temp.filtered > 0)
|
||||||
|
{
|
||||||
bcj_flush(s, b);
|
bcj_flush(s, b);
|
||||||
if (s->temp.filtered > 0)
|
if (s->temp.filtered > 0)
|
||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
@ -446,14 +458,14 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
|
|||||||
* case where the output buffer is full and the next filter has no
|
* case where the output buffer is full and the next filter has no
|
||||||
* more output coming but hasn't returned XZ_STREAM_END yet.
|
* more output coming but hasn't returned XZ_STREAM_END yet.
|
||||||
*/
|
*/
|
||||||
if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
|
if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0)
|
||||||
|
{
|
||||||
out_start = b->out_pos;
|
out_start = b->out_pos;
|
||||||
memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
|
memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
|
||||||
b->out_pos += s->temp.size;
|
b->out_pos += s->temp.size;
|
||||||
|
|
||||||
s->ret = xz_dec_lzma2_run(lzma2, b);
|
s->ret = xz_dec_lzma2_run(lzma2, b);
|
||||||
if (s->ret != XZ_STREAM_END
|
if (s->ret != XZ_STREAM_END && (s->ret != XZ_OK || s->single_call))
|
||||||
&& (s->ret != XZ_OK || s->single_call))
|
|
||||||
return s->ret;
|
return s->ret;
|
||||||
|
|
||||||
bcj_apply(s, b->out, &out_start, b->out_pos);
|
bcj_apply(s, b->out, &out_start, b->out_pos);
|
||||||
@ -487,7 +499,8 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
|
|||||||
* A mix of filtered and unfiltered data may be left in temp; it will
|
* A mix of filtered and unfiltered data may be left in temp; it will
|
||||||
* be taken care on the next call to this function.
|
* be taken care on the next call to this function.
|
||||||
*/
|
*/
|
||||||
if (b->out_pos < b->out_size) {
|
if (b->out_pos < b->out_size)
|
||||||
|
{
|
||||||
/* Make b->out{,_pos,_size} temporarily point to s->temp. */
|
/* Make b->out{,_pos,_size} temporarily point to s->temp. */
|
||||||
s->out = b->out;
|
s->out = b->out;
|
||||||
s->out_pos = b->out_pos;
|
s->out_pos = b->out_pos;
|
||||||
@ -535,7 +548,8 @@ XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call)
|
|||||||
|
|
||||||
XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
|
XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
|
||||||
{
|
{
|
||||||
switch (id) {
|
switch (id)
|
||||||
|
{
|
||||||
#ifdef XZ_DEC_X86
|
#ifdef XZ_DEC_X86
|
||||||
case BCJ_X86:
|
case BCJ_X86:
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,7 +41,8 @@
|
|||||||
* in which the dictionary variables address the actual output
|
* in which the dictionary variables address the actual output
|
||||||
* buffer directly.
|
* buffer directly.
|
||||||
*/
|
*/
|
||||||
struct dictionary {
|
struct dictionary
|
||||||
|
{
|
||||||
/* Beginning of the history buffer */
|
/* Beginning of the history buffer */
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
|
|
||||||
@ -92,7 +93,8 @@ struct dictionary {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Range decoder */
|
/* Range decoder */
|
||||||
struct rc_dec {
|
struct rc_dec
|
||||||
|
{
|
||||||
uint32_t range;
|
uint32_t range;
|
||||||
uint32_t code;
|
uint32_t code;
|
||||||
|
|
||||||
@ -112,7 +114,8 @@ struct rc_dec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Probabilities for a length decoder. */
|
/* Probabilities for a length decoder. */
|
||||||
struct lzma_len_dec {
|
struct lzma_len_dec
|
||||||
|
{
|
||||||
/* Probability of match length being at least 10 */
|
/* Probability of match length being at least 10 */
|
||||||
uint16_t choice;
|
uint16_t choice;
|
||||||
|
|
||||||
@ -129,7 +132,8 @@ struct lzma_len_dec {
|
|||||||
uint16_t high[LEN_HIGH_SYMBOLS];
|
uint16_t high[LEN_HIGH_SYMBOLS];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lzma_dec {
|
struct lzma_dec
|
||||||
|
{
|
||||||
/* Distances of latest four matches */
|
/* Distances of latest four matches */
|
||||||
uint32_t rep0;
|
uint32_t rep0;
|
||||||
uint32_t rep1;
|
uint32_t rep1;
|
||||||
@ -153,7 +157,7 @@ struct lzma_dec {
|
|||||||
*/
|
*/
|
||||||
uint32_t lc;
|
uint32_t lc;
|
||||||
uint32_t literal_pos_mask; /* (1 << lp) - 1 */
|
uint32_t literal_pos_mask; /* (1 << lp) - 1 */
|
||||||
uint32_t pos_mask; /* (1 << pb) - 1 */
|
uint32_t pos_mask; /* (1 << pb) - 1 */
|
||||||
|
|
||||||
/* If 1, it's a match. Otherwise it's a single 8-bit literal. */
|
/* If 1, it's a match. Otherwise it's a single 8-bit literal. */
|
||||||
uint16_t is_match[STATES][POS_STATES_MAX];
|
uint16_t is_match[STATES][POS_STATES_MAX];
|
||||||
@ -211,9 +215,11 @@ struct lzma_dec {
|
|||||||
uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
|
uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lzma2_dec {
|
struct lzma2_dec
|
||||||
|
{
|
||||||
/* Position in xz_dec_lzma2_run(). */
|
/* Position in xz_dec_lzma2_run(). */
|
||||||
enum lzma2_seq {
|
enum lzma2_seq
|
||||||
|
{
|
||||||
SEQ_CONTROL,
|
SEQ_CONTROL,
|
||||||
SEQ_UNCOMPRESSED_1,
|
SEQ_UNCOMPRESSED_1,
|
||||||
SEQ_UNCOMPRESSED_2,
|
SEQ_UNCOMPRESSED_2,
|
||||||
@ -250,7 +256,8 @@ struct lzma2_dec {
|
|||||||
bool need_props;
|
bool need_props;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xz_dec_lzma2 {
|
struct xz_dec_lzma2
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* The order below is important on x86 to reduce code size and
|
* The order below is important on x86 to reduce code size and
|
||||||
* it shouldn't hurt on other platforms. Everything up to and
|
* it shouldn't hurt on other platforms. Everything up to and
|
||||||
@ -269,7 +276,8 @@ struct xz_dec_lzma2 {
|
|||||||
* Temporary buffer which holds small number of input bytes between
|
* Temporary buffer which holds small number of input bytes between
|
||||||
* decoder calls. See lzma2_lzma() for details.
|
* decoder calls. See lzma2_lzma() for details.
|
||||||
*/
|
*/
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t buf[3 * LZMA_IN_REQUIRED];
|
uint8_t buf[3 * LZMA_IN_REQUIRED];
|
||||||
} temp;
|
} temp;
|
||||||
@ -285,7 +293,8 @@ struct xz_dec_lzma2 {
|
|||||||
*/
|
*/
|
||||||
static void dict_reset(struct dictionary *dict, struct xz_buf *b)
|
static void dict_reset(struct dictionary *dict, struct xz_buf *b)
|
||||||
{
|
{
|
||||||
if (DEC_IS_SINGLE(dict->mode)) {
|
if (DEC_IS_SINGLE(dict->mode))
|
||||||
|
{
|
||||||
dict->buf = b->out + b->out_pos;
|
dict->buf = b->out + b->out_pos;
|
||||||
dict->end = b->out_size - b->out_pos;
|
dict->end = b->out_size - b->out_pos;
|
||||||
}
|
}
|
||||||
@ -358,7 +367,8 @@ static bool dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist)
|
|||||||
if (dist >= dict->pos)
|
if (dist >= dict->pos)
|
||||||
back += dict->end;
|
back += dict->end;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
dict->buf[dict->pos++] = dict->buf[back++];
|
dict->buf[dict->pos++] = dict->buf[back++];
|
||||||
if (back == dict->end)
|
if (back == dict->end)
|
||||||
back = 0;
|
back = 0;
|
||||||
@ -371,15 +381,13 @@ static bool dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Copy uncompressed data as is from input to dictionary and output buffers. */
|
/* Copy uncompressed data as is from input to dictionary and output buffers. */
|
||||||
static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
|
static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b, uint32_t *left)
|
||||||
uint32_t *left)
|
|
||||||
{
|
{
|
||||||
size_t copy_size;
|
size_t copy_size;
|
||||||
|
|
||||||
while (*left > 0 && b->in_pos < b->in_size
|
while (*left > 0 && b->in_pos < b->in_size && b->out_pos < b->out_size)
|
||||||
&& b->out_pos < b->out_size) {
|
{
|
||||||
copy_size = min(b->in_size - b->in_pos,
|
copy_size = min(b->in_size - b->in_pos, b->out_size - b->out_pos);
|
||||||
b->out_size - b->out_pos);
|
|
||||||
if (copy_size > dict->end - dict->pos)
|
if (copy_size > dict->end - dict->pos)
|
||||||
copy_size = dict->end - dict->pos;
|
copy_size = dict->end - dict->pos;
|
||||||
if (copy_size > *left)
|
if (copy_size > *left)
|
||||||
@ -393,12 +401,12 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
|
|||||||
if (dict->full < dict->pos)
|
if (dict->full < dict->pos)
|
||||||
dict->full = dict->pos;
|
dict->full = dict->pos;
|
||||||
|
|
||||||
if (DEC_IS_MULTI(dict->mode)) {
|
if (DEC_IS_MULTI(dict->mode))
|
||||||
|
{
|
||||||
if (dict->pos == dict->end)
|
if (dict->pos == dict->end)
|
||||||
dict->pos = 0;
|
dict->pos = 0;
|
||||||
|
|
||||||
memcpy(b->out + b->out_pos, b->in + b->in_pos,
|
memcpy(b->out + b->out_pos, b->in + b->in_pos, copy_size);
|
||||||
copy_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dict->start = dict->pos;
|
dict->start = dict->pos;
|
||||||
@ -417,12 +425,12 @@ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
|
|||||||
{
|
{
|
||||||
size_t copy_size = dict->pos - dict->start;
|
size_t copy_size = dict->pos - dict->start;
|
||||||
|
|
||||||
if (DEC_IS_MULTI(dict->mode)) {
|
if (DEC_IS_MULTI(dict->mode))
|
||||||
|
{
|
||||||
if (dict->pos == dict->end)
|
if (dict->pos == dict->end)
|
||||||
dict->pos = 0;
|
dict->pos = 0;
|
||||||
|
|
||||||
memcpy(b->out + b->out_pos, dict->buf + dict->start,
|
memcpy(b->out + b->out_pos, dict->buf + dict->start, copy_size);
|
||||||
copy_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dict->start = dict->pos;
|
dict->start = dict->pos;
|
||||||
@ -437,7 +445,7 @@ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
|
|||||||
/* Reset the range decoder. */
|
/* Reset the range decoder. */
|
||||||
static void rc_reset(struct rc_dec *rc)
|
static void rc_reset(struct rc_dec *rc)
|
||||||
{
|
{
|
||||||
rc->range = (uint32_t)-1;
|
rc->range = (uint32_t) - 1;
|
||||||
rc->code = 0;
|
rc->code = 0;
|
||||||
rc->init_bytes_left = RC_INIT_BYTES;
|
rc->init_bytes_left = RC_INIT_BYTES;
|
||||||
}
|
}
|
||||||
@ -448,7 +456,8 @@ static void rc_reset(struct rc_dec *rc)
|
|||||||
*/
|
*/
|
||||||
static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b)
|
static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b)
|
||||||
{
|
{
|
||||||
while (rc->init_bytes_left > 0) {
|
while (rc->init_bytes_left > 0)
|
||||||
|
{
|
||||||
if (b->in_pos == b->in_size)
|
if (b->in_pos == b->in_size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -477,7 +486,8 @@ static inline bool rc_is_finished(const struct rc_dec *rc)
|
|||||||
/* Read the next input byte if needed. */
|
/* Read the next input byte if needed. */
|
||||||
static __always_inline void rc_normalize(struct rc_dec *rc)
|
static __always_inline void rc_normalize(struct rc_dec *rc)
|
||||||
{
|
{
|
||||||
if (rc->range < RC_TOP_VALUE) {
|
if (rc->range < RC_TOP_VALUE)
|
||||||
|
{
|
||||||
rc->range <<= RC_SHIFT_BITS;
|
rc->range <<= RC_SHIFT_BITS;
|
||||||
rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
|
rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
|
||||||
}
|
}
|
||||||
@ -501,11 +511,14 @@ static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob)
|
|||||||
|
|
||||||
rc_normalize(rc);
|
rc_normalize(rc);
|
||||||
bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
|
bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
|
||||||
if (rc->code < bound) {
|
if (rc->code < bound)
|
||||||
|
{
|
||||||
rc->range = bound;
|
rc->range = bound;
|
||||||
*prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
|
*prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
|
||||||
bit = 0;
|
bit = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
rc->range -= bound;
|
rc->range -= bound;
|
||||||
rc->code -= bound;
|
rc->code -= bound;
|
||||||
*prob -= *prob >> RC_MOVE_BITS;
|
*prob -= *prob >> RC_MOVE_BITS;
|
||||||
@ -516,12 +529,12 @@ static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Decode a bittree starting from the most significant bit. */
|
/* Decode a bittree starting from the most significant bit. */
|
||||||
static __always_inline uint32_t rc_bittree(struct rc_dec *rc,
|
static __always_inline uint32_t rc_bittree(struct rc_dec *rc, uint16_t *probs, uint32_t limit)
|
||||||
uint16_t *probs, uint32_t limit)
|
|
||||||
{
|
{
|
||||||
uint32_t symbol = 1;
|
uint32_t symbol = 1;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
if (rc_bit(rc, &probs[symbol]))
|
if (rc_bit(rc, &probs[symbol]))
|
||||||
symbol = (symbol << 1) + 1;
|
symbol = (symbol << 1) + 1;
|
||||||
else
|
else
|
||||||
@ -532,18 +545,21 @@ static __always_inline uint32_t rc_bittree(struct rc_dec *rc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Decode a bittree starting from the least significant bit. */
|
/* Decode a bittree starting from the least significant bit. */
|
||||||
static __always_inline void rc_bittree_reverse(struct rc_dec *rc,
|
static __always_inline void rc_bittree_reverse(struct rc_dec *rc, uint16_t *probs,
|
||||||
uint16_t *probs,
|
uint32_t *dest, uint32_t limit)
|
||||||
uint32_t *dest, uint32_t limit)
|
|
||||||
{
|
{
|
||||||
uint32_t symbol = 1;
|
uint32_t symbol = 1;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
do {
|
do
|
||||||
if (rc_bit(rc, &probs[symbol])) {
|
{
|
||||||
|
if (rc_bit(rc, &probs[symbol]))
|
||||||
|
{
|
||||||
symbol = (symbol << 1) + 1;
|
symbol = (symbol << 1) + 1;
|
||||||
*dest += 1 << i;
|
*dest += 1 << i;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
symbol <<= 1;
|
symbol <<= 1;
|
||||||
}
|
}
|
||||||
} while (++i < limit);
|
} while (++i < limit);
|
||||||
@ -554,7 +570,8 @@ static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit)
|
|||||||
{
|
{
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
rc_normalize(rc);
|
rc_normalize(rc);
|
||||||
rc->range >>= 1;
|
rc->range >>= 1;
|
||||||
rc->code -= rc->range;
|
rc->code -= rc->range;
|
||||||
@ -589,22 +606,29 @@ static void lzma_literal(struct xz_dec_lzma2 *s)
|
|||||||
|
|
||||||
probs = lzma_literal_probs(s);
|
probs = lzma_literal_probs(s);
|
||||||
|
|
||||||
if (lzma_state_is_literal(s->lzma.state)) {
|
if (lzma_state_is_literal(s->lzma.state))
|
||||||
|
{
|
||||||
symbol = rc_bittree(&s->rc, probs, 0x100);
|
symbol = rc_bittree(&s->rc, probs, 0x100);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
symbol = 1;
|
symbol = 1;
|
||||||
match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
|
match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
|
||||||
offset = 0x100;
|
offset = 0x100;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
match_bit = match_byte & offset;
|
match_bit = match_byte & offset;
|
||||||
match_byte <<= 1;
|
match_byte <<= 1;
|
||||||
i = offset + match_bit + symbol;
|
i = offset + match_bit + symbol;
|
||||||
|
|
||||||
if (rc_bit(&s->rc, &probs[i])) {
|
if (rc_bit(&s->rc, &probs[i]))
|
||||||
|
{
|
||||||
symbol = (symbol << 1) + 1;
|
symbol = (symbol << 1) + 1;
|
||||||
offset &= match_bit;
|
offset &= match_bit;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
symbol <<= 1;
|
symbol <<= 1;
|
||||||
offset &= ~match_bit;
|
offset &= ~match_bit;
|
||||||
}
|
}
|
||||||
@ -616,26 +640,30 @@ static void lzma_literal(struct xz_dec_lzma2 *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Decode the length of the match into s->lzma.len. */
|
/* Decode the length of the match into s->lzma.len. */
|
||||||
static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l,
|
static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l, uint32_t pos_state)
|
||||||
uint32_t pos_state)
|
|
||||||
{
|
{
|
||||||
uint16_t *probs;
|
uint16_t *probs;
|
||||||
uint32_t limit;
|
uint32_t limit;
|
||||||
|
|
||||||
if (!rc_bit(&s->rc, &l->choice)) {
|
if (!rc_bit(&s->rc, &l->choice))
|
||||||
|
{
|
||||||
probs = l->low[pos_state];
|
probs = l->low[pos_state];
|
||||||
limit = LEN_LOW_SYMBOLS;
|
limit = LEN_LOW_SYMBOLS;
|
||||||
s->lzma.len = MATCH_LEN_MIN;
|
s->lzma.len = MATCH_LEN_MIN;
|
||||||
} else {
|
}
|
||||||
if (!rc_bit(&s->rc, &l->choice2)) {
|
else
|
||||||
|
{
|
||||||
|
if (!rc_bit(&s->rc, &l->choice2))
|
||||||
|
{
|
||||||
probs = l->mid[pos_state];
|
probs = l->mid[pos_state];
|
||||||
limit = LEN_MID_SYMBOLS;
|
limit = LEN_MID_SYMBOLS;
|
||||||
s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
|
s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
probs = l->high;
|
probs = l->high;
|
||||||
limit = LEN_HIGH_SYMBOLS;
|
limit = LEN_HIGH_SYMBOLS;
|
||||||
s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS
|
s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS;
|
||||||
+ LEN_MID_SYMBOLS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,23 +688,26 @@ static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
|
|||||||
probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
|
probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
|
||||||
dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
|
dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
|
||||||
|
|
||||||
if (dist_slot < DIST_MODEL_START) {
|
if (dist_slot < DIST_MODEL_START)
|
||||||
|
{
|
||||||
s->lzma.rep0 = dist_slot;
|
s->lzma.rep0 = dist_slot;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
limit = (dist_slot >> 1) - 1;
|
limit = (dist_slot >> 1) - 1;
|
||||||
s->lzma.rep0 = 2 + (dist_slot & 1);
|
s->lzma.rep0 = 2 + (dist_slot & 1);
|
||||||
|
|
||||||
if (dist_slot < DIST_MODEL_END) {
|
if (dist_slot < DIST_MODEL_END)
|
||||||
|
{
|
||||||
s->lzma.rep0 <<= limit;
|
s->lzma.rep0 <<= limit;
|
||||||
probs = s->lzma.dist_special + s->lzma.rep0
|
probs = s->lzma.dist_special + s->lzma.rep0 - dist_slot - 1;
|
||||||
- dist_slot - 1;
|
rc_bittree_reverse(&s->rc, probs, &s->lzma.rep0, limit);
|
||||||
rc_bittree_reverse(&s->rc, probs,
|
}
|
||||||
&s->lzma.rep0, limit);
|
else
|
||||||
} else {
|
{
|
||||||
rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
|
rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
|
||||||
s->lzma.rep0 <<= ALIGN_BITS;
|
s->lzma.rep0 <<= ALIGN_BITS;
|
||||||
rc_bittree_reverse(&s->rc, s->lzma.dist_align,
|
rc_bittree_reverse(&s->rc, s->lzma.dist_align, &s->lzma.rep0, ALIGN_BITS);
|
||||||
&s->lzma.rep0, ALIGN_BITS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -689,20 +720,29 @@ static void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
|
|||||||
{
|
{
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) {
|
if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state]))
|
||||||
if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[
|
{
|
||||||
s->lzma.state][pos_state])) {
|
if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[s->lzma.state][pos_state]))
|
||||||
|
{
|
||||||
lzma_state_short_rep(&s->lzma.state);
|
lzma_state_short_rep(&s->lzma.state);
|
||||||
s->lzma.len = 1;
|
s->lzma.len = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) {
|
else
|
||||||
|
{
|
||||||
|
if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state]))
|
||||||
|
{
|
||||||
tmp = s->lzma.rep1;
|
tmp = s->lzma.rep1;
|
||||||
} else {
|
}
|
||||||
if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) {
|
else
|
||||||
|
{
|
||||||
|
if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state]))
|
||||||
|
{
|
||||||
tmp = s->lzma.rep2;
|
tmp = s->lzma.rep2;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tmp = s->lzma.rep3;
|
tmp = s->lzma.rep3;
|
||||||
s->lzma.rep3 = s->lzma.rep2;
|
s->lzma.rep3 = s->lzma.rep2;
|
||||||
}
|
}
|
||||||
@ -734,13 +774,16 @@ static bool lzma_main(struct xz_dec_lzma2 *s)
|
|||||||
* Decode more LZMA symbols. One iteration may consume up to
|
* Decode more LZMA symbols. One iteration may consume up to
|
||||||
* LZMA_IN_REQUIRED - 1 bytes.
|
* LZMA_IN_REQUIRED - 1 bytes.
|
||||||
*/
|
*/
|
||||||
while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) {
|
while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc))
|
||||||
|
{
|
||||||
pos_state = s->dict.pos & s->lzma.pos_mask;
|
pos_state = s->dict.pos & s->lzma.pos_mask;
|
||||||
|
|
||||||
if (!rc_bit(&s->rc, &s->lzma.is_match[
|
if (!rc_bit(&s->rc, &s->lzma.is_match[s->lzma.state][pos_state]))
|
||||||
s->lzma.state][pos_state])) {
|
{
|
||||||
lzma_literal(s);
|
lzma_literal(s);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
|
if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
|
||||||
lzma_rep_match(s, pos_state);
|
lzma_rep_match(s, pos_state);
|
||||||
else
|
else
|
||||||
@ -802,7 +845,8 @@ static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
s->lzma.pos_mask = 0;
|
s->lzma.pos_mask = 0;
|
||||||
while (props >= 9 * 5) {
|
while (props >= 9 * 5)
|
||||||
|
{
|
||||||
props -= 9 * 5;
|
props -= 9 * 5;
|
||||||
++s->lzma.pos_mask;
|
++s->lzma.pos_mask;
|
||||||
}
|
}
|
||||||
@ -810,7 +854,8 @@ static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
|
|||||||
s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
|
s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
|
||||||
|
|
||||||
s->lzma.literal_pos_mask = 0;
|
s->lzma.literal_pos_mask = 0;
|
||||||
while (props >= 9) {
|
while (props >= 9)
|
||||||
|
{
|
||||||
props -= 9;
|
props -= 9;
|
||||||
++s->lzma.literal_pos_mask;
|
++s->lzma.literal_pos_mask;
|
||||||
}
|
}
|
||||||
@ -849,7 +894,8 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
|||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
in_avail = b->in_size - b->in_pos;
|
in_avail = b->in_size - b->in_pos;
|
||||||
if (s->temp.size > 0 || s->lzma2.compressed == 0) {
|
if (s->temp.size > 0 || s->lzma2.compressed == 0)
|
||||||
|
{
|
||||||
tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
|
tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
|
||||||
if (tmp > s->lzma2.compressed - s->temp.size)
|
if (tmp > s->lzma2.compressed - s->temp.size)
|
||||||
tmp = s->lzma2.compressed - s->temp.size;
|
tmp = s->lzma2.compressed - s->temp.size;
|
||||||
@ -858,16 +904,19 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
|||||||
|
|
||||||
memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
|
memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
|
||||||
|
|
||||||
if (s->temp.size + tmp == s->lzma2.compressed) {
|
if (s->temp.size + tmp == s->lzma2.compressed)
|
||||||
memzero(s->temp.buf + s->temp.size + tmp,
|
{
|
||||||
sizeof(s->temp.buf)
|
memzero(s->temp.buf + s->temp.size + tmp, sizeof(s->temp.buf) - s->temp.size - tmp);
|
||||||
- s->temp.size - tmp);
|
|
||||||
s->rc.in_limit = s->temp.size + tmp;
|
s->rc.in_limit = s->temp.size + tmp;
|
||||||
} else if (s->temp.size + tmp < LZMA_IN_REQUIRED) {
|
}
|
||||||
|
else if (s->temp.size + tmp < LZMA_IN_REQUIRED)
|
||||||
|
{
|
||||||
s->temp.size += tmp;
|
s->temp.size += tmp;
|
||||||
b->in_pos += tmp;
|
b->in_pos += tmp;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
|
s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,10 +928,10 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
|||||||
|
|
||||||
s->lzma2.compressed -= s->rc.in_pos;
|
s->lzma2.compressed -= s->rc.in_pos;
|
||||||
|
|
||||||
if (s->rc.in_pos < s->temp.size) {
|
if (s->rc.in_pos < s->temp.size)
|
||||||
|
{
|
||||||
s->temp.size -= s->rc.in_pos;
|
s->temp.size -= s->rc.in_pos;
|
||||||
memmove(s->temp.buf, s->temp.buf + s->rc.in_pos,
|
memmove(s->temp.buf, s->temp.buf + s->rc.in_pos, s->temp.size);
|
||||||
s->temp.size);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -891,7 +940,8 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
in_avail = b->in_size - b->in_pos;
|
in_avail = b->in_size - b->in_pos;
|
||||||
if (in_avail >= LZMA_IN_REQUIRED) {
|
if (in_avail >= LZMA_IN_REQUIRED)
|
||||||
|
{
|
||||||
s->rc.in = b->in;
|
s->rc.in = b->in;
|
||||||
s->rc.in_pos = b->in_pos;
|
s->rc.in_pos = b->in_pos;
|
||||||
|
|
||||||
@ -912,7 +962,8 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
in_avail = b->in_size - b->in_pos;
|
in_avail = b->in_size - b->in_pos;
|
||||||
if (in_avail < LZMA_IN_REQUIRED) {
|
if (in_avail < LZMA_IN_REQUIRED)
|
||||||
|
{
|
||||||
if (in_avail > s->lzma2.compressed)
|
if (in_avail > s->lzma2.compressed)
|
||||||
in_avail = s->lzma2.compressed;
|
in_avail = s->lzma2.compressed;
|
||||||
|
|
||||||
@ -928,13 +979,14 @@ static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
|||||||
* Take care of the LZMA2 control layer, and forward the job of actual LZMA
|
* Take care of the LZMA2 control layer, and forward the job of actual LZMA
|
||||||
* decoding or copying of uncompressed chunks to other functions.
|
* decoding or copying of uncompressed chunks to other functions.
|
||||||
*/
|
*/
|
||||||
XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
|
XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
||||||
struct xz_buf *b)
|
|
||||||
{
|
{
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) {
|
while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN)
|
||||||
switch (s->lzma2.sequence) {
|
{
|
||||||
|
switch (s->lzma2.sequence)
|
||||||
|
{
|
||||||
case SEQ_CONTROL:
|
case SEQ_CONTROL:
|
||||||
/*
|
/*
|
||||||
* LZMA2 control byte
|
* LZMA2 control byte
|
||||||
@ -972,38 +1024,45 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
|
|||||||
if (tmp == 0x00)
|
if (tmp == 0x00)
|
||||||
return XZ_STREAM_END;
|
return XZ_STREAM_END;
|
||||||
|
|
||||||
if (tmp >= 0xE0 || tmp == 0x01) {
|
if (tmp >= 0xE0 || tmp == 0x01)
|
||||||
|
{
|
||||||
s->lzma2.need_props = true;
|
s->lzma2.need_props = true;
|
||||||
s->lzma2.need_dict_reset = false;
|
s->lzma2.need_dict_reset = false;
|
||||||
dict_reset(&s->dict, b);
|
dict_reset(&s->dict, b);
|
||||||
} else if (s->lzma2.need_dict_reset) {
|
}
|
||||||
|
else if (s->lzma2.need_dict_reset)
|
||||||
|
{
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp >= 0x80) {
|
if (tmp >= 0x80)
|
||||||
|
{
|
||||||
s->lzma2.uncompressed = (tmp & 0x1F) << 16;
|
s->lzma2.uncompressed = (tmp & 0x1F) << 16;
|
||||||
s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
|
s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
|
||||||
|
|
||||||
if (tmp >= 0xC0) {
|
if (tmp >= 0xC0)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* When there are new properties,
|
* When there are new properties,
|
||||||
* state reset is done at
|
* state reset is done at
|
||||||
* SEQ_PROPERTIES.
|
* SEQ_PROPERTIES.
|
||||||
*/
|
*/
|
||||||
s->lzma2.need_props = false;
|
s->lzma2.need_props = false;
|
||||||
s->lzma2.next_sequence
|
s->lzma2.next_sequence = SEQ_PROPERTIES;
|
||||||
= SEQ_PROPERTIES;
|
}
|
||||||
|
else if (s->lzma2.need_props)
|
||||||
} else if (s->lzma2.need_props) {
|
{
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
}
|
||||||
} else {
|
else
|
||||||
s->lzma2.next_sequence
|
{
|
||||||
= SEQ_LZMA_PREPARE;
|
s->lzma2.next_sequence = SEQ_LZMA_PREPARE;
|
||||||
if (tmp >= 0xA0)
|
if (tmp >= 0xA0)
|
||||||
lzma_reset(s);
|
lzma_reset(s);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (tmp > 0x02)
|
if (tmp > 0x02)
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
@ -1014,26 +1073,22 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_UNCOMPRESSED_1:
|
case SEQ_UNCOMPRESSED_1:
|
||||||
s->lzma2.uncompressed
|
s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] << 8;
|
||||||
+= (uint32_t)b->in[b->in_pos++] << 8;
|
|
||||||
s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
|
s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_UNCOMPRESSED_2:
|
case SEQ_UNCOMPRESSED_2:
|
||||||
s->lzma2.uncompressed
|
s->lzma2.uncompressed += (uint32_t)b->in[b->in_pos++] + 1;
|
||||||
+= (uint32_t)b->in[b->in_pos++] + 1;
|
|
||||||
s->lzma2.sequence = SEQ_COMPRESSED_0;
|
s->lzma2.sequence = SEQ_COMPRESSED_0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_COMPRESSED_0:
|
case SEQ_COMPRESSED_0:
|
||||||
s->lzma2.compressed
|
s->lzma2.compressed = (uint32_t)b->in[b->in_pos++] << 8;
|
||||||
= (uint32_t)b->in[b->in_pos++] << 8;
|
|
||||||
s->lzma2.sequence = SEQ_COMPRESSED_1;
|
s->lzma2.sequence = SEQ_COMPRESSED_1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQ_COMPRESSED_1:
|
case SEQ_COMPRESSED_1:
|
||||||
s->lzma2.compressed
|
s->lzma2.compressed += (uint32_t)b->in[b->in_pos++] + 1;
|
||||||
+= (uint32_t)b->in[b->in_pos++] + 1;
|
|
||||||
s->lzma2.sequence = s->lzma2.next_sequence;
|
s->lzma2.sequence = s->lzma2.next_sequence;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1063,26 +1118,24 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
|
|||||||
* the output buffer yet, we may run this loop
|
* the output buffer yet, we may run this loop
|
||||||
* multiple times without changing s->lzma2.sequence.
|
* multiple times without changing s->lzma2.sequence.
|
||||||
*/
|
*/
|
||||||
dict_limit(&s->dict, min_t(size_t,
|
dict_limit(&s->dict,
|
||||||
b->out_size - b->out_pos,
|
min_t(size_t, b->out_size - b->out_pos, s->lzma2.uncompressed));
|
||||||
s->lzma2.uncompressed));
|
|
||||||
if (!lzma2_lzma(s, b))
|
if (!lzma2_lzma(s, b))
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
s->lzma2.uncompressed -= dict_flush(&s->dict, b);
|
s->lzma2.uncompressed -= dict_flush(&s->dict, b);
|
||||||
|
|
||||||
if (s->lzma2.uncompressed == 0) {
|
if (s->lzma2.uncompressed == 0)
|
||||||
if (s->lzma2.compressed > 0 || s->lzma.len > 0
|
{
|
||||||
|| !rc_is_finished(&s->rc))
|
if (s->lzma2.compressed > 0 || s->lzma.len > 0 || !rc_is_finished(&s->rc))
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
rc_reset(&s->rc);
|
rc_reset(&s->rc);
|
||||||
s->lzma2.sequence = SEQ_CONTROL;
|
s->lzma2.sequence = SEQ_CONTROL;
|
||||||
|
}
|
||||||
} else if (b->out_pos == b->out_size
|
else if (b->out_pos == b->out_size ||
|
||||||
|| (b->in_pos == b->in_size
|
(b->in_pos == b->in_size && s->temp.size < s->lzma2.compressed))
|
||||||
&& s->temp.size
|
{
|
||||||
< s->lzma2.compressed)) {
|
|
||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1101,8 +1154,7 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
|
|||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
|
XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode, uint32_t dict_max)
|
||||||
uint32_t dict_max)
|
|
||||||
{
|
{
|
||||||
struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
|
struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
@ -1111,13 +1163,17 @@ XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
|
|||||||
s->dict.mode = mode;
|
s->dict.mode = mode;
|
||||||
s->dict.size_max = dict_max;
|
s->dict.size_max = dict_max;
|
||||||
|
|
||||||
if (DEC_IS_PREALLOC(mode)) {
|
if (DEC_IS_PREALLOC(mode))
|
||||||
|
{
|
||||||
s->dict.buf = vmalloc(dict_max);
|
s->dict.buf = vmalloc(dict_max);
|
||||||
if (s->dict.buf == NULL) {
|
if (s->dict.buf == NULL)
|
||||||
|
{
|
||||||
kfree(s);
|
kfree(s);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else if (DEC_IS_DYNALLOC(mode)) {
|
}
|
||||||
|
else if (DEC_IS_DYNALLOC(mode))
|
||||||
|
{
|
||||||
s->dict.buf = NULL;
|
s->dict.buf = NULL;
|
||||||
s->dict.allocated = 0;
|
s->dict.allocated = 0;
|
||||||
}
|
}
|
||||||
@ -1134,17 +1190,21 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
|
|||||||
s->dict.size = 2 + (props & 1);
|
s->dict.size = 2 + (props & 1);
|
||||||
s->dict.size <<= (props >> 1) + 11;
|
s->dict.size <<= (props >> 1) + 11;
|
||||||
|
|
||||||
if (DEC_IS_MULTI(s->dict.mode)) {
|
if (DEC_IS_MULTI(s->dict.mode))
|
||||||
|
{
|
||||||
if (s->dict.size > s->dict.size_max)
|
if (s->dict.size > s->dict.size_max)
|
||||||
return XZ_MEMLIMIT_ERROR;
|
return XZ_MEMLIMIT_ERROR;
|
||||||
|
|
||||||
s->dict.end = s->dict.size;
|
s->dict.end = s->dict.size;
|
||||||
|
|
||||||
if (DEC_IS_DYNALLOC(s->dict.mode)) {
|
if (DEC_IS_DYNALLOC(s->dict.mode))
|
||||||
if (s->dict.allocated < s->dict.size) {
|
{
|
||||||
|
if (s->dict.allocated < s->dict.size)
|
||||||
|
{
|
||||||
vfree(s->dict.buf);
|
vfree(s->dict.buf);
|
||||||
s->dict.buf = vmalloc(s->dict.size);
|
s->dict.buf = vmalloc(s->dict.size);
|
||||||
if (s->dict.buf == NULL) {
|
if (s->dict.buf == NULL)
|
||||||
|
{
|
||||||
s->dict.allocated = 0;
|
s->dict.allocated = 0;
|
||||||
return XZ_MEM_ERROR;
|
return XZ_MEM_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -11,21 +11,24 @@
|
|||||||
#include "xz_stream.h"
|
#include "xz_stream.h"
|
||||||
|
|
||||||
#ifdef XZ_USE_CRC64
|
#ifdef XZ_USE_CRC64
|
||||||
# define IS_CRC64(check_type) ((check_type) == XZ_CHECK_CRC64)
|
#define IS_CRC64(check_type) ((check_type) == XZ_CHECK_CRC64)
|
||||||
#else
|
#else
|
||||||
# define IS_CRC64(check_type) false
|
#define IS_CRC64(check_type) false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Hash used to validate the Index field */
|
/* Hash used to validate the Index field */
|
||||||
struct xz_dec_hash {
|
struct xz_dec_hash
|
||||||
|
{
|
||||||
vli_type unpadded;
|
vli_type unpadded;
|
||||||
vli_type uncompressed;
|
vli_type uncompressed;
|
||||||
uint32_t crc32;
|
uint32_t crc32;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xz_dec {
|
struct xz_dec
|
||||||
|
{
|
||||||
/* Position in dec_main() */
|
/* Position in dec_main() */
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
SEQ_STREAM_HEADER,
|
SEQ_STREAM_HEADER,
|
||||||
SEQ_BLOCK_START,
|
SEQ_BLOCK_START,
|
||||||
SEQ_BLOCK_HEADER,
|
SEQ_BLOCK_HEADER,
|
||||||
@ -69,7 +72,8 @@ struct xz_dec {
|
|||||||
bool allow_buf_error;
|
bool allow_buf_error;
|
||||||
|
|
||||||
/* Information stored in Block Header */
|
/* Information stored in Block Header */
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Value stored in the Compressed Size field, or
|
* Value stored in the Compressed Size field, or
|
||||||
* VLI_UNKNOWN if Compressed Size is not present.
|
* VLI_UNKNOWN if Compressed Size is not present.
|
||||||
@ -87,7 +91,8 @@ struct xz_dec {
|
|||||||
} block_header;
|
} block_header;
|
||||||
|
|
||||||
/* Information collected when decoding Blocks */
|
/* Information collected when decoding Blocks */
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
/* Observed compressed size of the current Block */
|
/* Observed compressed size of the current Block */
|
||||||
vli_type compressed;
|
vli_type compressed;
|
||||||
|
|
||||||
@ -105,9 +110,11 @@ struct xz_dec {
|
|||||||
} block;
|
} block;
|
||||||
|
|
||||||
/* Variables needed when verifying the Index field */
|
/* Variables needed when verifying the Index field */
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
/* Position in dec_index() */
|
/* Position in dec_index() */
|
||||||
enum {
|
enum
|
||||||
|
{
|
||||||
SEQ_INDEX_COUNT,
|
SEQ_INDEX_COUNT,
|
||||||
SEQ_INDEX_UNPADDED,
|
SEQ_INDEX_UNPADDED,
|
||||||
SEQ_INDEX_UNCOMPRESSED
|
SEQ_INDEX_UNCOMPRESSED
|
||||||
@ -133,7 +140,8 @@ struct xz_dec {
|
|||||||
* to a multiple of four bytes; the size_t variables before it
|
* to a multiple of four bytes; the size_t variables before it
|
||||||
* should guarantee this.
|
* should guarantee this.
|
||||||
*/
|
*/
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
size_t pos;
|
size_t pos;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint8_t buf[1024];
|
uint8_t buf[1024];
|
||||||
@ -149,14 +157,8 @@ struct xz_dec {
|
|||||||
|
|
||||||
#ifdef XZ_DEC_ANY_CHECK
|
#ifdef XZ_DEC_ANY_CHECK
|
||||||
/* Sizes of the Check field with different Check IDs */
|
/* Sizes of the Check field with different Check IDs */
|
||||||
static const uint8_t check_sizes[16] = {
|
static const uint8_t check_sizes[16] = {0, 4, 4, 4, 8, 8, 8, 16,
|
||||||
0,
|
16, 16, 32, 32, 32, 64, 64, 64};
|
||||||
4, 4, 4,
|
|
||||||
8, 8, 8,
|
|
||||||
16, 16, 16,
|
|
||||||
32, 32, 32,
|
|
||||||
64, 64, 64
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -167,14 +169,14 @@ static const uint8_t check_sizes[16] = {
|
|||||||
*/
|
*/
|
||||||
static bool fill_temp(struct xz_dec *s, struct xz_buf *b)
|
static bool fill_temp(struct xz_dec *s, struct xz_buf *b)
|
||||||
{
|
{
|
||||||
size_t copy_size = min_t(size_t,
|
size_t copy_size = min_t(size_t, b->in_size - b->in_pos, s->temp.size - s->temp.pos);
|
||||||
b->in_size - b->in_pos, s->temp.size - s->temp.pos);
|
|
||||||
|
|
||||||
memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
|
memcpy(s->temp.buf + s->temp.pos, b->in + b->in_pos, copy_size);
|
||||||
b->in_pos += copy_size;
|
b->in_pos += copy_size;
|
||||||
s->temp.pos += copy_size;
|
s->temp.pos += copy_size;
|
||||||
|
|
||||||
if (s->temp.pos == s->temp.size) {
|
if (s->temp.pos == s->temp.size)
|
||||||
|
{
|
||||||
s->temp.pos = 0;
|
s->temp.pos = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -183,21 +185,22 @@ static bool fill_temp(struct xz_dec *s, struct xz_buf *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Decode a variable-length integer (little-endian base-128 encoding) */
|
/* Decode a variable-length integer (little-endian base-128 encoding) */
|
||||||
static enum xz_ret dec_vli(struct xz_dec *s, const uint8_t *in,
|
static enum xz_ret dec_vli(struct xz_dec *s, const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||||
size_t *in_pos, size_t in_size)
|
|
||||||
{
|
{
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
|
|
||||||
if (s->pos == 0)
|
if (s->pos == 0)
|
||||||
s->vli = 0;
|
s->vli = 0;
|
||||||
|
|
||||||
while (*in_pos < in_size) {
|
while (*in_pos < in_size)
|
||||||
|
{
|
||||||
byte = in[*in_pos];
|
byte = in[*in_pos];
|
||||||
++*in_pos;
|
++*in_pos;
|
||||||
|
|
||||||
s->vli |= (vli_type)(byte & 0x7F) << s->pos;
|
s->vli |= (vli_type)(byte & 0x7F) << s->pos;
|
||||||
|
|
||||||
if ((byte & 0x80) == 0) {
|
if ((byte & 0x80) == 0)
|
||||||
|
{
|
||||||
/* Don't allow non-minimal encodings. */
|
/* Don't allow non-minimal encodings. */
|
||||||
if (byte == 0 && s->pos != 0)
|
if (byte == 0 && s->pos != 0)
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
@ -247,33 +250,28 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
|
|||||||
* There is no need to separately check for VLI_UNKNOWN, since
|
* There is no need to separately check for VLI_UNKNOWN, since
|
||||||
* the observed sizes are always smaller than VLI_UNKNOWN.
|
* the observed sizes are always smaller than VLI_UNKNOWN.
|
||||||
*/
|
*/
|
||||||
if (s->block.compressed > s->block_header.compressed
|
if (s->block.compressed > s->block_header.compressed ||
|
||||||
|| s->block.uncompressed
|
s->block.uncompressed > s->block_header.uncompressed)
|
||||||
> s->block_header.uncompressed)
|
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
if (s->check_type == XZ_CHECK_CRC32)
|
if (s->check_type == XZ_CHECK_CRC32)
|
||||||
s->crc = xz_crc32(b->out + s->out_start,
|
s->crc = xz_crc32(b->out + s->out_start, b->out_pos - s->out_start, s->crc);
|
||||||
b->out_pos - s->out_start, s->crc);
|
|
||||||
#ifdef XZ_USE_CRC64
|
#ifdef XZ_USE_CRC64
|
||||||
else if (s->check_type == XZ_CHECK_CRC64)
|
else if (s->check_type == XZ_CHECK_CRC64)
|
||||||
s->crc = xz_crc64(b->out + s->out_start,
|
s->crc = xz_crc64(b->out + s->out_start, b->out_pos - s->out_start, s->crc);
|
||||||
b->out_pos - s->out_start, s->crc);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ret == XZ_STREAM_END) {
|
if (ret == XZ_STREAM_END)
|
||||||
if (s->block_header.compressed != VLI_UNKNOWN
|
{
|
||||||
&& s->block_header.compressed
|
if (s->block_header.compressed != VLI_UNKNOWN &&
|
||||||
!= s->block.compressed)
|
s->block_header.compressed != s->block.compressed)
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
if (s->block_header.uncompressed != VLI_UNKNOWN
|
if (s->block_header.uncompressed != VLI_UNKNOWN &&
|
||||||
&& s->block_header.uncompressed
|
s->block_header.uncompressed != s->block.uncompressed)
|
||||||
!= s->block.uncompressed)
|
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
s->block.hash.unpadded += s->block_header.size
|
s->block.hash.unpadded += s->block_header.size + s->block.compressed;
|
||||||
+ s->block.compressed;
|
|
||||||
|
|
||||||
#ifdef XZ_DEC_ANY_CHECK
|
#ifdef XZ_DEC_ANY_CHECK
|
||||||
s->block.hash.unpadded += check_sizes[s->check_type];
|
s->block.hash.unpadded += check_sizes[s->check_type];
|
||||||
@ -285,9 +283,8 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->block.hash.uncompressed += s->block.uncompressed;
|
s->block.hash.uncompressed += s->block.uncompressed;
|
||||||
s->block.hash.crc32 = xz_crc32(
|
s->block.hash.crc32 = xz_crc32((const uint8_t *)&s->block.hash, sizeof(s->block.hash),
|
||||||
(const uint8_t *)&s->block.hash,
|
s->block.hash.crc32);
|
||||||
sizeof(s->block.hash), s->block.hash.crc32);
|
|
||||||
|
|
||||||
++s->block.count;
|
++s->block.count;
|
||||||
}
|
}
|
||||||
@ -315,14 +312,17 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
|
|||||||
{
|
{
|
||||||
enum xz_ret ret;
|
enum xz_ret ret;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
|
ret = dec_vli(s, b->in, &b->in_pos, b->in_size);
|
||||||
if (ret != XZ_STREAM_END) {
|
if (ret != XZ_STREAM_END)
|
||||||
|
{
|
||||||
index_update(s, b);
|
index_update(s, b);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (s->index.sequence) {
|
switch (s->index.sequence)
|
||||||
|
{
|
||||||
case SEQ_INDEX_COUNT:
|
case SEQ_INDEX_COUNT:
|
||||||
s->index.count = s->vli;
|
s->index.count = s->vli;
|
||||||
|
|
||||||
@ -344,10 +344,8 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
|
|||||||
|
|
||||||
case SEQ_INDEX_UNCOMPRESSED:
|
case SEQ_INDEX_UNCOMPRESSED:
|
||||||
s->index.hash.uncompressed += s->vli;
|
s->index.hash.uncompressed += s->vli;
|
||||||
s->index.hash.crc32 = xz_crc32(
|
s->index.hash.crc32 = xz_crc32((const uint8_t *)&s->index.hash,
|
||||||
(const uint8_t *)&s->index.hash,
|
sizeof(s->index.hash), s->index.hash.crc32);
|
||||||
sizeof(s->index.hash),
|
|
||||||
s->index.hash.crc32);
|
|
||||||
--s->index.count;
|
--s->index.count;
|
||||||
s->index.sequence = SEQ_INDEX_UNPADDED;
|
s->index.sequence = SEQ_INDEX_UNPADDED;
|
||||||
break;
|
break;
|
||||||
@ -362,10 +360,10 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
|
|||||||
* of s->crc. s->pos must be zero when starting to validate the first byte.
|
* of s->crc. s->pos must be zero when starting to validate the first byte.
|
||||||
* The "bits" argument allows using the same code for both CRC32 and CRC64.
|
* The "bits" argument allows using the same code for both CRC32 and CRC64.
|
||||||
*/
|
*/
|
||||||
static enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b,
|
static enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b, uint32_t bits)
|
||||||
uint32_t bits)
|
|
||||||
{
|
{
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
if (b->in_pos == b->in_size)
|
if (b->in_pos == b->in_size)
|
||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
|
|
||||||
@ -389,7 +387,8 @@ static enum xz_ret crc_validate(struct xz_dec *s, struct xz_buf *b,
|
|||||||
*/
|
*/
|
||||||
static bool check_skip(struct xz_dec *s, struct xz_buf *b)
|
static bool check_skip(struct xz_dec *s, struct xz_buf *b)
|
||||||
{
|
{
|
||||||
while (s->pos < check_sizes[s->check_type]) {
|
while (s->pos < check_sizes[s->check_type])
|
||||||
|
{
|
||||||
if (b->in_pos == b->in_size)
|
if (b->in_pos == b->in_size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -409,8 +408,8 @@ static enum xz_ret dec_stream_header(struct xz_dec *s)
|
|||||||
if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
|
if (!memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
|
||||||
return XZ_FORMAT_ERROR;
|
return XZ_FORMAT_ERROR;
|
||||||
|
|
||||||
if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0)
|
if (xz_crc32(s->temp.buf + HEADER_MAGIC_SIZE, 2, 0) !=
|
||||||
!= get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
|
get_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2))
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
|
if (s->temp.buf[HEADER_MAGIC_SIZE] != 0)
|
||||||
@ -476,49 +475,53 @@ static enum xz_ret dec_block_header(struct xz_dec *s)
|
|||||||
* eight bytes so this is safe.
|
* eight bytes so this is safe.
|
||||||
*/
|
*/
|
||||||
s->temp.size -= 4;
|
s->temp.size -= 4;
|
||||||
if (xz_crc32(s->temp.buf, s->temp.size, 0)
|
if (xz_crc32(s->temp.buf, s->temp.size, 0) != get_le32(s->temp.buf + s->temp.size))
|
||||||
!= get_le32(s->temp.buf + s->temp.size))
|
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
s->temp.pos = 2;
|
s->temp.pos = 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Catch unsupported Block Flags. We support only one or two filters
|
* Catch unsupported Block Flags. We support only one or two filters
|
||||||
* in the chain, so we catch that with the same test.
|
* in the chain, so we catch that with the same test.
|
||||||
*/
|
*/
|
||||||
#ifdef XZ_DEC_BCJ
|
#ifdef XZ_DEC_BCJ
|
||||||
if (s->temp.buf[1] & 0x3E)
|
if (s->temp.buf[1] & 0x3E)
|
||||||
#else
|
#else
|
||||||
if (s->temp.buf[1] & 0x3F)
|
if (s->temp.buf[1] & 0x3F)
|
||||||
#endif
|
#endif
|
||||||
return XZ_OPTIONS_ERROR;
|
return XZ_OPTIONS_ERROR;
|
||||||
|
|
||||||
/* Compressed Size */
|
/* Compressed Size */
|
||||||
if (s->temp.buf[1] & 0x40) {
|
if (s->temp.buf[1] & 0x40)
|
||||||
if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
|
{
|
||||||
!= XZ_STREAM_END)
|
if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) != XZ_STREAM_END)
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
s->block_header.compressed = s->vli;
|
s->block_header.compressed = s->vli;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
s->block_header.compressed = VLI_UNKNOWN;
|
s->block_header.compressed = VLI_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Uncompressed Size */
|
/* Uncompressed Size */
|
||||||
if (s->temp.buf[1] & 0x80) {
|
if (s->temp.buf[1] & 0x80)
|
||||||
if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size)
|
{
|
||||||
!= XZ_STREAM_END)
|
if (dec_vli(s, s->temp.buf, &s->temp.pos, s->temp.size) != XZ_STREAM_END)
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
s->block_header.uncompressed = s->vli;
|
s->block_header.uncompressed = s->vli;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
s->block_header.uncompressed = VLI_UNKNOWN;
|
s->block_header.uncompressed = VLI_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XZ_DEC_BCJ
|
#ifdef XZ_DEC_BCJ
|
||||||
/* If there are two filters, the first one must be a BCJ filter. */
|
/* If there are two filters, the first one must be a BCJ filter. */
|
||||||
s->bcj_active = s->temp.buf[1] & 0x01;
|
s->bcj_active = s->temp.buf[1] & 0x01;
|
||||||
if (s->bcj_active) {
|
if (s->bcj_active)
|
||||||
|
{
|
||||||
if (s->temp.size - s->temp.pos < 2)
|
if (s->temp.size - s->temp.pos < 2)
|
||||||
return XZ_OPTIONS_ERROR;
|
return XZ_OPTIONS_ERROR;
|
||||||
|
|
||||||
@ -577,8 +580,10 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||||||
*/
|
*/
|
||||||
s->in_start = b->in_pos;
|
s->in_start = b->in_pos;
|
||||||
|
|
||||||
while (true) {
|
while (true)
|
||||||
switch (s->sequence) {
|
{
|
||||||
|
switch (s->sequence)
|
||||||
|
{
|
||||||
case SEQ_STREAM_HEADER:
|
case SEQ_STREAM_HEADER:
|
||||||
/*
|
/*
|
||||||
* Stream Header is copied to s->temp, and then
|
* Stream Header is copied to s->temp, and then
|
||||||
@ -610,7 +615,8 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
|
|
||||||
/* See if this is the beginning of the Index field. */
|
/* See if this is the beginning of the Index field. */
|
||||||
if (b->in[b->in_pos] == 0) {
|
if (b->in[b->in_pos] == 0)
|
||||||
|
{
|
||||||
s->in_start = b->in_pos++;
|
s->in_start = b->in_pos++;
|
||||||
s->sequence = SEQ_INDEX;
|
s->sequence = SEQ_INDEX;
|
||||||
break;
|
break;
|
||||||
@ -620,8 +626,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||||||
* Calculate the size of the Block Header and
|
* Calculate the size of the Block Header and
|
||||||
* prepare to decode it.
|
* prepare to decode it.
|
||||||
*/
|
*/
|
||||||
s->block_header.size
|
s->block_header.size = ((uint32_t)b->in[b->in_pos] + 1) * 4;
|
||||||
= ((uint32_t)b->in[b->in_pos] + 1) * 4;
|
|
||||||
|
|
||||||
s->temp.size = s->block_header.size;
|
s->temp.size = s->block_header.size;
|
||||||
s->temp.pos = 0;
|
s->temp.pos = 0;
|
||||||
@ -652,7 +657,8 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||||||
* anymore, so we use it here to test the size
|
* anymore, so we use it here to test the size
|
||||||
* of the Block Padding field.
|
* of the Block Padding field.
|
||||||
*/
|
*/
|
||||||
while (s->block.compressed & 3) {
|
while (s->block.compressed & 3)
|
||||||
|
{
|
||||||
if (b->in_pos == b->in_size)
|
if (b->in_pos == b->in_size)
|
||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
|
|
||||||
@ -665,18 +671,21 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||||||
s->sequence = SEQ_BLOCK_CHECK;
|
s->sequence = SEQ_BLOCK_CHECK;
|
||||||
|
|
||||||
case SEQ_BLOCK_CHECK:
|
case SEQ_BLOCK_CHECK:
|
||||||
if (s->check_type == XZ_CHECK_CRC32) {
|
if (s->check_type == XZ_CHECK_CRC32)
|
||||||
|
{
|
||||||
ret = crc_validate(s, b, 32);
|
ret = crc_validate(s, b, 32);
|
||||||
if (ret != XZ_STREAM_END)
|
if (ret != XZ_STREAM_END)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else if (IS_CRC64(s->check_type)) {
|
else if (IS_CRC64(s->check_type))
|
||||||
|
{
|
||||||
ret = crc_validate(s, b, 64);
|
ret = crc_validate(s, b, 64);
|
||||||
if (ret != XZ_STREAM_END)
|
if (ret != XZ_STREAM_END)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#ifdef XZ_DEC_ANY_CHECK
|
#ifdef XZ_DEC_ANY_CHECK
|
||||||
else if (!check_skip(s, b)) {
|
else if (!check_skip(s, b))
|
||||||
|
{
|
||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -692,9 +701,10 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||||||
s->sequence = SEQ_INDEX_PADDING;
|
s->sequence = SEQ_INDEX_PADDING;
|
||||||
|
|
||||||
case SEQ_INDEX_PADDING:
|
case SEQ_INDEX_PADDING:
|
||||||
while ((s->index.size + (b->in_pos - s->in_start))
|
while ((s->index.size + (b->in_pos - s->in_start)) & 3)
|
||||||
& 3) {
|
{
|
||||||
if (b->in_pos == b->in_size) {
|
if (b->in_pos == b->in_size)
|
||||||
|
{
|
||||||
index_update(s, b);
|
index_update(s, b);
|
||||||
return XZ_OK;
|
return XZ_OK;
|
||||||
}
|
}
|
||||||
@ -707,8 +717,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||||||
index_update(s, b);
|
index_update(s, b);
|
||||||
|
|
||||||
/* Compare the hashes to validate the Index field. */
|
/* Compare the hashes to validate the Index field. */
|
||||||
if (!memeq(&s->block.hash, &s->index.hash,
|
if (!memeq(&s->block.hash, &s->index.hash, sizeof(s->block.hash)))
|
||||||
sizeof(s->block.hash)))
|
|
||||||
return XZ_DATA_ERROR;
|
return XZ_DATA_ERROR;
|
||||||
|
|
||||||
s->sequence = SEQ_INDEX_CRC32;
|
s->sequence = SEQ_INDEX_CRC32;
|
||||||
@ -770,23 +779,26 @@ XZ_EXTERN enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b)
|
|||||||
out_start = b->out_pos;
|
out_start = b->out_pos;
|
||||||
ret = dec_main(s, b);
|
ret = dec_main(s, b);
|
||||||
|
|
||||||
if (DEC_IS_SINGLE(s->mode)) {
|
if (DEC_IS_SINGLE(s->mode))
|
||||||
|
{
|
||||||
if (ret == XZ_OK)
|
if (ret == XZ_OK)
|
||||||
ret = b->in_pos == b->in_size
|
ret = b->in_pos == b->in_size ? XZ_DATA_ERROR : XZ_BUF_ERROR;
|
||||||
? XZ_DATA_ERROR : XZ_BUF_ERROR;
|
|
||||||
|
|
||||||
if (ret != XZ_STREAM_END) {
|
if (ret != XZ_STREAM_END)
|
||||||
|
{
|
||||||
b->in_pos = in_start;
|
b->in_pos = in_start;
|
||||||
b->out_pos = out_start;
|
b->out_pos = out_start;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (ret == XZ_OK && in_start == b->in_pos
|
else if (ret == XZ_OK && in_start == b->in_pos && out_start == b->out_pos)
|
||||||
&& out_start == b->out_pos) {
|
{
|
||||||
if (s->allow_buf_error)
|
if (s->allow_buf_error)
|
||||||
ret = XZ_BUF_ERROR;
|
ret = XZ_BUF_ERROR;
|
||||||
|
|
||||||
s->allow_buf_error = true;
|
s->allow_buf_error = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
s->allow_buf_error = false;
|
s->allow_buf_error = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,7 +849,8 @@ XZ_EXTERN void xz_dec_reset(struct xz_dec *s)
|
|||||||
|
|
||||||
XZ_EXTERN void xz_dec_end(struct xz_dec *s)
|
XZ_EXTERN void xz_dec_end(struct xz_dec *s)
|
||||||
{
|
{
|
||||||
if (s != NULL) {
|
if (s != NULL)
|
||||||
|
{
|
||||||
xz_dec_lzma2_end(s->lzma2);
|
xz_dec_lzma2_end(s->lzma2);
|
||||||
#ifdef XZ_DEC_BCJ
|
#ifdef XZ_DEC_BCJ
|
||||||
xz_dec_bcj_end(s->bcj);
|
xz_dec_bcj_end(s->bcj);
|
||||||
|
@ -39,7 +39,8 @@
|
|||||||
* The symbol names are in from STATE_oldest_older_previous. REP means
|
* The symbol names are in from STATE_oldest_older_previous. REP means
|
||||||
* either short or long repeated match, and NONLIT means any non-literal.
|
* either short or long repeated match, and NONLIT means any non-literal.
|
||||||
*/
|
*/
|
||||||
enum lzma_state {
|
enum lzma_state
|
||||||
|
{
|
||||||
STATE_LIT_LIT,
|
STATE_LIT_LIT,
|
||||||
STATE_MATCH_LIT_LIT,
|
STATE_MATCH_LIT_LIT,
|
||||||
STATE_REP_LIT_LIT,
|
STATE_REP_LIT_LIT,
|
||||||
@ -146,8 +147,7 @@ static inline bool lzma_state_is_literal(enum lzma_state state)
|
|||||||
*/
|
*/
|
||||||
static inline uint32_t lzma_get_dist_state(uint32_t len)
|
static inline uint32_t lzma_get_dist_state(uint32_t len)
|
||||||
{
|
{
|
||||||
return len < DIST_STATES + MATCH_LEN_MIN
|
return len < DIST_STATES + MATCH_LEN_MIN ? len - MATCH_LEN_MIN : DIST_STATES - 1;
|
||||||
? len - MATCH_LEN_MIN : DIST_STATES - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -192,7 +192,7 @@ static inline uint32_t lzma_get_dist_state(uint32_t len)
|
|||||||
#define ALIGN_MASK (ALIGN_SIZE - 1)
|
#define ALIGN_MASK (ALIGN_SIZE - 1)
|
||||||
|
|
||||||
/* Total number of all probability variables */
|
/* Total number of all probability variables */
|
||||||
#define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX * LITERAL_CODER_SIZE)
|
#define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX *LITERAL_CODER_SIZE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LZMA remembers the four most recent match distances. Reusing these
|
* LZMA remembers the four most recent match distances. Reusing these
|
||||||
|
@ -11,51 +11,50 @@
|
|||||||
#define XZ_PRIVATE_H
|
#define XZ_PRIVATE_H
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
# include <linux/xz.h>
|
#include <linux/xz.h>
|
||||||
# include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
# include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
/* XZ_PREBOOT may be defined only via decompress_unxz.c. */
|
/* XZ_PREBOOT may be defined only via decompress_unxz.c. */
|
||||||
# ifndef XZ_PREBOOT
|
#ifndef XZ_PREBOOT
|
||||||
# include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
# include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
# include <linux/string.h>
|
#include <linux/string.h>
|
||||||
# ifdef CONFIG_XZ_DEC_X86
|
#ifdef CONFIG_XZ_DEC_X86
|
||||||
# define XZ_DEC_X86
|
#define XZ_DEC_X86
|
||||||
# endif
|
#endif
|
||||||
# ifdef CONFIG_XZ_DEC_POWERPC
|
#ifdef CONFIG_XZ_DEC_POWERPC
|
||||||
# define XZ_DEC_POWERPC
|
#define XZ_DEC_POWERPC
|
||||||
# endif
|
#endif
|
||||||
# ifdef CONFIG_XZ_DEC_IA64
|
#ifdef CONFIG_XZ_DEC_IA64
|
||||||
# define XZ_DEC_IA64
|
#define XZ_DEC_IA64
|
||||||
# endif
|
#endif
|
||||||
# ifdef CONFIG_XZ_DEC_ARM
|
#ifdef CONFIG_XZ_DEC_ARM
|
||||||
# define XZ_DEC_ARM
|
#define XZ_DEC_ARM
|
||||||
# endif
|
#endif
|
||||||
# ifdef CONFIG_XZ_DEC_ARMTHUMB
|
#ifdef CONFIG_XZ_DEC_ARMTHUMB
|
||||||
# define XZ_DEC_ARMTHUMB
|
#define XZ_DEC_ARMTHUMB
|
||||||
# endif
|
#endif
|
||||||
# ifdef CONFIG_XZ_DEC_SPARC
|
#ifdef CONFIG_XZ_DEC_SPARC
|
||||||
# define XZ_DEC_SPARC
|
#define XZ_DEC_SPARC
|
||||||
# endif
|
#endif
|
||||||
# define memeq(a, b, size) (memcmp(a, b, size) == 0)
|
#define memeq(a, b, size) (memcmp(a, b, size) == 0)
|
||||||
# define memzero(buf, size) memset(buf, 0, size)
|
#define memzero(buf, size) memset(buf, 0, size)
|
||||||
# endif
|
#endif
|
||||||
# define get_le32(p) le32_to_cpup((const uint32_t *)(p))
|
#define get_le32(p) le32_to_cpup((const uint32_t *)(p))
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* For userspace builds, use a separate header to define the required
|
* For userspace builds, use a separate header to define the required
|
||||||
* macros and functions. This makes it easier to adapt the code into
|
* macros and functions. This makes it easier to adapt the code into
|
||||||
* different environments and avoids clutter in the Linux kernel tree.
|
* different environments and avoids clutter in the Linux kernel tree.
|
||||||
*/
|
*/
|
||||||
# include "xz_config.h"
|
#include "xz_config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If no specific decoding mode is requested, enable support for all modes. */
|
/* If no specific decoding mode is requested, enable support for all modes. */
|
||||||
#if !defined(XZ_DEC_SINGLE) && !defined(XZ_DEC_PREALLOC) \
|
#if !defined(XZ_DEC_SINGLE) && !defined(XZ_DEC_PREALLOC) && !defined(XZ_DEC_DYNALLOC)
|
||||||
&& !defined(XZ_DEC_DYNALLOC)
|
#define XZ_DEC_SINGLE
|
||||||
# define XZ_DEC_SINGLE
|
#define XZ_DEC_PREALLOC
|
||||||
# define XZ_DEC_PREALLOC
|
#define XZ_DEC_DYNALLOC
|
||||||
# define XZ_DEC_DYNALLOC
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -64,29 +63,29 @@
|
|||||||
* false at compile time and thus allow the compiler to omit unneeded code.
|
* false at compile time and thus allow the compiler to omit unneeded code.
|
||||||
*/
|
*/
|
||||||
#ifdef XZ_DEC_SINGLE
|
#ifdef XZ_DEC_SINGLE
|
||||||
# define DEC_IS_SINGLE(mode) ((mode) == XZ_SINGLE)
|
#define DEC_IS_SINGLE(mode) ((mode) == XZ_SINGLE)
|
||||||
#else
|
#else
|
||||||
# define DEC_IS_SINGLE(mode) (false)
|
#define DEC_IS_SINGLE(mode) (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XZ_DEC_PREALLOC
|
#ifdef XZ_DEC_PREALLOC
|
||||||
# define DEC_IS_PREALLOC(mode) ((mode) == XZ_PREALLOC)
|
#define DEC_IS_PREALLOC(mode) ((mode) == XZ_PREALLOC)
|
||||||
#else
|
#else
|
||||||
# define DEC_IS_PREALLOC(mode) (false)
|
#define DEC_IS_PREALLOC(mode) (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XZ_DEC_DYNALLOC
|
#ifdef XZ_DEC_DYNALLOC
|
||||||
# define DEC_IS_DYNALLOC(mode) ((mode) == XZ_DYNALLOC)
|
#define DEC_IS_DYNALLOC(mode) ((mode) == XZ_DYNALLOC)
|
||||||
#else
|
#else
|
||||||
# define DEC_IS_DYNALLOC(mode) (false)
|
#define DEC_IS_DYNALLOC(mode) (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(XZ_DEC_SINGLE)
|
#if !defined(XZ_DEC_SINGLE)
|
||||||
# define DEC_IS_MULTI(mode) (true)
|
#define DEC_IS_MULTI(mode) (true)
|
||||||
#elif defined(XZ_DEC_PREALLOC) || defined(XZ_DEC_DYNALLOC)
|
#elif defined(XZ_DEC_PREALLOC) || defined(XZ_DEC_DYNALLOC)
|
||||||
# define DEC_IS_MULTI(mode) ((mode) != XZ_SINGLE)
|
#define DEC_IS_MULTI(mode) ((mode) != XZ_SINGLE)
|
||||||
#else
|
#else
|
||||||
# define DEC_IS_MULTI(mode) (false)
|
#define DEC_IS_MULTI(mode) (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -94,20 +93,18 @@
|
|||||||
* XZ_DEC_BCJ is used to enable generic support for BCJ decoders.
|
* XZ_DEC_BCJ is used to enable generic support for BCJ decoders.
|
||||||
*/
|
*/
|
||||||
#ifndef XZ_DEC_BCJ
|
#ifndef XZ_DEC_BCJ
|
||||||
# if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \
|
#if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) || defined(XZ_DEC_IA64) || \
|
||||||
|| defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \
|
defined(XZ_DEC_ARM) || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) || \
|
||||||
|| defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \
|
defined(XZ_DEC_SPARC)
|
||||||
|| defined(XZ_DEC_SPARC)
|
#define XZ_DEC_BCJ
|
||||||
# define XZ_DEC_BCJ
|
#endif
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used
|
* Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used
|
||||||
* before calling xz_dec_lzma2_run().
|
* before calling xz_dec_lzma2_run().
|
||||||
*/
|
*/
|
||||||
XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
|
XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode, uint32_t dict_max);
|
||||||
uint32_t dict_max);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode the LZMA2 properties (one byte) and reset the decoder. Return
|
* Decode the LZMA2 properties (one byte) and reset the decoder. Return
|
||||||
@ -115,12 +112,10 @@ XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
|
|||||||
* big enough, and XZ_OPTIONS_ERROR if props indicates something that this
|
* big enough, and XZ_OPTIONS_ERROR if props indicates something that this
|
||||||
* decoder doesn't support.
|
* decoder doesn't support.
|
||||||
*/
|
*/
|
||||||
XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s,
|
XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props);
|
||||||
uint8_t props);
|
|
||||||
|
|
||||||
/* Decode raw LZMA2 stream from b->in to b->out. */
|
/* Decode raw LZMA2 stream from b->in to b->out. */
|
||||||
XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
|
XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, struct xz_buf *b);
|
||||||
struct xz_buf *b);
|
|
||||||
|
|
||||||
/* Free the memory allocated for the LZMA2 decoder. */
|
/* Free the memory allocated for the LZMA2 decoder. */
|
||||||
XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s);
|
XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s);
|
||||||
@ -145,9 +140,8 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id);
|
|||||||
* a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run()
|
* a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run()
|
||||||
* must be called directly.
|
* must be called directly.
|
||||||
*/
|
*/
|
||||||
XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
|
XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2,
|
||||||
struct xz_dec_lzma2 *lzma2,
|
struct xz_buf *b);
|
||||||
struct xz_buf *b);
|
|
||||||
|
|
||||||
/* Free the memory allocated for the BCJ filters. */
|
/* Free the memory allocated for the BCJ filters. */
|
||||||
#define xz_dec_bcj_end(s) kfree(s)
|
#define xz_dec_bcj_end(s) kfree(s)
|
||||||
|
@ -11,10 +11,9 @@
|
|||||||
#define XZ_STREAM_H
|
#define XZ_STREAM_H
|
||||||
|
|
||||||
#if defined(__KERNEL__) && !XZ_INTERNAL_CRC32
|
#if defined(__KERNEL__) && !XZ_INTERNAL_CRC32
|
||||||
# include <linux/crc32.h>
|
#include <linux/crc32.h>
|
||||||
# undef crc32
|
#undef crc32
|
||||||
# define xz_crc32(buf, size, crc) \
|
#define xz_crc32(buf, size, crc) (~crc32_le(~(uint32_t)(crc), buf, size))
|
||||||
(~crc32_le(~(uint32_t)(crc), buf, size))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -42,14 +41,15 @@
|
|||||||
*/
|
*/
|
||||||
typedef uint64_t vli_type;
|
typedef uint64_t vli_type;
|
||||||
|
|
||||||
#define VLI_MAX ((vli_type)-1 / 2)
|
#define VLI_MAX ((vli_type) - 1 / 2)
|
||||||
#define VLI_UNKNOWN ((vli_type)-1)
|
#define VLI_UNKNOWN ((vli_type) - 1)
|
||||||
|
|
||||||
/* Maximum encoded size of a VLI */
|
/* Maximum encoded size of a VLI */
|
||||||
#define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7)
|
#define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7)
|
||||||
|
|
||||||
/* Integrity Check types */
|
/* Integrity Check types */
|
||||||
enum xz_check {
|
enum xz_check
|
||||||
|
{
|
||||||
XZ_CHECK_NONE = 0,
|
XZ_CHECK_NONE = 0,
|
||||||
XZ_CHECK_CRC32 = 1,
|
XZ_CHECK_CRC32 = 1,
|
||||||
XZ_CHECK_CRC64 = 4,
|
XZ_CHECK_CRC64 = 4,
|
||||||
|
@ -29,10 +29,11 @@ int main(int argc, char **argv)
|
|||||||
enum xz_ret ret;
|
enum xz_ret ret;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
|
||||||
if (argc >= 2 && strcmp(argv[1], "--help") == 0) {
|
if (argc >= 2 && strcmp(argv[1], "--help") == 0)
|
||||||
|
{
|
||||||
fputs("Uncompress a .xz file from stdin to stdout.\n"
|
fputs("Uncompress a .xz file from stdin to stdout.\n"
|
||||||
"Arguments other than `--help' are ignored.\n",
|
"Arguments other than `--help' are ignored.\n",
|
||||||
stdout);
|
stdout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +47,8 @@ int main(int argc, char **argv)
|
|||||||
* is allocated once the headers have been parsed.
|
* is allocated once the headers have been parsed.
|
||||||
*/
|
*/
|
||||||
s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
|
s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
|
||||||
if (s == NULL) {
|
if (s == NULL)
|
||||||
|
{
|
||||||
msg = "Memory allocation failed\n";
|
msg = "Memory allocation failed\n";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -58,16 +60,20 @@ int main(int argc, char **argv)
|
|||||||
b.out_pos = 0;
|
b.out_pos = 0;
|
||||||
b.out_size = BUFSIZ;
|
b.out_size = BUFSIZ;
|
||||||
|
|
||||||
while (true) {
|
while (true)
|
||||||
if (b.in_pos == b.in_size) {
|
{
|
||||||
|
if (b.in_pos == b.in_size)
|
||||||
|
{
|
||||||
b.in_size = fread(in, 1, sizeof(in), stdin);
|
b.in_size = fread(in, 1, sizeof(in), stdin);
|
||||||
b.in_pos = 0;
|
b.in_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = xz_dec_run(s, &b);
|
ret = xz_dec_run(s, &b);
|
||||||
|
|
||||||
if (b.out_pos == sizeof(out)) {
|
if (b.out_pos == sizeof(out))
|
||||||
if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
|
{
|
||||||
|
if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos)
|
||||||
|
{
|
||||||
msg = "Write error\n";
|
msg = "Write error\n";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -79,22 +85,25 @@ int main(int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
#ifdef XZ_DEC_ANY_CHECK
|
#ifdef XZ_DEC_ANY_CHECK
|
||||||
if (ret == XZ_UNSUPPORTED_CHECK) {
|
if (ret == XZ_UNSUPPORTED_CHECK)
|
||||||
|
{
|
||||||
fputs(argv[0], stderr);
|
fputs(argv[0], stderr);
|
||||||
fputs(": ", stderr);
|
fputs(": ", stderr);
|
||||||
fputs("Unsupported check; not verifying "
|
fputs("Unsupported check; not verifying "
|
||||||
"file integrity\n", stderr);
|
"file integrity\n",
|
||||||
|
stderr);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos
|
if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos || fclose(stdout))
|
||||||
|| fclose(stdout)) {
|
{
|
||||||
msg = "Write error\n";
|
msg = "Write error\n";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret)
|
||||||
|
{
|
||||||
case XZ_STREAM_END:
|
case XZ_STREAM_END:
|
||||||
xz_dec_end(s);
|
xz_dec_end(s);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,11 +1,26 @@
|
|||||||
#include "consolewindow.h"
|
/* Copyright 2013 MultiMC Contributors
|
||||||
#include "ui_consolewindow.h"
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ConsoleWindow.h"
|
||||||
|
#include "ui_ConsoleWindow.h"
|
||||||
|
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include <gui/platform.h>
|
#include <gui/Platform.h>
|
||||||
#include <gui/CustomMessageBox.h>
|
#include <gui/dialogs/CustomMessageBox.h>
|
||||||
|
|
||||||
ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent) :
|
ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
@ -1,10 +1,25 @@
|
|||||||
#ifndef CONSOLEWINDOW_H
|
/* Copyright 2013 MultiMC Contributors
|
||||||
#define CONSOLEWINDOW_H
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "logic/MinecraftProcess.h"
|
#include "logic/MinecraftProcess.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class ConsoleWindow;
|
class ConsoleWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,14 +38,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setMayClose(bool mayclose);
|
void setMayClose(bool mayclose);
|
||||||
|
|
||||||
public slots:
|
public
|
||||||
|
slots:
|
||||||
/**
|
/**
|
||||||
* @brief write a string
|
* @brief write a string
|
||||||
* @param data the string
|
* @param data the string
|
||||||
* @param mode the WriteMode
|
* @param mode the WriteMode
|
||||||
* lines have to be put through this as a whole!
|
* lines have to be put through this as a whole!
|
||||||
*/
|
*/
|
||||||
void write(QString data, MessageLevel::Enum level=MessageLevel::MultiMC);
|
void write(QString data, MessageLevel::Enum level = MessageLevel::MultiMC);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief write a colored paragraph
|
* @brief write a colored paragraph
|
||||||
@ -39,14 +55,15 @@ public slots:
|
|||||||
* this will only insert a single paragraph.
|
* this will only insert a single paragraph.
|
||||||
* \n are ignored. a real \n is always appended.
|
* \n are ignored. a real \n is always appended.
|
||||||
*/
|
*/
|
||||||
void writeColor(QString data, const char *color=nullptr);
|
void writeColor(QString data, const char *color = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief clear the text widget
|
* @brief clear the text widget
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private slots:
|
private
|
||||||
|
slots:
|
||||||
void on_closeButton_clicked();
|
void on_closeButton_clicked();
|
||||||
void on_btnKillMinecraft_clicked();
|
void on_btnKillMinecraft_clicked();
|
||||||
void onEnded(BaseInstance *instance);
|
void onEnded(BaseInstance *instance);
|
||||||
@ -60,4 +77,3 @@ private:
|
|||||||
bool m_mayclose;
|
bool m_mayclose;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONSOLEWINDOW_H
|
|
@ -1,19 +0,0 @@
|
|||||||
#include "CustomMessageBox.h"
|
|
||||||
|
|
||||||
namespace CustomMessageBox
|
|
||||||
{
|
|
||||||
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
|
|
||||||
QMessageBox::Icon icon, QMessageBox::StandardButtons buttons,
|
|
||||||
QMessageBox::StandardButton defaultButton)
|
|
||||||
{
|
|
||||||
QMessageBox *messageBox = new QMessageBox(parent);
|
|
||||||
messageBox->setWindowTitle(title);
|
|
||||||
messageBox->setText(text);
|
|
||||||
messageBox->setStandardButtons(buttons);
|
|
||||||
messageBox->setDefaultButton(defaultButton);
|
|
||||||
messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
|
||||||
messageBox->setIcon(icon);
|
|
||||||
|
|
||||||
return messageBox;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
namespace CustomMessageBox
|
|
||||||
{
|
|
||||||
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
|
|
||||||
QMessageBox::Icon icon = QMessageBox::NoIcon,
|
|
||||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
|
||||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
#include "EditNotesDialog.h"
|
|
||||||
#include "ui_EditNotesDialog.h"
|
|
||||||
#include "gui/platform.h"
|
|
||||||
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
EditNotesDialog::EditNotesDialog( QString notes, QString name, QWidget* parent ) :
|
|
||||||
m_instance_notes(notes),
|
|
||||||
m_instance_name(name),
|
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::EditNotesDialog)
|
|
||||||
{
|
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->noteEditor->setText(notes);
|
|
||||||
setWindowTitle(tr("Edit notes of %1").arg(m_instance_name));
|
|
||||||
//connect(ui->closeButton, SIGNAL(clicked()), SLOT(close()));
|
|
||||||
}
|
|
||||||
|
|
||||||
EditNotesDialog::~EditNotesDialog()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString EditNotesDialog::getText()
|
|
||||||
{
|
|
||||||
return ui->noteEditor->toPlainText();
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class EditNotesDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class EditNotesDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit EditNotesDialog(QString notes, QString name, QWidget *parent = 0);
|
|
||||||
~EditNotesDialog();
|
|
||||||
QString getText();
|
|
||||||
private:
|
|
||||||
Ui::EditNotesDialog *ui;
|
|
||||||
QString m_instance_name;
|
|
||||||
QString m_instance_notes;
|
|
||||||
};
|
|
@ -1,147 +0,0 @@
|
|||||||
#include <MultiMC.h>
|
|
||||||
#include "IconPickerDialog.h"
|
|
||||||
#include "instancedelegate.h"
|
|
||||||
#include "ui_IconPickerDialog.h"
|
|
||||||
#include "logic/lists/IconList.h"
|
|
||||||
#include "gui/platform.h"
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QFileDialog>
|
|
||||||
|
|
||||||
IconPickerDialog::IconPickerDialog(QWidget *parent) :
|
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::IconPickerDialog)
|
|
||||||
{
|
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
|
||||||
ui->setupUi(this);
|
|
||||||
setWindowModality(Qt::WindowModal);
|
|
||||||
|
|
||||||
auto contentsWidget = ui->iconView;
|
|
||||||
contentsWidget->setViewMode(QListView::IconMode);
|
|
||||||
contentsWidget->setFlow(QListView::LeftToRight);
|
|
||||||
contentsWidget->setIconSize(QSize(48, 48));
|
|
||||||
contentsWidget->setMovement(QListView::Static);
|
|
||||||
contentsWidget->setResizeMode(QListView::Adjust);
|
|
||||||
contentsWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
||||||
contentsWidget->setSpacing(5);
|
|
||||||
contentsWidget->setWordWrap(false);
|
|
||||||
contentsWidget->setWrapping(true);
|
|
||||||
contentsWidget->setUniformItemSizes(true);
|
|
||||||
contentsWidget->setTextElideMode(Qt::ElideRight);
|
|
||||||
contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
|
||||||
contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
|
||||||
contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
contentsWidget->setItemDelegate(new ListViewDelegate());
|
|
||||||
|
|
||||||
//contentsWidget->setAcceptDrops(true);
|
|
||||||
contentsWidget->setDropIndicatorShown(true);
|
|
||||||
contentsWidget->viewport()->setAcceptDrops(true);
|
|
||||||
contentsWidget->setDragDropMode(QAbstractItemView::DropOnly);
|
|
||||||
contentsWidget->setDefaultDropAction(Qt::CopyAction);
|
|
||||||
|
|
||||||
contentsWidget->installEventFilter(this);
|
|
||||||
|
|
||||||
contentsWidget->setModel(MMC->icons().get());
|
|
||||||
|
|
||||||
auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"),QDialogButtonBox::ResetRole);
|
|
||||||
auto buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"),QDialogButtonBox::ResetRole);
|
|
||||||
|
|
||||||
|
|
||||||
connect(buttonAdd,SIGNAL(clicked(bool)),SLOT(addNewIcon()));
|
|
||||||
connect(buttonRemove,SIGNAL(clicked(bool)),SLOT(removeSelectedIcon()));
|
|
||||||
|
|
||||||
connect
|
|
||||||
(
|
|
||||||
contentsWidget,
|
|
||||||
SIGNAL(doubleClicked(QModelIndex)),
|
|
||||||
SLOT(activated(QModelIndex))
|
|
||||||
);
|
|
||||||
|
|
||||||
connect
|
|
||||||
(
|
|
||||||
contentsWidget->selectionModel(),
|
|
||||||
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
|
||||||
SLOT(selectionChanged(QItemSelection,QItemSelection))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
bool IconPickerDialog::eventFilter ( QObject* obj, QEvent* evt)
|
|
||||||
{
|
|
||||||
if(obj != ui->iconView)
|
|
||||||
return QDialog::eventFilter(obj ,evt);
|
|
||||||
if (evt->type() != QEvent::KeyPress)
|
|
||||||
{
|
|
||||||
return QDialog::eventFilter(obj ,evt);
|
|
||||||
}
|
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(evt);
|
|
||||||
switch(keyEvent->key())
|
|
||||||
{
|
|
||||||
case Qt::Key_Delete:
|
|
||||||
removeSelectedIcon();
|
|
||||||
return true;
|
|
||||||
case Qt::Key_Plus:
|
|
||||||
addNewIcon();
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return QDialog::eventFilter(obj ,evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IconPickerDialog::addNewIcon()
|
|
||||||
{
|
|
||||||
//: The title of the select icons open file dialog
|
|
||||||
QString selectIcons = tr("Select Icons");
|
|
||||||
//: The type of icon files
|
|
||||||
QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), tr("Icons") + "(*.png *.jpg *.jpeg)");
|
|
||||||
MMC->icons()->installIcons(fileNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IconPickerDialog::removeSelectedIcon()
|
|
||||||
{
|
|
||||||
MMC->icons()->deleteIcon(selectedIconKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void IconPickerDialog::activated ( QModelIndex index )
|
|
||||||
{
|
|
||||||
selectedIconKey = index.data(Qt::UserRole).toString();
|
|
||||||
accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void IconPickerDialog::selectionChanged ( QItemSelection selected, QItemSelection deselected )
|
|
||||||
{
|
|
||||||
if(selected.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString key = selected.first().indexes().first().data(Qt::UserRole).toString();
|
|
||||||
if(!key.isEmpty())
|
|
||||||
selectedIconKey = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
int IconPickerDialog::exec ( QString selection )
|
|
||||||
{
|
|
||||||
auto list = MMC->icons();
|
|
||||||
auto contentsWidget = ui->iconView;
|
|
||||||
selectedIconKey = selection;
|
|
||||||
|
|
||||||
|
|
||||||
int index_nr = list->getIconIndex(selection);
|
|
||||||
auto model_index = list->index(index_nr);
|
|
||||||
contentsWidget->selectionModel()->select(model_index, QItemSelectionModel::Current | QItemSelectionModel::Select);
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection, Q_ARG(QModelIndex,model_index));
|
|
||||||
return QDialog::exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
void IconPickerDialog::delayed_scroll ( QModelIndex model_index )
|
|
||||||
{
|
|
||||||
auto contentsWidget = ui->iconView;
|
|
||||||
contentsWidget->scrollTo(model_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
IconPickerDialog::~IconPickerDialog()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QItemSelection>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class IconPickerDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class IconPickerDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit IconPickerDialog(QWidget *parent = 0);
|
|
||||||
~IconPickerDialog();
|
|
||||||
int exec(QString selection);
|
|
||||||
QString selectedIconKey;
|
|
||||||
protected:
|
|
||||||
virtual bool eventFilter ( QObject* , QEvent* );
|
|
||||||
private:
|
|
||||||
Ui::IconPickerDialog *ui;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void selectionChanged ( QItemSelection,QItemSelection );
|
|
||||||
void activated ( QModelIndex );
|
|
||||||
void delayed_scroll ( QModelIndex );
|
|
||||||
void addNewIcon();
|
|
||||||
void removeSelectedIcon();
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QToolButton>
|
|
||||||
|
|
||||||
class QLabel;
|
|
||||||
|
|
||||||
class LabeledToolButton : public QToolButton
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
QLabel * m_label;
|
|
||||||
|
|
||||||
public:
|
|
||||||
LabeledToolButton(QWidget * parent = 0);
|
|
||||||
|
|
||||||
QString text() const;
|
|
||||||
void setText(const QString & text);
|
|
||||||
virtual QSize sizeHint() const;
|
|
||||||
protected:
|
|
||||||
void resizeEvent(QResizeEvent * event);
|
|
||||||
};
|
|
@ -16,10 +16,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include <MultiMC.h>
|
#include "MultiMC.h"
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "MainWindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_MainWindow.h"
|
||||||
#include "keyring.h"
|
#include "keyring.h"
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
@ -40,17 +40,25 @@
|
|||||||
#include "categorizedview.h"
|
#include "categorizedview.h"
|
||||||
#include "categorydrawer.h"
|
#include "categorydrawer.h"
|
||||||
|
|
||||||
#include "gui/settingsdialog.h"
|
#include "gui/Platform.h"
|
||||||
#include "gui/newinstancedialog.h"
|
|
||||||
#include "gui/logindialog.h"
|
#include "gui/widgets/InstanceDelegate.h"
|
||||||
#include "gui/ProgressDialog.h"
|
#include "gui/widgets/LabeledToolButton.h"
|
||||||
#include "gui/aboutdialog.h"
|
|
||||||
#include "gui/versionselectdialog.h"
|
#include "gui/dialogs/SettingsDialog.h"
|
||||||
#include "gui/lwjglselectdialog.h"
|
#include "gui/dialogs/NewInstanceDialog.h"
|
||||||
#include "gui/consolewindow.h"
|
#include "gui/dialogs/LoginDialog.h"
|
||||||
#include "gui/instancesettings.h"
|
#include "gui/dialogs/ProgressDialog.h"
|
||||||
#include "gui/platform.h"
|
#include "gui/dialogs/AboutDialog.h"
|
||||||
#include "gui/CustomMessageBox.h"
|
#include "gui/dialogs/VersionSelectDialog.h"
|
||||||
|
#include "gui/dialogs/CustomMessageBox.h"
|
||||||
|
#include "gui/dialogs/LwjglSelectDialog.h"
|
||||||
|
#include "gui/dialogs/InstanceSettings.h"
|
||||||
|
#include "gui/dialogs/IconPickerDialog.h"
|
||||||
|
#include "gui/dialogs/EditNotesDialog.h"
|
||||||
|
#include "gui/dialogs/CopyInstanceDialog.h"
|
||||||
|
|
||||||
|
#include "gui/ConsoleWindow.h"
|
||||||
|
|
||||||
#include "logic/lists/InstanceList.h"
|
#include "logic/lists/InstanceList.h"
|
||||||
#include "logic/lists/MinecraftVersionList.h"
|
#include "logic/lists/MinecraftVersionList.h"
|
||||||
@ -70,12 +78,6 @@
|
|||||||
|
|
||||||
#include "logic/LegacyInstance.h"
|
#include "logic/LegacyInstance.h"
|
||||||
|
|
||||||
#include "instancedelegate.h"
|
|
||||||
#include "IconPickerDialog.h"
|
|
||||||
#include "LabeledToolButton.h"
|
|
||||||
#include "EditNotesDialog.h"
|
|
||||||
#include "CopyInstanceDialog.h"
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
MultiMCPlatform::fixWM_CLASS(this);
|
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MAINWINDOW_H
|
#pragma once
|
||||||
#define MAINWINDOW_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
@ -166,5 +165,3 @@ private:
|
|||||||
QLabel *m_statusLeft;
|
QLabel *m_statusLeft;
|
||||||
QLabel *m_statusRight;
|
QLabel *m_statusRight;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
|
@ -1,41 +0,0 @@
|
|||||||
#include "ModEditDialogCommon.h"
|
|
||||||
#include "CustomMessageBox.h"
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QString>
|
|
||||||
#include <QUrl>
|
|
||||||
bool lastfirst(QModelIndexList &list, int &first, int &last)
|
|
||||||
{
|
|
||||||
if (!list.size())
|
|
||||||
return false;
|
|
||||||
first = last = list[0].row();
|
|
||||||
for (auto item : list)
|
|
||||||
{
|
|
||||||
int row = item.row();
|
|
||||||
if (row < first)
|
|
||||||
first = row;
|
|
||||||
if (row > last)
|
|
||||||
last = row;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void showWebsiteForMod(QWidget *parentDlg, Mod &m)
|
|
||||||
{
|
|
||||||
QString url = m.homeurl();
|
|
||||||
if (url.size())
|
|
||||||
{
|
|
||||||
// catch the cases where the protocol is missing
|
|
||||||
if(!url.startsWith("http"))
|
|
||||||
{
|
|
||||||
url = "http://" + url;
|
|
||||||
}
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CustomMessageBox::selectable(parentDlg, parentDlg->tr("How sad!"),
|
|
||||||
parentDlg->tr("The mod author didn't provide a website link for this mod."),
|
|
||||||
QMessageBox::Warning);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <QAbstractItemModel>
|
|
||||||
#include <logic/Mod.h>
|
|
||||||
|
|
||||||
bool lastfirst (QModelIndexList & list, int & first, int & last);
|
|
||||||
|
|
||||||
void showWebsiteForMod(QWidget * parentDlg, Mod& m);
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <QTreeView>
|
|
||||||
|
|
||||||
class Mod;
|
|
||||||
|
|
||||||
class ModListView: public QTreeView
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit ModListView ( QWidget* parent = 0 );
|
|
||||||
virtual void setModel ( QAbstractItemModel* model );
|
|
||||||
|
|
||||||
};
|
|
@ -15,11 +15,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PLATFORM_H
|
#pragma once
|
||||||
#define PLATFORM_H
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file platform.h
|
* @file Platform.h
|
||||||
* This file contains platform-specific functions, tweaks and fixes.
|
* This file contains platform-specific functions, tweaks and fixes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -31,5 +30,3 @@ public:
|
|||||||
// X11 WM_CLASS
|
// X11 WM_CLASS
|
||||||
static void fixWM_CLASS(QWidget *widget);
|
static void fixWM_CLASS(QWidget *widget);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLATFORM_H
|
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gui/platform.h>
|
#include <gui/Platform.h>
|
||||||
/**
|
/**
|
||||||
* Stub for non-X11 platforms
|
* Stub for non-X11 platforms
|
||||||
* @brief MultiMCPlatform::fixWM_CLASS
|
* @brief MultiMCPlatform::fixWM_CLASS
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gui/platform.h>
|
#include <gui/Platform.h>
|
||||||
#include <QtX11Extras/QX11Info>
|
#include <QtX11Extras/QX11Info>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
#include "aboutdialog.h"
|
|
||||||
#include "ui_aboutdialog.h"
|
|
||||||
#include <QIcon>
|
|
||||||
#include <MultiMC.h>
|
|
||||||
#include "gui/platform.h"
|
|
||||||
|
|
||||||
AboutDialog::AboutDialog(QWidget *parent) :
|
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::AboutDialog)
|
|
||||||
{
|
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
ui->icon->setPixmap(QIcon(":/icons/multimc/scalable/apps/multimc.svg").pixmap(64));
|
|
||||||
ui->title->setText("MultiMC " + MMC->version().toString());
|
|
||||||
connect(ui->closeButton, SIGNAL(clicked()), SLOT(close()));
|
|
||||||
|
|
||||||
MMC->connect(ui->aboutQt, SIGNAL(clicked()), SLOT(aboutQt()));
|
|
||||||
}
|
|
||||||
|
|
||||||
AboutDialog::~AboutDialog()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
#ifndef ABOUTDIALOG_H
|
|
||||||
#define ABOUTDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class AboutDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AboutDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AboutDialog(QWidget *parent = 0);
|
|
||||||
~AboutDialog();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::AboutDialog *ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ABOUTDIALOG_H
|
|
37
gui/dialogs/AboutDialog.cpp
Normal file
37
gui/dialogs/AboutDialog.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AboutDialog.h"
|
||||||
|
#include "ui_AboutDialog.h"
|
||||||
|
#include <QIcon>
|
||||||
|
#include "MultiMC.h"
|
||||||
|
#include "gui/Platform.h"
|
||||||
|
|
||||||
|
AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog)
|
||||||
|
{
|
||||||
|
MultiMCPlatform::fixWM_CLASS(this);
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->icon->setPixmap(QIcon(":/icons/multimc/scalable/apps/multimc.svg").pixmap(64));
|
||||||
|
ui->title->setText("MultiMC " + MMC->version().toString());
|
||||||
|
connect(ui->closeButton, SIGNAL(clicked()), SLOT(close()));
|
||||||
|
|
||||||
|
MMC->connect(ui->aboutQt, SIGNAL(clicked()), SLOT(aboutQt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
AboutDialog::~AboutDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
35
gui/dialogs/AboutDialog.h
Normal file
35
gui/dialogs/AboutDialog.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class AboutDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AboutDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AboutDialog(QWidget *parent = 0);
|
||||||
|
~AboutDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AboutDialog *ui;
|
||||||
|
};
|
@ -59,7 +59,7 @@
|
|||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="../multimc.qrc">:/icons/multimc/scalable/apps/multimc.svg</pixmap>
|
<pixmap resource="../../multimc.qrc">:/icons/multimc/scalable/apps/multimc.svg</pixmap>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -101,7 +101,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>432</width>
|
<width>432</width>
|
||||||
<height>197</height>
|
<height>179</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
@ -159,8 +159,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>432</width>
|
<width>98</width>
|
||||||
<height>197</height>
|
<height>120</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
@ -176,13 +176,13 @@
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Andrew Okin &lt;</span><a href="mailto:forkk@forkk.net"><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">forkk@forkk.net</span></a><span style=" font-family:'Ubuntu'; font-size:11pt;">&gt;</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Andrew Okin &lt;</span><a href="mailto:forkk@forkk.net"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">forkk@forkk.net</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Petr Mrázek &lt;</span><a href="mailto:peterix@gmail.com"><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">peterix@gmail.com</span></a><span style=" font-family:'Ubuntu'; font-size:11pt;">&gt;</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Petr Mrázek &lt;</span><a href="mailto:peterix@gmail.com"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">peterix@gmail.com</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Orochimarufan &lt;</span><a href="mailto:orochimarufan.x3@gmail.com"><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">orochimarufan.x3@gmail.com</span></a><span style=" font-family:'Ubuntu'; font-size:11pt;">&gt;</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Orochimarufan &lt;</span><a href="mailto:orochimarufan.x3@gmail.com"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">orochimarufan.x3@gmail.com</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">TakSuyu &lt;</span><a href="mailto:taksuyu@gmail.com"><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">taksuyu@gmail.com</span></a><span style=" font-family:'Ubuntu'; font-size:11pt;">&gt;</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">TakSuyu &lt;</span><a href="mailto:taksuyu@gmail.com"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">taksuyu@gmail.com</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Sky (Drayshak) &lt;</span><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">multimc@bunnies.cc</span><span style=" font-family:'Ubuntu'; font-size:11pt;">&gt;</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Sky (Drayshak) &lt;</span><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">multimc@bunnies.cc</span><span style=" font-family:'Ubuntu';">&gt;</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Kilobyte &lt;</span><a href="mailto:stiepen22@gmx.de"><span style=" font-family:'Ubuntu'; font-size:11pt; text-decoration: underline; color:#0000ff;">stiepen22@gmx.de</span></a><span style=" font-family:'Ubuntu'; font-size:11pt;">&gt;</span></p></body></html></string>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu';">Kilobyte &lt;</span><a href="mailto:stiepen22@gmx.de"><span style=" font-family:'Ubuntu'; text-decoration: underline; color:#0000ff;">stiepen22@gmx.de</span></a><span style=" font-family:'Ubuntu';">&gt;</span></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -203,8 +203,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>432</width>
|
<width>98</width>
|
||||||
<height>197</height>
|
<height>88</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="label">
|
<attribute name="label">
|
||||||
@ -226,7 +226,7 @@ p, li { white-space: pre-wrap; }
|
|||||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Copyright 2012 MultiMC Contributors</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Copyright 2012 MultiMC Contributors</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></p>
|
||||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">you may not use this file except in compliance with the License.</span></p>
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:10pt;">you may not use this file except in compliance with the License.</span></p>
|
||||||
@ -309,7 +309,8 @@ p, li { white-space: pre-wrap; }
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../multimc.qrc"/>
|
<include location="../../multimc.qrc"/>
|
||||||
|
<include location="../../multimc.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
@ -13,24 +13,24 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <MultiMC.h>
|
#include <QLayout>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
#include "MultiMC.h"
|
||||||
#include "CopyInstanceDialog.h"
|
#include "CopyInstanceDialog.h"
|
||||||
#include "ui_CopyInstanceDialog.h"
|
#include "ui_CopyInstanceDialog.h"
|
||||||
|
|
||||||
|
#include "gui/Platform.h"
|
||||||
|
#include "gui/dialogs/VersionSelectDialog.h"
|
||||||
|
#include "gui/dialogs/ProgressDialog.h"
|
||||||
|
#include "gui/dialogs/IconPickerDialog.h"
|
||||||
|
|
||||||
#include "logic/InstanceFactory.h"
|
#include "logic/InstanceFactory.h"
|
||||||
#include "logic/BaseVersion.h"
|
#include "logic/BaseVersion.h"
|
||||||
#include "logic/lists/IconList.h"
|
#include "logic/lists/IconList.h"
|
||||||
#include "logic/lists/MinecraftVersionList.h"
|
#include "logic/lists/MinecraftVersionList.h"
|
||||||
#include "logic/tasks/Task.h"
|
#include "logic/tasks/Task.h"
|
||||||
#include <logic/BaseInstance.h>
|
#include "logic/BaseInstance.h"
|
||||||
|
|
||||||
#include "gui/platform.h"
|
|
||||||
#include "versionselectdialog.h"
|
|
||||||
#include "ProgressDialog.h"
|
|
||||||
#include "IconPickerDialog.h"
|
|
||||||
|
|
||||||
#include <QLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
CopyInstanceDialog::CopyInstanceDialog(BaseInstance *original, QWidget *parent)
|
CopyInstanceDialog::CopyInstanceDialog(BaseInstance *original, QWidget *parent)
|
||||||
: m_original(original), QDialog(parent), ui(new Ui::CopyInstanceDialog)
|
: m_original(original), QDialog(parent), ui(new Ui::CopyInstanceDialog)
|
@ -17,7 +17,7 @@
|
|||||||
<string>Copy Instance</string>
|
<string>Copy Instance</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset resource="../multimc.qrc">
|
<iconset resource="../../multimc.qrc">
|
||||||
<normaloff>:/icons/toolbar/copy</normaloff>:/icons/toolbar/copy</iconset>
|
<normaloff>:/icons/toolbar/copy</normaloff>:/icons/toolbar/copy</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
@ -42,7 +42,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="iconButton">
|
<widget class="QToolButton" name="iconButton">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../multimc.qrc">
|
<iconset resource="../../multimc.qrc">
|
||||||
<normaloff>:/icons/instances/infinity</normaloff>:/icons/instances/infinity</iconset>
|
<normaloff>:/icons/instances/infinity</normaloff>:/icons/instances/infinity</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
@ -95,7 +95,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../multimc.qrc"/>
|
<include location="../../multimc.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
34
gui/dialogs/CustomMessageBox.cpp
Normal file
34
gui/dialogs/CustomMessageBox.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CustomMessageBox.h"
|
||||||
|
|
||||||
|
namespace CustomMessageBox
|
||||||
|
{
|
||||||
|
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
|
||||||
|
QMessageBox::Icon icon, QMessageBox::StandardButtons buttons,
|
||||||
|
QMessageBox::StandardButton defaultButton)
|
||||||
|
{
|
||||||
|
QMessageBox *messageBox = new QMessageBox(parent);
|
||||||
|
messageBox->setWindowTitle(title);
|
||||||
|
messageBox->setText(text);
|
||||||
|
messageBox->setStandardButtons(buttons);
|
||||||
|
messageBox->setDefaultButton(defaultButton);
|
||||||
|
messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
|
messageBox->setIcon(icon);
|
||||||
|
|
||||||
|
return messageBox;
|
||||||
|
}
|
||||||
|
}
|
26
gui/dialogs/CustomMessageBox.h
Normal file
26
gui/dialogs/CustomMessageBox.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
namespace CustomMessageBox
|
||||||
|
{
|
||||||
|
QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text,
|
||||||
|
QMessageBox::Icon icon = QMessageBox::NoIcon,
|
||||||
|
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||||
|
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||||
|
}
|
42
gui/dialogs/EditNotesDialog.cpp
Normal file
42
gui/dialogs/EditNotesDialog.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EditNotesDialog.h"
|
||||||
|
#include "ui_EditNotesDialog.h"
|
||||||
|
#include "gui/Platform.h"
|
||||||
|
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
EditNotesDialog::EditNotesDialog(QString notes, QString name, QWidget *parent)
|
||||||
|
: m_instance_notes(notes), m_instance_name(name), QDialog(parent),
|
||||||
|
ui(new Ui::EditNotesDialog)
|
||||||
|
{
|
||||||
|
MultiMCPlatform::fixWM_CLASS(this);
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->noteEditor->setText(notes);
|
||||||
|
setWindowTitle(tr("Edit notes of %1").arg(m_instance_name));
|
||||||
|
// connect(ui->closeButton, SIGNAL(clicked()), SLOT(close()));
|
||||||
|
}
|
||||||
|
|
||||||
|
EditNotesDialog::~EditNotesDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EditNotesDialog::getText()
|
||||||
|
{
|
||||||
|
return ui->noteEditor->toPlainText();
|
||||||
|
}
|
38
gui/dialogs/EditNotesDialog.h
Normal file
38
gui/dialogs/EditNotesDialog.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class EditNotesDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditNotesDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit EditNotesDialog(QString notes, QString name, QWidget *parent = 0);
|
||||||
|
~EditNotesDialog();
|
||||||
|
QString getText();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::EditNotesDialog *ui;
|
||||||
|
QString m_instance_name;
|
||||||
|
QString m_instance_notes;
|
||||||
|
};
|
156
gui/dialogs/IconPickerDialog.cpp
Normal file
156
gui/dialogs/IconPickerDialog.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
#include "MultiMC.h"
|
||||||
|
|
||||||
|
#include "IconPickerDialog.h"
|
||||||
|
#include "ui_IconPickerDialog.h"
|
||||||
|
|
||||||
|
#include "gui/Platform.h"
|
||||||
|
#include "gui/widgets/InstanceDelegate.h"
|
||||||
|
|
||||||
|
#include "logic/lists/IconList.h"
|
||||||
|
|
||||||
|
IconPickerDialog::IconPickerDialog(QWidget *parent)
|
||||||
|
: QDialog(parent), ui(new Ui::IconPickerDialog)
|
||||||
|
{
|
||||||
|
MultiMCPlatform::fixWM_CLASS(this);
|
||||||
|
ui->setupUi(this);
|
||||||
|
setWindowModality(Qt::WindowModal);
|
||||||
|
|
||||||
|
auto contentsWidget = ui->iconView;
|
||||||
|
contentsWidget->setViewMode(QListView::IconMode);
|
||||||
|
contentsWidget->setFlow(QListView::LeftToRight);
|
||||||
|
contentsWidget->setIconSize(QSize(48, 48));
|
||||||
|
contentsWidget->setMovement(QListView::Static);
|
||||||
|
contentsWidget->setResizeMode(QListView::Adjust);
|
||||||
|
contentsWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
contentsWidget->setSpacing(5);
|
||||||
|
contentsWidget->setWordWrap(false);
|
||||||
|
contentsWidget->setWrapping(true);
|
||||||
|
contentsWidget->setUniformItemSizes(true);
|
||||||
|
contentsWidget->setTextElideMode(Qt::ElideRight);
|
||||||
|
contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
|
contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
contentsWidget->setItemDelegate(new ListViewDelegate());
|
||||||
|
|
||||||
|
// contentsWidget->setAcceptDrops(true);
|
||||||
|
contentsWidget->setDropIndicatorShown(true);
|
||||||
|
contentsWidget->viewport()->setAcceptDrops(true);
|
||||||
|
contentsWidget->setDragDropMode(QAbstractItemView::DropOnly);
|
||||||
|
contentsWidget->setDefaultDropAction(Qt::CopyAction);
|
||||||
|
|
||||||
|
contentsWidget->installEventFilter(this);
|
||||||
|
|
||||||
|
contentsWidget->setModel(MMC->icons().get());
|
||||||
|
|
||||||
|
auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole);
|
||||||
|
auto buttonRemove =
|
||||||
|
ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole);
|
||||||
|
|
||||||
|
connect(buttonAdd, SIGNAL(clicked(bool)), SLOT(addNewIcon()));
|
||||||
|
connect(buttonRemove, SIGNAL(clicked(bool)), SLOT(removeSelectedIcon()));
|
||||||
|
|
||||||
|
connect(contentsWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(activated(QModelIndex)));
|
||||||
|
|
||||||
|
connect(contentsWidget->selectionModel(),
|
||||||
|
SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||||
|
SLOT(selectionChanged(QItemSelection, QItemSelection)));
|
||||||
|
}
|
||||||
|
bool IconPickerDialog::eventFilter(QObject *obj, QEvent *evt)
|
||||||
|
{
|
||||||
|
if (obj != ui->iconView)
|
||||||
|
return QDialog::eventFilter(obj, evt);
|
||||||
|
if (evt->type() != QEvent::KeyPress)
|
||||||
|
{
|
||||||
|
return QDialog::eventFilter(obj, evt);
|
||||||
|
}
|
||||||
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
|
||||||
|
switch (keyEvent->key())
|
||||||
|
{
|
||||||
|
case Qt::Key_Delete:
|
||||||
|
removeSelectedIcon();
|
||||||
|
return true;
|
||||||
|
case Qt::Key_Plus:
|
||||||
|
addNewIcon();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QDialog::eventFilter(obj, evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconPickerDialog::addNewIcon()
|
||||||
|
{
|
||||||
|
//: The title of the select icons open file dialog
|
||||||
|
QString selectIcons = tr("Select Icons");
|
||||||
|
//: The type of icon files
|
||||||
|
QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(),
|
||||||
|
tr("Icons") + "(*.png *.jpg *.jpeg)");
|
||||||
|
MMC->icons()->installIcons(fileNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconPickerDialog::removeSelectedIcon()
|
||||||
|
{
|
||||||
|
MMC->icons()->deleteIcon(selectedIconKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconPickerDialog::activated(QModelIndex index)
|
||||||
|
{
|
||||||
|
selectedIconKey = index.data(Qt::UserRole).toString();
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection deselected)
|
||||||
|
{
|
||||||
|
if (selected.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString key = selected.first().indexes().first().data(Qt::UserRole).toString();
|
||||||
|
if (!key.isEmpty())
|
||||||
|
selectedIconKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
int IconPickerDialog::exec(QString selection)
|
||||||
|
{
|
||||||
|
auto list = MMC->icons();
|
||||||
|
auto contentsWidget = ui->iconView;
|
||||||
|
selectedIconKey = selection;
|
||||||
|
|
||||||
|
int index_nr = list->getIconIndex(selection);
|
||||||
|
auto model_index = list->index(index_nr);
|
||||||
|
contentsWidget->selectionModel()->select(
|
||||||
|
model_index, QItemSelectionModel::Current | QItemSelectionModel::Select);
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection,
|
||||||
|
Q_ARG(QModelIndex, model_index));
|
||||||
|
return QDialog::exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconPickerDialog::delayed_scroll(QModelIndex model_index)
|
||||||
|
{
|
||||||
|
auto contentsWidget = ui->iconView;
|
||||||
|
contentsWidget->scrollTo(model_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
IconPickerDialog::~IconPickerDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
48
gui/dialogs/IconPickerDialog.h
Normal file
48
gui/dialogs/IconPickerDialog.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QItemSelection>
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class IconPickerDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class IconPickerDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IconPickerDialog(QWidget *parent = 0);
|
||||||
|
~IconPickerDialog();
|
||||||
|
int exec(QString selection);
|
||||||
|
QString selectedIconKey;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool eventFilter(QObject *, QEvent *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::IconPickerDialog *ui;
|
||||||
|
|
||||||
|
private
|
||||||
|
slots:
|
||||||
|
void selectionChanged(QItemSelection, QItemSelection);
|
||||||
|
void activated(QModelIndex);
|
||||||
|
void delayed_scroll(QModelIndex);
|
||||||
|
void addNewIcon();
|
||||||
|
void removeSelectedIcon();
|
||||||
|
};
|
@ -17,16 +17,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "instancesettings.h"
|
#include "InstanceSettings.h"
|
||||||
#include "ui_instancesettings.h"
|
#include "ui_InstanceSettings.h"
|
||||||
#include "gui/platform.h"
|
#include "gui/Platform.h"
|
||||||
|
|
||||||
InstanceSettings::InstanceSettings( SettingsObject * obj, QWidget *parent) :
|
InstanceSettings::InstanceSettings(SettingsObject *obj, QWidget *parent)
|
||||||
m_obj(obj),
|
: m_obj(obj), QDialog(parent), ui(new Ui::InstanceSettings)
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::InstanceSettings)
|
|
||||||
{
|
{
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
MultiMCPlatform::fixWM_CLASS(this);
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
loadSettings();
|
loadSettings();
|
||||||
}
|
}
|
||||||
@ -36,7 +34,7 @@ InstanceSettings::~InstanceSettings()
|
|||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceSettings::showEvent ( QShowEvent* ev )
|
void InstanceSettings::showEvent(QShowEvent *ev)
|
||||||
{
|
{
|
||||||
QDialog::showEvent(ev);
|
QDialog::showEvent(ev);
|
||||||
adjustSize();
|
adjustSize();
|
||||||
@ -58,13 +56,12 @@ void InstanceSettings::on_buttonBox_rejected()
|
|||||||
reject();
|
reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InstanceSettings::applySettings()
|
void InstanceSettings::applySettings()
|
||||||
{
|
{
|
||||||
// Console
|
// Console
|
||||||
bool console = ui->consoleSettingsBox->isChecked();
|
bool console = ui->consoleSettingsBox->isChecked();
|
||||||
m_obj->set("OverrideConsole", console);
|
m_obj->set("OverrideConsole", console);
|
||||||
if(console)
|
if (console)
|
||||||
{
|
{
|
||||||
m_obj->set("ShowConsole", ui->showConsoleCheck->isChecked());
|
m_obj->set("ShowConsole", ui->showConsoleCheck->isChecked());
|
||||||
m_obj->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
|
m_obj->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
|
||||||
@ -78,7 +75,7 @@ void InstanceSettings::applySettings()
|
|||||||
// Window Size
|
// Window Size
|
||||||
bool window = ui->windowSizeGroupBox->isChecked();
|
bool window = ui->windowSizeGroupBox->isChecked();
|
||||||
m_obj->set("OverrideWindow", window);
|
m_obj->set("OverrideWindow", window);
|
||||||
if(window)
|
if (window)
|
||||||
{
|
{
|
||||||
m_obj->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
|
m_obj->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
|
||||||
m_obj->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
|
m_obj->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
|
||||||
@ -90,12 +87,11 @@ void InstanceSettings::applySettings()
|
|||||||
m_obj->reset("MinecraftWinWidth");
|
m_obj->reset("MinecraftWinWidth");
|
||||||
m_obj->reset("MinecraftWinHeight");
|
m_obj->reset("MinecraftWinHeight");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Auto Login
|
// Auto Login
|
||||||
bool login = ui->accountSettingsGroupBox->isChecked();
|
bool login = ui->accountSettingsGroupBox->isChecked();
|
||||||
m_obj->set("OverrideLogin", login);
|
m_obj->set("OverrideLogin", login);
|
||||||
if(login)
|
if (login)
|
||||||
{
|
{
|
||||||
m_obj->set("AutoLogin", ui->autoLoginChecBox->isChecked());
|
m_obj->set("AutoLogin", ui->autoLoginChecBox->isChecked());
|
||||||
}
|
}
|
||||||
@ -103,12 +99,11 @@ void InstanceSettings::applySettings()
|
|||||||
{
|
{
|
||||||
m_obj->reset("AutoLogin");
|
m_obj->reset("AutoLogin");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
bool memory = ui->memoryGroupBox->isChecked();
|
bool memory = ui->memoryGroupBox->isChecked();
|
||||||
m_obj->set("OverrideMemory", memory);
|
m_obj->set("OverrideMemory", memory);
|
||||||
if(memory)
|
if (memory)
|
||||||
{
|
{
|
||||||
m_obj->set("MinMemAlloc", ui->minMemSpinBox->value());
|
m_obj->set("MinMemAlloc", ui->minMemSpinBox->value());
|
||||||
m_obj->set("MaxMemAlloc", ui->maxMemSpinBox->value());
|
m_obj->set("MaxMemAlloc", ui->maxMemSpinBox->value());
|
||||||
@ -120,12 +115,11 @@ void InstanceSettings::applySettings()
|
|||||||
m_obj->reset("MaxMemAlloc");
|
m_obj->reset("MaxMemAlloc");
|
||||||
m_obj->reset("PermGen");
|
m_obj->reset("PermGen");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Java Settings
|
// Java Settings
|
||||||
bool java = ui->javaSettingsGroupBox->isChecked();
|
bool java = ui->javaSettingsGroupBox->isChecked();
|
||||||
m_obj->set("OverrideJava", java);
|
m_obj->set("OverrideJava", java);
|
||||||
if(java)
|
if (java)
|
||||||
{
|
{
|
||||||
m_obj->set("JavaPath", ui->javaPathTextBox->text());
|
m_obj->set("JavaPath", ui->javaPathTextBox->text());
|
||||||
m_obj->set("JvmArgs", ui->jvmArgsTextBox->text());
|
m_obj->set("JvmArgs", ui->jvmArgsTextBox->text());
|
||||||
@ -135,12 +129,11 @@ void InstanceSettings::applySettings()
|
|||||||
m_obj->reset("JavaPath");
|
m_obj->reset("JavaPath");
|
||||||
m_obj->reset("JvmArgs");
|
m_obj->reset("JvmArgs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Custom Commands
|
// Custom Commands
|
||||||
bool custcmd = ui->customCommandsGroupBox->isChecked();
|
bool custcmd = ui->customCommandsGroupBox->isChecked();
|
||||||
m_obj->set("OverrideCommands", custcmd);
|
m_obj->set("OverrideCommands", custcmd);
|
||||||
if(custcmd)
|
if (custcmd)
|
||||||
{
|
{
|
||||||
m_obj->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text());
|
m_obj->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text());
|
||||||
m_obj->set("PostExitCommand", ui->postExitCmdTextBox->text());
|
m_obj->set("PostExitCommand", ui->postExitCmdTextBox->text());
|
||||||
@ -150,7 +143,6 @@ void InstanceSettings::applySettings()
|
|||||||
m_obj->reset("PreLaunchCommand");
|
m_obj->reset("PreLaunchCommand");
|
||||||
m_obj->reset("PostExitCommand");
|
m_obj->reset("PostExitCommand");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceSettings::loadSettings()
|
void InstanceSettings::loadSettings()
|
||||||
@ -165,7 +157,6 @@ void InstanceSettings::loadSettings()
|
|||||||
ui->maximizedCheckBox->setChecked(m_obj->get("LaunchMaximized").toBool());
|
ui->maximizedCheckBox->setChecked(m_obj->get("LaunchMaximized").toBool());
|
||||||
ui->windowWidthSpinBox->setValue(m_obj->get("MinecraftWinWidth").toInt());
|
ui->windowWidthSpinBox->setValue(m_obj->get("MinecraftWinWidth").toInt());
|
||||||
ui->windowHeightSpinBox->setValue(m_obj->get("MinecraftWinHeight").toInt());
|
ui->windowHeightSpinBox->setValue(m_obj->get("MinecraftWinHeight").toInt());
|
||||||
|
|
||||||
|
|
||||||
// Auto Login
|
// Auto Login
|
||||||
ui->accountSettingsGroupBox->setChecked(m_obj->get("OverrideLogin").toBool());
|
ui->accountSettingsGroupBox->setChecked(m_obj->get("OverrideLogin").toBool());
|
50
gui/dialogs/InstanceSettings.h
Normal file
50
gui/dialogs/InstanceSettings.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "settingsobject.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class InstanceSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
class InstanceSettings : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit InstanceSettings(SettingsObject *s, QWidget *parent = 0);
|
||||||
|
~InstanceSettings();
|
||||||
|
|
||||||
|
void updateCheckboxStuff();
|
||||||
|
|
||||||
|
void applySettings();
|
||||||
|
void loadSettings();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void showEvent(QShowEvent *);
|
||||||
|
private
|
||||||
|
slots:
|
||||||
|
void on_customCommandsGroupBox_toggled(bool arg1);
|
||||||
|
void on_buttonBox_accepted();
|
||||||
|
void on_buttonBox_rejected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::InstanceSettings *ui;
|
||||||
|
SettingsObject *m_obj;
|
||||||
|
};
|
@ -16,12 +16,12 @@
|
|||||||
#include "MultiMC.h"
|
#include "MultiMC.h"
|
||||||
#include "LegacyModEditDialog.h"
|
#include "LegacyModEditDialog.h"
|
||||||
#include "ModEditDialogCommon.h"
|
#include "ModEditDialogCommon.h"
|
||||||
#include "versionselectdialog.h"
|
#include "VersionSelectDialog.h"
|
||||||
#include "ProgressDialog.h"
|
#include "ProgressDialog.h"
|
||||||
#include "ui_LegacyModEditDialog.h"
|
#include "ui_LegacyModEditDialog.h"
|
||||||
#include "logic/ModList.h"
|
#include "logic/ModList.h"
|
||||||
#include "logic/lists/ForgeVersionList.h"
|
#include "logic/lists/ForgeVersionList.h"
|
||||||
#include "gui/platform.h"
|
#include "gui/Platform.h"
|
||||||
|
|
||||||
#include <pathutils.h>
|
#include <pathutils.h>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
LegacyModEditDialog::LegacyModEditDialog(LegacyInstance *inst, QWidget *parent)
|
LegacyModEditDialog::LegacyModEditDialog(LegacyInstance *inst, QWidget *parent)
|
||||||
: m_inst(inst), QDialog(parent), ui(new Ui::LegacyModEditDialog)
|
: m_inst(inst), QDialog(parent), ui(new Ui::LegacyModEditDialog)
|
||||||
{
|
{
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
MultiMCPlatform::fixWM_CLASS(this);
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
// Jar mods
|
// Jar mods
|
||||||
@ -358,7 +358,7 @@ void LegacyModEditDialog::on_buttonBox_rejected()
|
|||||||
|
|
||||||
void LegacyModEditDialog::jarCurrent(QModelIndex current, QModelIndex previous)
|
void LegacyModEditDialog::jarCurrent(QModelIndex current, QModelIndex previous)
|
||||||
{
|
{
|
||||||
if(!current.isValid())
|
if (!current.isValid())
|
||||||
{
|
{
|
||||||
ui->jarMIFrame->clear();
|
ui->jarMIFrame->clear();
|
||||||
return;
|
return;
|
||||||
@ -370,7 +370,7 @@ void LegacyModEditDialog::jarCurrent(QModelIndex current, QModelIndex previous)
|
|||||||
|
|
||||||
void LegacyModEditDialog::coreCurrent(QModelIndex current, QModelIndex previous)
|
void LegacyModEditDialog::coreCurrent(QModelIndex current, QModelIndex previous)
|
||||||
{
|
{
|
||||||
if(!current.isValid())
|
if (!current.isValid())
|
||||||
{
|
{
|
||||||
ui->coreMIFrame->clear();
|
ui->coreMIFrame->clear();
|
||||||
return;
|
return;
|
||||||
@ -382,7 +382,7 @@ void LegacyModEditDialog::coreCurrent(QModelIndex current, QModelIndex previous)
|
|||||||
|
|
||||||
void LegacyModEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous)
|
void LegacyModEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous)
|
||||||
{
|
{
|
||||||
if(!current.isValid())
|
if (!current.isValid())
|
||||||
{
|
{
|
||||||
ui->loaderMIFrame->clear();
|
ui->loaderMIFrame->clear();
|
||||||
return;
|
return;
|
@ -307,12 +307,12 @@
|
|||||||
<customwidget>
|
<customwidget>
|
||||||
<class>ModListView</class>
|
<class>ModListView</class>
|
||||||
<extends>QTreeView</extends>
|
<extends>QTreeView</extends>
|
||||||
<header>gui/ModListView.h</header>
|
<header>gui/widgets/ModListView.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>MCModInfoFrame</class>
|
<class>MCModInfoFrame</class>
|
||||||
<extends>QFrame</extends>
|
<extends>QFrame</extends>
|
||||||
<header>gui/MCModInfoFrame.h</header>
|
<header>gui/widgets/MCModInfoFrame.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,10 +13,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "logindialog.h"
|
#include "LoginDialog.h"
|
||||||
#include "ui_logindialog.h"
|
#include "ui_LoginDialog.h"
|
||||||
#include "keyring.h"
|
#include "keyring.h"
|
||||||
#include "gui/platform.h"
|
#include "gui/Platform.h"
|
||||||
#include "MultiMC.h"
|
#include "MultiMC.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@ -24,58 +24,58 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonParseError>
|
#include <QJsonParseError>
|
||||||
#include "logic/net/HttpMetaCache.h"
|
#include "logic/net/HttpMetaCache.h"
|
||||||
#include <logger/QsLog.h>
|
#include "logger/QsLog.h"
|
||||||
|
|
||||||
LoginDialog::LoginDialog(QWidget *parent, const QString& loginErrMsg) :
|
LoginDialog::LoginDialog(QWidget *parent, const QString &loginErrMsg)
|
||||||
QDialog(parent),
|
: QDialog(parent), ui(new Ui::LoginDialog)
|
||||||
ui(new Ui::LoginDialog)
|
|
||||||
{
|
{
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
MultiMCPlatform::fixWM_CLASS(this);
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
//: Use offline mode one time
|
//: Use offline mode one time
|
||||||
offlineButton = new QPushButton(tr("Offline Once"));
|
offlineButton = new QPushButton(tr("Offline Once"));
|
||||||
|
|
||||||
ui->loginButtonBox->addButton(offlineButton, QDialogButtonBox::ActionRole);
|
ui->loginButtonBox->addButton(offlineButton, QDialogButtonBox::ActionRole);
|
||||||
|
|
||||||
blockToggles = false;
|
blockToggles = false;
|
||||||
isOnline_ = true;
|
isOnline_ = true;
|
||||||
onlineForced = false;
|
onlineForced = false;
|
||||||
|
|
||||||
//: The username during login (placeholder)
|
//: The username during login (placeholder)
|
||||||
ui->usernameTextBox->lineEdit()->setPlaceholderText(tr("Name"));
|
ui->usernameTextBox->lineEdit()->setPlaceholderText(tr("Name"));
|
||||||
|
|
||||||
connect(ui->usernameTextBox, SIGNAL(currentTextChanged(QString)), this, SLOT(userTextChanged(QString)));
|
connect(ui->usernameTextBox, SIGNAL(currentTextChanged(QString)), this,
|
||||||
|
SLOT(userTextChanged(QString)));
|
||||||
connect(ui->forgetButton, SIGNAL(clicked(bool)), this, SLOT(forgetCurrentUser()));
|
connect(ui->forgetButton, SIGNAL(clicked(bool)), this, SLOT(forgetCurrentUser()));
|
||||||
connect(offlineButton, SIGNAL(clicked(bool)), this, SLOT(launchOffline()));
|
connect(offlineButton, SIGNAL(clicked(bool)), this, SLOT(launchOffline()));
|
||||||
|
|
||||||
if (loginErrMsg.isEmpty())
|
if (loginErrMsg.isEmpty())
|
||||||
ui->loginErrorLabel->setVisible(false);
|
ui->loginErrorLabel->setVisible(false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ui->loginErrorLabel->setVisible(true);
|
ui->loginErrorLabel->setVisible(true);
|
||||||
ui->loginErrorLabel->setText(QString("<span style=\" color:#ff0000;\">%1</span>").
|
ui->loginErrorLabel->setText(
|
||||||
arg(loginErrMsg));
|
QString("<span style=\" color:#ff0000;\">%1</span>").arg(loginErrMsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->lblFace->setVisible(false);
|
ui->lblFace->setVisible(false);
|
||||||
|
|
||||||
resize(minimumSizeHint());
|
resize(minimumSizeHint());
|
||||||
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
Keyring * k = Keyring::instance();
|
Keyring *k = Keyring::instance();
|
||||||
QStringList accounts = k->getStoredAccounts("minecraft");
|
QStringList accounts = k->getStoredAccounts("minecraft");
|
||||||
ui->usernameTextBox->addItems(accounts);
|
ui->usernameTextBox->addItems(accounts);
|
||||||
|
|
||||||
// TODO: restore last selected account here, if applicable
|
// TODO: restore last selected account here, if applicable
|
||||||
|
|
||||||
int index = ui->usernameTextBox->currentIndex();
|
int index = ui->usernameTextBox->currentIndex();
|
||||||
if(index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
ui->passwordTextBox->setFocus(Qt::OtherFocusReason);
|
ui->passwordTextBox->setFocus(Qt::OtherFocusReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(ui->rememberUsernameCheckbox,SIGNAL(toggled(bool)), SLOT(usernameToggled(bool)));
|
connect(ui->rememberUsernameCheckbox, SIGNAL(toggled(bool)), SLOT(usernameToggled(bool)));
|
||||||
connect(ui->rememberPasswordCheckbox,SIGNAL(toggled(bool)), SLOT(passwordToggled(bool)));
|
connect(ui->rememberPasswordCheckbox, SIGNAL(toggled(bool)), SLOT(passwordToggled(bool)));
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginDialog::~LoginDialog()
|
LoginDialog::~LoginDialog()
|
||||||
@ -96,14 +96,14 @@ QString LoginDialog::getPassword() const
|
|||||||
|
|
||||||
void LoginDialog::forgetCurrentUser()
|
void LoginDialog::forgetCurrentUser()
|
||||||
{
|
{
|
||||||
Keyring * k = Keyring::instance();
|
Keyring *k = Keyring::instance();
|
||||||
QString acct = ui->usernameTextBox->currentText();
|
QString acct = ui->usernameTextBox->currentText();
|
||||||
k->removeStoredAccount("minecraft", acct);
|
k->removeStoredAccount("minecraft", acct);
|
||||||
ui->passwordTextBox->clear();
|
ui->passwordTextBox->clear();
|
||||||
int index = ui->usernameTextBox->findText(acct);
|
int index = ui->usernameTextBox->findText(acct);
|
||||||
if(index != -1)
|
if (index != -1)
|
||||||
ui->usernameTextBox->removeItem(index);
|
ui->usernameTextBox->removeItem(index);
|
||||||
if(!ui->usernameTextBox->count())
|
if (!ui->usernameTextBox->count())
|
||||||
{
|
{
|
||||||
blockToggles = true;
|
blockToggles = true;
|
||||||
ui->rememberUsernameCheckbox->setChecked(false);
|
ui->rememberUsernameCheckbox->setChecked(false);
|
||||||
@ -112,19 +112,19 @@ void LoginDialog::forgetCurrentUser()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoginDialog::passwordToggled ( bool state )
|
void LoginDialog::passwordToggled(bool state)
|
||||||
{
|
{
|
||||||
// if toggled off
|
// if toggled off
|
||||||
if(blockToggles)
|
if (blockToggles)
|
||||||
return;
|
return;
|
||||||
blockToggles = true;
|
blockToggles = true;
|
||||||
if(!state)
|
if (!state)
|
||||||
{
|
{
|
||||||
QLOG_DEBUG() << "password disabled";
|
QLOG_DEBUG() << "password disabled";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!ui->rememberUsernameCheckbox->isChecked())
|
if (!ui->rememberUsernameCheckbox->isChecked())
|
||||||
{
|
{
|
||||||
ui->rememberUsernameCheckbox->setChecked(true);
|
ui->rememberUsernameCheckbox->setChecked(true);
|
||||||
}
|
}
|
||||||
@ -133,15 +133,15 @@ void LoginDialog::passwordToggled ( bool state )
|
|||||||
blockToggles = false;
|
blockToggles = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoginDialog::usernameToggled ( bool state )
|
void LoginDialog::usernameToggled(bool state)
|
||||||
{
|
{
|
||||||
// if toggled off
|
// if toggled off
|
||||||
if(blockToggles)
|
if (blockToggles)
|
||||||
return;
|
return;
|
||||||
blockToggles = true;
|
blockToggles = true;
|
||||||
if(!state)
|
if (!state)
|
||||||
{
|
{
|
||||||
if(ui->rememberPasswordCheckbox->isChecked())
|
if (ui->rememberPasswordCheckbox->isChecked())
|
||||||
{
|
{
|
||||||
ui->rememberPasswordCheckbox->setChecked(false);
|
ui->rememberPasswordCheckbox->setChecked(false);
|
||||||
}
|
}
|
||||||
@ -154,26 +154,26 @@ void LoginDialog::usernameToggled ( bool state )
|
|||||||
blockToggles = false;
|
blockToggles = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoginDialog::userTextChanged(const QString &user)
|
||||||
void LoginDialog::userTextChanged ( const QString& user )
|
|
||||||
{
|
{
|
||||||
blockToggles = true;
|
blockToggles = true;
|
||||||
Keyring * k = Keyring::instance();
|
Keyring *k = Keyring::instance();
|
||||||
QStringList sl = k->getStoredAccounts("minecraft");
|
QStringList sl = k->getStoredAccounts("minecraft");
|
||||||
bool gotFace = false;
|
bool gotFace = false;
|
||||||
|
|
||||||
if(sl.contains(user))
|
if (sl.contains(user))
|
||||||
{
|
{
|
||||||
ui->rememberUsernameCheckbox->setChecked(true);
|
ui->rememberUsernameCheckbox->setChecked(true);
|
||||||
QString passwd = k->getPassword("minecraft",user);
|
QString passwd = k->getPassword("minecraft", user);
|
||||||
ui->rememberPasswordCheckbox->setChecked(!passwd.isEmpty());
|
ui->rememberPasswordCheckbox->setChecked(!passwd.isEmpty());
|
||||||
ui->passwordTextBox->setText(passwd);
|
ui->passwordTextBox->setText(passwd);
|
||||||
|
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
{
|
{
|
||||||
auto filename = MMC->metacache()->resolveEntry("skins", "skins.json")->getFullPath();
|
auto filename =
|
||||||
|
MMC->metacache()->resolveEntry("skins", "skins.json")->getFullPath();
|
||||||
QFile listFile(filename);
|
QFile listFile(filename);
|
||||||
if(!listFile.open(QIODevice::ReadOnly))
|
if (!listFile.open(QIODevice::ReadOnly))
|
||||||
return;
|
return;
|
||||||
data = listFile.readAll();
|
data = listFile.readAll();
|
||||||
}
|
}
|
||||||
@ -183,20 +183,25 @@ void LoginDialog::userTextChanged ( const QString& user )
|
|||||||
QJsonObject root = jsonDoc.object();
|
QJsonObject root = jsonDoc.object();
|
||||||
QJsonObject mappings = root.value("mappings").toObject();
|
QJsonObject mappings = root.value("mappings").toObject();
|
||||||
|
|
||||||
if(!mappings[user].isUndefined())
|
if (!mappings[user].isUndefined())
|
||||||
{
|
{
|
||||||
QJsonArray usernames = mappings.value(user).toArray();
|
QJsonArray usernames = mappings.value(user).toArray();
|
||||||
if(!usernames.isEmpty())
|
if (!usernames.isEmpty())
|
||||||
{
|
{
|
||||||
QString mapped_username = usernames[0].toString();
|
QString mapped_username = usernames[0].toString();
|
||||||
|
|
||||||
if(!mapped_username.isEmpty())
|
if (!mapped_username.isEmpty())
|
||||||
{
|
{
|
||||||
QFile fskin(MMC->metacache()->resolveEntry("skins", mapped_username + ".png")->getFullPath());
|
QFile fskin(MMC->metacache()
|
||||||
if(fskin.exists())
|
->resolveEntry("skins", mapped_username + ".png")
|
||||||
|
->getFullPath());
|
||||||
|
if (fskin.exists())
|
||||||
{
|
{
|
||||||
QPixmap skin(MMC->metacache()->resolveEntry("skins", mapped_username + ".png")->getFullPath());
|
QPixmap skin(MMC->metacache()
|
||||||
QPixmap face = skin.copy(8, 8, 8, 8).scaled(48, 48, Qt::KeepAspectRatio);
|
->resolveEntry("skins", mapped_username + ".png")
|
||||||
|
->getFullPath());
|
||||||
|
QPixmap face =
|
||||||
|
skin.copy(8, 8, 8, 8).scaled(48, 48, Qt::KeepAspectRatio);
|
||||||
|
|
||||||
ui->lblFace->setPixmap(face);
|
ui->lblFace->setPixmap(face);
|
||||||
gotFace = true;
|
gotFace = true;
|
||||||
@ -210,21 +215,20 @@ void LoginDialog::userTextChanged ( const QString& user )
|
|||||||
blockToggles = false;
|
blockToggles = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LoginDialog::accept()
|
void LoginDialog::accept()
|
||||||
{
|
{
|
||||||
bool saveName = ui->rememberUsernameCheckbox->isChecked();
|
bool saveName = ui->rememberUsernameCheckbox->isChecked();
|
||||||
bool savePass = ui->rememberPasswordCheckbox->isChecked();
|
bool savePass = ui->rememberPasswordCheckbox->isChecked();
|
||||||
Keyring * k = Keyring::instance();
|
Keyring *k = Keyring::instance();
|
||||||
if(saveName)
|
if (saveName)
|
||||||
{
|
{
|
||||||
if(savePass)
|
if (savePass)
|
||||||
{
|
{
|
||||||
k->storePassword("minecraft",getUsername(),getPassword());
|
k->storePassword("minecraft", getUsername(), getPassword());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
k->storePassword("minecraft",getUsername(),QString());
|
k->storePassword("minecraft", getUsername(), QString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -235,7 +239,7 @@ void LoginDialog::accept()
|
|||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoginDialog::launchOffline()
|
void LoginDialog::launchOffline()
|
||||||
{
|
{
|
||||||
isOnline_ = false;
|
isOnline_ = false;
|
||||||
QDialog::accept();
|
QDialog::accept();
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,39 +13,45 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LOGINDIALOG_H
|
#pragma once
|
||||||
#define LOGINDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class LoginDialog;
|
class LoginDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginDialog : public QDialog
|
class LoginDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LoginDialog(QWidget *parent = 0, const QString& loginErrMsg = "");
|
explicit LoginDialog(QWidget *parent = 0, const QString &loginErrMsg = "");
|
||||||
~LoginDialog();
|
~LoginDialog();
|
||||||
|
|
||||||
QString getUsername() const;
|
QString getUsername() const;
|
||||||
QString getPassword() const;
|
QString getPassword() const;
|
||||||
|
|
||||||
inline bool isOnline() { return isOnline_; }
|
inline bool isOnline()
|
||||||
|
{
|
||||||
|
return isOnline_;
|
||||||
|
}
|
||||||
|
|
||||||
void forceOnline();
|
void forceOnline();
|
||||||
|
|
||||||
public slots:
|
public
|
||||||
|
slots:
|
||||||
virtual void accept();
|
virtual void accept();
|
||||||
virtual void userTextChanged(const QString& user);
|
virtual void userTextChanged(const QString &user);
|
||||||
virtual void forgetCurrentUser();
|
virtual void forgetCurrentUser();
|
||||||
private slots:
|
private
|
||||||
void usernameToggled ( bool );
|
slots:
|
||||||
void passwordToggled ( bool );
|
void usernameToggled(bool);
|
||||||
|
void passwordToggled(bool);
|
||||||
void launchOffline();
|
void launchOffline();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::LoginDialog *ui;
|
Ui::LoginDialog *ui;
|
||||||
bool blockToggles;
|
bool blockToggles;
|
||||||
@ -53,5 +59,3 @@ private:
|
|||||||
bool isOnline_;
|
bool isOnline_;
|
||||||
bool onlineForced;
|
bool onlineForced;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LOGINDIALOG_H
|
|
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>476</width>
|
<width>496</width>
|
||||||
<height>168</height>
|
<height>168</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -50,7 +50,7 @@
|
|||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap">
|
<property name="pixmap">
|
||||||
<pixmap resource="../multimc.qrc">:/icons/instances/steve</pixmap>
|
<pixmap resource="../../multimc.qrc">:/icons/instances/steve</pixmap>
|
||||||
</property>
|
</property>
|
||||||
<property name="scaledContents">
|
<property name="scaledContents">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@ -146,6 +146,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
|
<include location="../../multimc.qrc"/>
|
||||||
<include location="../multimc.qrc"/>
|
<include location="../multimc.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -14,23 +14,23 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MultiMC.h"
|
#include "MultiMC.h"
|
||||||
#include "lwjglselectdialog.h"
|
#include "LwjglSelectDialog.h"
|
||||||
#include "ui_lwjglselectdialog.h"
|
#include "ui_LwjglSelectDialog.h"
|
||||||
#include "gui/platform.h"
|
#include "gui/Platform.h"
|
||||||
|
|
||||||
#include "logic/lists/LwjglVersionList.h"
|
#include "logic/lists/LwjglVersionList.h"
|
||||||
|
|
||||||
LWJGLSelectDialog::LWJGLSelectDialog(QWidget *parent) :
|
LWJGLSelectDialog::LWJGLSelectDialog(QWidget *parent)
|
||||||
QDialog(parent),
|
: QDialog(parent), ui(new Ui::LWJGLSelectDialog)
|
||||||
ui(new Ui::LWJGLSelectDialog)
|
|
||||||
{
|
{
|
||||||
MultiMCPlatform::fixWM_CLASS(this);
|
MultiMCPlatform::fixWM_CLASS(this);
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->labelStatus->setVisible(false);
|
ui->labelStatus->setVisible(false);
|
||||||
auto lwjgllist = MMC->lwjgllist();
|
auto lwjgllist = MMC->lwjgllist();
|
||||||
ui->lwjglListView->setModel(lwjgllist.get());
|
ui->lwjglListView->setModel(lwjgllist.get());
|
||||||
|
|
||||||
connect(lwjgllist.get(), SIGNAL(loadingStateUpdated(bool)), SLOT(loadingStateUpdated(bool)));
|
connect(lwjgllist.get(), SIGNAL(loadingStateUpdated(bool)),
|
||||||
|
SLOT(loadingStateUpdated(bool)));
|
||||||
connect(lwjgllist.get(), SIGNAL(loadListFailed(QString)), SLOT(loadingFailed(QString)));
|
connect(lwjgllist.get(), SIGNAL(loadListFailed(QString)), SLOT(loadingFailed(QString)));
|
||||||
loadingStateUpdated(lwjgllist->isLoading());
|
loadingStateUpdated(lwjgllist->isLoading());
|
||||||
}
|
}
|
||||||
@ -42,9 +42,9 @@ LWJGLSelectDialog::~LWJGLSelectDialog()
|
|||||||
|
|
||||||
QString LWJGLSelectDialog::selectedVersion() const
|
QString LWJGLSelectDialog::selectedVersion() const
|
||||||
{
|
{
|
||||||
return MMC->lwjgllist()->data(
|
return MMC->lwjgllist()
|
||||||
ui->lwjglListView->selectionModel()->currentIndex(),
|
->data(ui->lwjglListView->selectionModel()->currentIndex(), Qt::DisplayRole)
|
||||||
Qt::DisplayRole).toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LWJGLSelectDialog::on_refreshButton_clicked()
|
void LWJGLSelectDialog::on_refreshButton_clicked()
|
@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
@ -13,8 +13,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LWJGLSELECTDIALOG_H
|
#pragma once
|
||||||
#define LWJGLSELECTDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
@ -26,21 +25,20 @@ class LWJGLSelectDialog;
|
|||||||
class LWJGLSelectDialog : public QDialog
|
class LWJGLSelectDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LWJGLSelectDialog(QWidget *parent = 0);
|
explicit LWJGLSelectDialog(QWidget *parent = 0);
|
||||||
~LWJGLSelectDialog();
|
~LWJGLSelectDialog();
|
||||||
|
|
||||||
QString selectedVersion() const;
|
QString selectedVersion() const;
|
||||||
|
|
||||||
private slots:
|
private
|
||||||
|
slots:
|
||||||
void on_refreshButton_clicked();
|
void on_refreshButton_clicked();
|
||||||
|
|
||||||
void loadingStateUpdated(bool loading);
|
void loadingStateUpdated(bool loading);
|
||||||
void loadingFailed(QString error);
|
void loadingFailed(QString error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::LWJGLSelectDialog *ui;
|
Ui::LWJGLSelectDialog *ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LWJGLSELECTDIALOG_H
|
|
57
gui/dialogs/ModEditDialogCommon.cpp
Normal file
57
gui/dialogs/ModEditDialogCommon.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/* Copyright 2013 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ModEditDialogCommon.h"
|
||||||
|
#include "CustomMessageBox.h"
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QString>
|
||||||
|
#include <QUrl>
|
||||||
|
bool lastfirst(QModelIndexList &list, int &first, int &last)
|
||||||
|
{
|
||||||
|
if (!list.size())
|
||||||
|
return false;
|
||||||
|
first = last = list[0].row();
|
||||||
|
for (auto item : list)
|
||||||
|
{
|
||||||
|
int row = item.row();
|
||||||
|
if (row < first)
|
||||||
|
first = row;
|
||||||
|
if (row > last)
|
||||||
|
last = row;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showWebsiteForMod(QWidget *parentDlg, Mod &m)
|
||||||
|
{
|
||||||
|
QString url = m.homeurl();
|
||||||
|
if (url.size())
|
||||||
|
{
|
||||||
|
// catch the cases where the protocol is missing
|
||||||
|
if (!url.startsWith("http"))
|
||||||
|
{
|
||||||
|
url = "http://" + url;
|
||||||
|
}
|
||||||
|
QDesktopServices::openUrl(url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CustomMessageBox::selectable(
|
||||||
|
parentDlg, parentDlg->tr("How sad!"),
|
||||||
|
parentDlg->tr("The mod author didn't provide a website link for this mod."),
|
||||||
|
QMessageBox::Warning);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user