/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing ** ** This file is part of Qbs. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms and ** conditions see http://www.qt.io/terms-conditions. For further information ** use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ #if defined(WIN32) || defined(_WIN32) #define SCANNER_EXPORT __declspec(dllexport) #else #define SCANNER_EXPORT #endif #include "../scanner.h" #include #ifdef Q_OS_UNIX #include #include #include #include #include #else #include #endif #include #include #include struct Opaq { #ifdef Q_OS_UNIX int fd; int mapl; #else QFile *file; #endif char *map; QXmlStreamReader *xml; QByteArray current; Opaq() #ifdef Q_OS_UNIX : fd (0), #else : file(0), #endif map(0), xml(0) {} ~Opaq() { #ifdef Q_OS_UNIX if (map) munmap (map, mapl); if (fd) close (fd); #else delete file; #endif delete xml; } }; static void *openScanner(const unsigned short *filePath, int flags) { Q_UNUSED(flags); QScopedPointer opaque(new Opaq); #ifdef Q_OS_UNIX QString filePathS = QString::fromUtf16(filePath); opaque->fd = open(qPrintable(filePathS), O_RDONLY); if (opaque->fd == -1) { opaque->fd = 0; return 0; } struct stat s; int r = fstat(opaque->fd, &s); if (r != 0) return 0; opaque->mapl = s.st_size; void *map = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, opaque->fd, 0); if (map == 0) return 0; #else opaque->file = new QFile(QString::fromUtf16(filePath)); if (!opaque->file->open(QFile::ReadOnly)) return 0; uchar *map = opaque->file->map(0, opaque->file->size()); if (!map) return 0; #endif opaque->map = reinterpret_cast(map); opaque->xml = new QXmlStreamReader(opaque->map); return static_cast(opaque.take()); } static void closeScanner(void *ptr) { Opaq *opaque = static_cast(ptr); delete opaque; } static const char *nextQrc(void *opaq, int *size, int *flags) { Opaq *o= static_cast(opaq); while (!o->xml->atEnd()) { o->xml->readNext(); switch (o->xml->tokenType()) { case QXmlStreamReader::StartElement: if (o->xml->name() == QLatin1String("file")) { o->current = o->xml->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).toUtf8(); *flags = SC_LOCAL_INCLUDE_FLAG; *size = o->current.size(); return o->current.data(); } break; case QXmlStreamReader::EndDocument: return 0; default: break; } } return 0; } static const char **additionalFileTags(void *, int *size) { *size = 0; return 0; } extern "C" { ScannerPlugin qrcScanner = { "qt_qrc_scanner", "qrc", openScanner, closeScanner, nextQrc, additionalFileTags, NoScannerFlags }; ScannerPlugin *theScanners[] = {&qrcScanner, NULL}; SCANNER_EXPORT ScannerPlugin **getScanners() { return theScanners; } } // extern "C"