65 return dataStream << static_cast<uint8_t>(tag);
68 QDataStream&
writeStream(QDataStream& dataStream,
const QByteArray& data)
71 dataStream.writeRawData(size.data(), size.size());
72 dataStream.writeRawData(data.data(), data.size());
76 QDataStream&
writeStream(QDataStream& dataStream,
const QString& str)
83 return dataStream >>
reinterpret_cast<quint8&
>(tag);
87 QDataStream&
readStream(QDataStream& dataStream, QByteArray& data)
93 dataStream.readRawData(&num3, 1);
94 num |= (num3 & 0x7f) << num2;
96 }
while ((num3 & 0x80) != 0);
98 dataStream.readRawData(data.data(), num);
113 if (prefix.isEmpty())
115 int index =
groups.indexOf(prefix);
131 auto index = std::find_if(std::begin(
arrays), std::end(
arrays),
132 [=](
const Array& a) {
return a.
name == prefix; });
134 if (index != std::end(
arrays)) {
135 array =
static_cast<int>(index - std::begin(
arrays));
148 auto index = std::find_if(std::begin(
arrays), std::end(
arrays),
149 [=](
const Array& a) {
return a.
name == prefix; });
151 if (index != std::end(
arrays)) {
152 array =
static_cast<int>(index - std::begin(
arrays));
155 index->size = std::max(index->size, size);
201 if (a.group !=
group)
204 for (
int vi : a.values) {
212 if (v.group ==
group && v.array == -1 && v.key == key)
231 if (!f.open(QIODevice::ReadOnly))
234 if (f.read(fmagic,
sizeof(fmagic)) !=
sizeof(fmagic))
236 return !memcmp(fmagic,
magic, 4) || tox_is_data_encrypted(
reinterpret_cast<uint8_t*
>(fmagic));
256 if (!f.open(QIODevice::Truncate | QIODevice::WriteOnly)) {
257 qWarning() <<
"Couldn't open file";
261 QByteArray data(
magic, 4);
262 QDataStream stream(&data, QIODevice::ReadWrite | QIODevice::Append);
263 stream.setVersion(QDataStream::Qt_5_0);
266 int numGroups = std::max(0,
groups.size());
267 for (
int g = -1; g < numGroups; ++g) {
284 for (
int vi : a.values) {
296 if (v.group != g || v.array != -1)
316 qCritical() <<
"Failed to write, can't save!";
323 if (!f.open(QIODevice::ReadOnly)) {
324 qWarning() <<
"Couldn't open file";
327 QByteArray data = f.readAll();
333 qCritical() <<
"The settings file is encrypted, but we don't have a passkey!";
338 if (data.isEmpty()) {
339 qCritical() <<
"Failed to decrypt the settings file";
344 qWarning() <<
"We have a password, but the settings file is not encrypted";
347 if (memcmp(data.data(),
magic, 4)) {
348 qWarning() <<
"Bad magic!";
353 QDataStream stream(&data, QIODevice::ReadOnly);
354 stream.setVersion(QDataStream::Qt_5_0);
356 while (!stream.atEnd()) {
364 setValue(QString::fromUtf8(key), QVariant(QString::fromUtf8(
value)));
375 if (sizeData.isEmpty()) {
376 qWarning(
"The personal save file is corrupted!");
382 QByteArray indexData;
384 if (indexData.isEmpty()) {
385 qWarning(
"The personal save file is corrupted!");
393 setValue(QString::fromUtf8(key), QVariant(QString::fromUtf8(
value)));
404 QSettings s(
path, QSettings::IniFormat);
410 if (!s.group().isEmpty())
413 for (QString k : s.childKeys()) {
418 gstack.push_back(QString());
419 for (QString g : s.childGroups())
423 while (!gstack.isEmpty()) {
424 QString g = gstack.takeLast();
426 if (gstack.isEmpty())
435 }
while (!gstack.isEmpty());
442 std::unique_ptr<int[]> groupSizes{
new int[
groups.size()]};
443 memset(groupSizes.get(), 0,
static_cast<size_t>(
groups.size()) *
sizeof(
int));
445 if (v.group < 0 || v.group >
groups.size())
447 groupSizes[
static_cast<size_t>(v.group)]++;
451 QVector<int> groupsToKill;
452 for (
int i =
values.size() - 1; i >= 0; i--) {
456 if (groupSizes[
static_cast<size_t>(v.
group)] != 1)
460 if (!v.
value.canConvert(QVariant::Int))
465 int slashIndex =
groups[
static_cast<int>(v.
group)].lastIndexOf(
'/');
466 if (slashIndex == -1) {
472 for (
int i = 0; i <
groups.size(); ++i)
477 groupSizes[
static_cast<size_t>(v.
group)]--;
478 groupsToKill.append(
static_cast<int>(v.
group));
484 for (
int ai = 0; ai <
arrays.size(); ++ai) {
488 arrayPrefix +=
groups[
static_cast<int>(a.
group)] +
'/';
489 arrayPrefix += a.
name +
'/';
492 for (
int g = 0; g <
groups.size(); ++g) {
493 if (!
groups[g].startsWith(arrayPrefix))
496 int groupArrayIndex =
groups[g].mid(arrayPrefix.size()).toInt(&ok);
499 groupsToKill.append(g);
501 if (groupArrayIndex > a.
size)
502 a.
size = groupArrayIndex;
505 for (
int vi =
values.size() - 1; vi >= 0; vi--) {
509 groupSizes[
static_cast<size_t>(g)]--;
519 std::sort(std::begin(groupsToKill), std::end(groupsToKill), std::greater_equal<int>());
521 for (
int g : groupsToKill) {
522 if (groupSizes[
static_cast<size_t>(g)])
540 assert(a.group !=
group);
545 assert(v.group !=
group);
554 assert(v.canConvert(QVariant::String));
555 QString str = v.toString();
558 else if (str ==
"false")