Warning, file /system/kjournald/lib/journaldexportreader.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-License-Identifier: LGPL-2.1-or-later OR MIT 0003 SPDX-FileCopyrightText: 2021 Andreas Cord-Landwehr <cordlandwehr@kde.org> 0004 */ 0005 0006 #include "journaldexportreader.h" 0007 #include "kjournaldlib_log_general.h" 0008 #include <QDebug> 0009 #include <QVector> 0010 #include <QIODevice> 0011 #include <climits> 0012 0013 JournaldExportReader::JournaldExportReader(QIODevice *device) 0014 : mDevice(device) 0015 { 0016 if (!mDevice || !mDevice->open(QIODevice::ReadOnly)) { 0017 qCCritical(KJOURNALDLIB_GENERAL) << "Could not open device for reading"; 0018 return; 0019 } 0020 } 0021 0022 bool JournaldExportReader::atEnd() const 0023 { 0024 return mDevice->atEnd(); 0025 } 0026 0027 // Format description: <https://www.freedesktop.org/wiki/Software/systemd/export/> 0028 // - Two journal entries that follow each other are separated by a double newline. 0029 // - Journal fields consisting only of valid non-control UTF-8 codepoints are serialized as they are 0030 // (i.e. the field name, followed by '=', followed by field data), followed by a newline as 0031 // separator to the next field. Note that fields containing newlines cannot be formatted like 0032 // this. Non-control UTF-8 codepoints are the codepoints with value at or above 32 (' '), or 0033 // equal to 9 (TAB). 0034 // - Other journal fields are serialized in a special binary safe way: field name, followed by 0035 // newline, followed by a binary 64bit little endian size value, followed by the binary field 0036 // data, followed by a newline as separator to the next field. 0037 // - Entry metadata that is not actually a field is serialized like it was a field, but beginning 0038 // with two underscores. More specifically, __CURSOR=, __REALTIME_TIMESTAMP=, 0039 // __MONOTONIC_TIMESTAMP= are introduced this way. Note that these meta-fields are only generated 0040 // when actual journal files are serialized. They are omitted for entries that do not originate 0041 // from a journal file (for example because they are transferred for the first time to be stored 0042 // in one). Or in other words: if you are generating this format you shouldn't care about these 0043 // special double-underscore fields. But you might find them usable when you deserialize the 0044 // format generated by us. Additional fields prefixed with two underscores might be added later 0045 // on, your parser should skip over the fields it does not know. 0046 // - The order in which fields appear in an entry is undefined and might be different for each entry 0047 // that is serialized. 0048 0049 bool JournaldExportReader::readNext() 0050 { 0051 if (mDevice->atEnd()) { 0052 return false; 0053 } 0054 0055 mCurrentEntry.clear(); 0056 while (!mDevice->atEnd()) { 0057 QString line = QString::fromLocal8Bit(mDevice->readLine().trimmed()); 0058 // empty line = beginning of new log entry 0059 if (line.isEmpty()) { 0060 break; // found break in log entry 0061 } 0062 0063 // if line does not contain "=" then switch to binary reading mode 0064 int separatorIndex = line.indexOf(QLatin1Char('=')); 0065 if (separatorIndex > 0) { 0066 mCurrentEntry[line.left(separatorIndex)] = line.right(line.length() - separatorIndex - 1).trimmed(); 0067 } else { 0068 QString fieldId = line; 0069 union { 0070 uint64_t uint64; 0071 char chars[4]; 0072 } size; 0073 qint64 bytes = mDevice->read(size.chars, 8); 0074 if (bytes != 8) { 0075 qCWarning(KJOURNALDLIB_GENERAL) << "Journal entry read that has unexpected number of bytes (8 bytes expected)" << bytes; 0076 } 0077 mCurrentEntry[fieldId] = QString::fromLocal8Bit(mDevice->read(le64toh(size.uint64))); 0078 // read line break after binary content, such that reader points to next line 0079 mDevice->read(1); 0080 } 0081 } 0082 0083 return true; 0084 } 0085 0086 JournaldExportReader::LogEntry JournaldExportReader::entry() const 0087 { 0088 return mCurrentEntry; 0089 }