File indexing completed on 2024-12-08 10:16:03

0001 /*
0002     SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include "abstractreader.h"
0007 #include "datatypes.h"
0008 #include "datasetmergebuffer.h"
0009 
0010 #include <QDebug>
0011 #include <QIODevice>
0012 
0013 #include <cassert>
0014 #include <cstring>
0015 
0016 using namespace OSM;
0017 
0018 namespace OSM {
0019 /** Readonly QIODevice adapter for memory-mapped data. */
0020 class MemoryMapIoDevice : public QIODevice
0021 {
0022     Q_OBJECT
0023 public:
0024     explicit MemoryMapIoDevice(const uint8_t *data, std::size_t size, QObject *parent = nullptr)
0025         : QIODevice(parent)
0026         , m_data(data)
0027         , m_size(size)
0028     {}
0029     ~MemoryMapIoDevice() = default;
0030 
0031     bool open(QIODevice::OpenMode mode) override
0032     {
0033         if (mode != QIODevice::ReadOnly) {
0034             return false;
0035         }
0036         return QIODevice::open(mode);
0037     }
0038 
0039     bool isSequential() const override
0040     {
0041         return false;
0042     }
0043 
0044     qint64 size() const override
0045     {
0046         return m_size;
0047     }
0048 
0049 protected:
0050     qint64 readData(char *data, qint64 maxlen) override
0051     {
0052         const auto readSize = std::min<qint64>(m_size - pos(), maxlen);
0053         if (readSize < 0) {
0054             return 0;
0055         }
0056         std::memcpy(data, reinterpret_cast<const char*>(m_data + pos()), readSize);
0057         return readSize;
0058     }
0059 
0060     qint64 writeData([[maybe_unused]] const char *data, [[maybe_unused]] qint64 len) override
0061     {
0062         return 0;
0063     }
0064 
0065 private:
0066     const uint8_t *m_data = nullptr;
0067     const std::size_t m_size = {};
0068 };
0069 }
0070 
0071 
0072 AbstractReader::AbstractReader(OSM::DataSet *dataSet)
0073     : m_dataSet(dataSet)
0074 {
0075     assert(dataSet);
0076 }
0077 
0078 AbstractReader::~AbstractReader() = default;
0079 
0080 void AbstractReader::setMergeBuffer(OSM::DataSetMergeBuffer *buffer)
0081 {
0082     m_mergeBuffer = buffer;
0083 }
0084 
0085 void AbstractReader::read(const uint8_t *data, std::size_t len)
0086 {
0087     readFromData(data, len);
0088     if (!m_error.isEmpty()) {
0089         qWarning() << m_error;
0090     }
0091 }
0092 
0093 void AbstractReader::read(QIODevice *io)
0094 {
0095     readFromIODevice(io);
0096     if (!m_error.isEmpty()) {
0097         qWarning() << m_error;
0098     }
0099 }
0100 
0101 void AbstractReader::readFromData(const uint8_t *data, std::size_t len)
0102 {
0103     assert(data);
0104     MemoryMapIoDevice io(data, len);
0105     io.open(QIODevice::ReadOnly);
0106     readFromIODevice(&io);
0107 }
0108 
0109 void AbstractReader::readFromIODevice(QIODevice *io)
0110 {
0111     assert(io);
0112     QByteArray data = io->readAll();
0113     readFromData(reinterpret_cast<const uint8_t*>(data.constData()), data.size());
0114 }
0115 
0116 QString AbstractReader::errorString() const
0117 {
0118     return m_error;
0119 }
0120 
0121 void AbstractReader::addNode(OSM::Node &&node)
0122 {
0123     m_mergeBuffer ? m_mergeBuffer->nodes.push_back(std::move(node)) : m_dataSet->addNode(std::move(node));
0124 }
0125 
0126 void AbstractReader::addWay(OSM::Way &&way)
0127 {
0128     m_mergeBuffer ? m_mergeBuffer->ways.push_back(std::move(way)) : m_dataSet->addWay(std::move(way));
0129 }
0130 
0131 void AbstractReader::addRelation(OSM::Relation &&relation)
0132 {
0133     m_mergeBuffer ? m_mergeBuffer->relations.push_back(std::move(relation)) : m_dataSet->addRelation(std::move(relation));
0134 }
0135 
0136 #include "abstractreader.moc"