File indexing completed on 2024-06-16 04:55:34
0001 /* 0002 SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include <kitinerary_version.h> 0007 0008 #include <../lib/plist/plistreader.cpp> 0009 #include "../lib/plist/plistdata_p.h" 0010 0011 #include <QCommandLineParser> 0012 #include <QCoreApplication> 0013 #include <QFile> 0014 #include <QJsonDocument> 0015 0016 #include <iostream> 0017 0018 using namespace KItinerary; 0019 0020 void dumpValue(const QVariant &v) 0021 { 0022 if (v.userType() == qMetaTypeId<PListArray>()) { 0023 const auto a = v.value<PListArray>(); 0024 std::cout << "["; 0025 for (uint64_t i = 0; i < a.size(); ++i) { 0026 std::cout << a.value(i); 0027 if (i != a.size() - 1) { 0028 std::cout << ","; 0029 } 0030 } 0031 std::cout << "]"; 0032 return; 0033 } 0034 0035 if (v.userType() == qMetaTypeId<PListDict>()) { 0036 const auto a = v.value<PListDict>(); 0037 std::cout << "{"; 0038 for (uint64_t i = 0; i < a.size(); ++i) { 0039 std::cout << a.key(i) << ":" << a.value(i); 0040 if (i != a.size() - 1) { 0041 std::cout << ", "; 0042 } 0043 } 0044 std::cout << "}"; 0045 return; 0046 } 0047 0048 if (v.userType() == qMetaTypeId<PListUid>()) { 0049 std::cout << "UID:" << v.value<PListUid>().value; 0050 return; 0051 } 0052 0053 std::cout << qPrintable(v.toString()); 0054 } 0055 0056 static void writeIndent(int indent) 0057 { 0058 while (indent) { 0059 std::cout << " "; 0060 --indent; 0061 } 0062 } 0063 0064 static void dumpRecursive(const PListReader &reader, uint64_t idx, int indent = 0) 0065 { 0066 const auto type = reader.objectType(idx); 0067 switch (type) { 0068 case PListObjectType::Array: 0069 { 0070 const auto a = reader.object(idx).value<PListArray>(); 0071 std::cout << "[" << std::endl; 0072 for (uint64_t i = 0; i < a.size(); ++i) { 0073 writeIndent(indent + 1); 0074 dumpRecursive(reader, a.value(i), indent + 1); 0075 } 0076 writeIndent(indent); 0077 std::cout << "]" << std::endl; 0078 break; 0079 } 0080 case PListObjectType::Dict: 0081 { 0082 const auto d = reader.object(idx).value<PListDict>(); 0083 std::cout << "{" << std::endl; 0084 for (uint64_t i = 0; i < d.size(); ++i) { 0085 writeIndent(indent + 1); 0086 dumpValue(reader.object(d.key(i))); 0087 std::cout << ": "; 0088 dumpRecursive(reader, d.value(i), indent + 1); 0089 } 0090 writeIndent(indent); 0091 std::cout << "}" << std::endl; 0092 break; 0093 } 0094 default: 0095 dumpValue(reader.object(idx)); 0096 std::cout << std::endl; 0097 } 0098 } 0099 0100 int main(int argc, char **argv) 0101 { 0102 QCoreApplication::setApplicationName(QStringLiteral("plist-dump")); 0103 QCoreApplication::setApplicationVersion(QStringLiteral(KITINERARY_VERSION_STRING)); 0104 QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); 0105 QCoreApplication::setOrganizationName(QStringLiteral("KDE")); 0106 QCoreApplication app(argc, argv); 0107 0108 QCommandLineParser parser; 0109 parser.setApplicationDescription(QStringLiteral("Dump binary plist content.")); 0110 parser.addHelpOption(); 0111 parser.addVersionOption(); 0112 parser.addPositionalArgument(QStringLiteral("input"), QStringLiteral("File to read data from, omit for using stdin.")); 0113 parser.process(app); 0114 0115 QFile file; 0116 if (parser.positionalArguments().isEmpty()) { 0117 file.open(stdin, QFile::ReadOnly); 0118 } else { 0119 file.setFileName(parser.positionalArguments().at(0)); 0120 if (!file.open(QFile::ReadOnly)) { 0121 std::cerr << qPrintable(file.errorString()) << std::endl; 0122 return 1; 0123 } 0124 } 0125 0126 const auto buffer = file.readAll(); 0127 PListReader reader(buffer); 0128 0129 // object list 0130 for (uint64_t i = 0; i < reader.objectCount(); ++i) { 0131 std::cout << i << ": [" << (int)reader.objectType(i) << "] "; 0132 dumpValue(reader.object(i)); 0133 std::cout << std::endl; 0134 } 0135 std::cout << std::endl << std::endl; 0136 0137 // object tree 0138 dumpRecursive(reader, reader.rootObjectIndex()); 0139 std::cout << std::endl << std::endl; 0140 0141 // NSKeyedArchiver 0142 std::cout << QJsonDocument(reader.unpackKeyedArchive().toObject()).toJson().constData() << std::endl; 0143 } 0144