├── .gitignore ├── CMakeLists.txt ├── Info.plist ├── LICENSE ├── README.md ├── about.cpp ├── about.h ├── about.ui ├── debian ├── changelog ├── compat ├── control ├── copyright ├── extract-icons ├── rules └── source │ └── format ├── directoryloader.cpp ├── directoryloader.h ├── directoryloader.ui ├── dot.cpp ├── dot.h ├── extra └── yaml-cpp │ ├── include │ └── yaml-cpp │ │ ├── anchor.h │ │ ├── binary.h │ │ ├── contrib │ │ ├── anchordict.h │ │ └── graphbuilder.h │ │ ├── dll.h │ │ ├── emitfromevents.h │ │ ├── emitter.h │ │ ├── emitterdef.h │ │ ├── emittermanip.h │ │ ├── emitterstyle.h │ │ ├── eventhandler.h │ │ ├── exceptions.h │ │ ├── mark.h │ │ ├── node │ │ ├── convert.h │ │ ├── detail │ │ │ ├── bool_type.h │ │ │ ├── impl.h │ │ │ ├── iterator.h │ │ │ ├── iterator_fwd.h │ │ │ ├── memory.h │ │ │ ├── node.h │ │ │ ├── node_data.h │ │ │ ├── node_iterator.h │ │ │ └── node_ref.h │ │ ├── emit.h │ │ ├── impl.h │ │ ├── iterator.h │ │ ├── node.h │ │ ├── parse.h │ │ ├── ptr.h │ │ └── type.h │ │ ├── noncopyable.h │ │ ├── null.h │ │ ├── ostream_wrapper.h │ │ ├── parser.h │ │ ├── stlemitter.h │ │ ├── traits.h │ │ └── yaml.h │ └── src │ ├── binary.cpp │ ├── collectionstack.h │ ├── contrib │ ├── graphbuilder.cpp │ ├── graphbuilderadapter.cpp │ └── graphbuilderadapter.h │ ├── convert.cpp │ ├── directives.cpp │ ├── directives.h │ ├── emit.cpp │ ├── emitfromevents.cpp │ ├── emitter.cpp │ ├── emitterstate.cpp │ ├── emitterstate.h │ ├── emitterutils.cpp │ ├── emitterutils.h │ ├── exceptions.cpp │ ├── exp.cpp │ ├── exp.h │ ├── indentation.h │ ├── memory.cpp │ ├── node.cpp │ ├── node_data.cpp │ ├── nodebuilder.cpp │ ├── nodebuilder.h │ ├── nodeevents.cpp │ ├── nodeevents.h │ ├── null.cpp │ ├── ostream_wrapper.cpp │ ├── parse.cpp │ ├── parser.cpp │ ├── ptr_vector.h │ ├── regex_yaml.cpp │ ├── regex_yaml.h │ ├── regeximpl.h │ ├── scanner.cpp │ ├── scanner.h │ ├── scanscalar.cpp │ ├── scanscalar.h │ ├── scantag.cpp │ ├── scantag.h │ ├── scantoken.cpp │ ├── setting.h │ ├── simplekey.cpp │ ├── singledocparser.cpp │ ├── singledocparser.h │ ├── stream.cpp │ ├── stream.h │ ├── streamcharsource.h │ ├── stringsource.h │ ├── tag.cpp │ ├── tag.h │ └── token.h ├── imagefile.cpp ├── imagefile.h ├── images ├── plates.icns └── plates.ico ├── imageview.cpp ├── imageview.h ├── imageview.ui ├── imageviewerbase.cpp ├── imageviewerbase.h ├── imageviewerobserver.cpp ├── imageviewerobserver.h ├── imageviewerplateselector.cpp ├── imageviewerplateselector.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── man └── plates.1 ├── options.cpp ├── options.h ├── options.ui ├── platefile.cpp ├── platefile.h ├── plates-yaml.h ├── plates.desktop ├── plates.iss ├── plates.pro ├── plates.qrc ├── plates.rc ├── plateselector.cpp ├── plateselector.h ├── plateselector.ui ├── polygons.cpp ├── polygons.h ├── qprogressindicator ├── QProgressIndicator.cpp └── QProgressIndicator.h ├── selection.cpp ├── selection.h ├── settings.cpp ├── settings.h ├── squeezedlabel.cpp ├── squeezedlabel.h ├── threadedimageloader.cpp ├── threadedimageloader.h ├── utils.cpp └── utils.h /.gitignore: -------------------------------------------------------------------------------- 1 | plates.exe 2 | *.app 3 | obj 4 | *.pro.user* 5 | *~ 6 | *.autosave 7 | *.a 8 | *.core 9 | *.moc 10 | *.o 11 | *.obj 12 | *.orig 13 | *.rej 14 | *_pch.h.cpp 15 | *_resource.rc 16 | *.qm 17 | .#* 18 | *.*# 19 | core 20 | !core/ 21 | tags 22 | .DS_Store 23 | .directory 24 | *.debug 25 | Makefile* 26 | *.prl 27 | *.app 28 | moc_*.cpp 29 | ui_*.h 30 | qrc_*.cpp 31 | Thumbs.db 32 | *.res 33 | /.qmake.cache 34 | /.qmake.stash 35 | build/ 36 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.11) 2 | 3 | project(openalpr_tagger) 4 | 5 | SET(VERSION_MAJOR 1) 6 | SET(VERSION_MINOR 0) 7 | SET(VERSION_PATCH 0) 8 | 9 | SET (VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") 10 | add_definitions(-DVERSION_MAJOR=${VERSION_MAJOR}) 11 | add_definitions(-DVERSION_MINOR=${VERSION_MINOR}) 12 | add_definitions(-DVERSION_PATCH=${VERSION_PATCH}) 13 | add_definitions(-DVERSION_STRING="${VERSION}") 14 | 15 | 16 | add_definitions(-DTARGET="openalpr_tagger") 17 | add_definitions(-DTARGET_STRING="openalpr_tagger") 18 | add_definitions(-DTARGET_UPPER_STRING="OPENALPR_TAGGER") 19 | add_definitions(-DTARGET_HUMAN_STRING="openalpr_tagger") 20 | 21 | ADD_DEFINITIONS( 22 | -std=c++11 23 | ) 24 | 25 | 26 | # Find the QtWidgets library 27 | find_package(Qt5Widgets) 28 | 29 | set(CMAKE_AUTOMOC ON) 30 | set(CMAKE_AUTOUIC ON) 31 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 32 | 33 | # Tell CMake to create the helloworld executable 34 | add_executable(openalpr_tagger 35 | about.cpp 36 | directoryloader.cpp 37 | dot.cpp 38 | imagefile.cpp 39 | imageview.cpp 40 | imageviewerbase.cpp 41 | imageviewerobserver.cpp 42 | imageviewerplateselector.cpp 43 | main.cpp 44 | mainwindow.cpp 45 | options.cpp 46 | platefile.cpp 47 | plateselector.cpp 48 | polygons.cpp 49 | selection.cpp 50 | settings.cpp 51 | squeezedlabel.cpp 52 | threadedimageloader.cpp 53 | utils.cpp 54 | qprogressindicator/QProgressIndicator.cpp 55 | 56 | extra/yaml-cpp/src/nodeevents.cpp 57 | extra/yaml-cpp/src/exceptions.cpp 58 | extra/yaml-cpp/src/nodebuilder.cpp 59 | extra/yaml-cpp/src/contrib/graphbuilder.cpp 60 | extra/yaml-cpp/src/contrib/graphbuilderadapter.cpp 61 | extra/yaml-cpp/src/exp.cpp 62 | extra/yaml-cpp/src/binary.cpp 63 | extra/yaml-cpp/src/null.cpp 64 | extra/yaml-cpp/src/parser.cpp 65 | extra/yaml-cpp/src/convert.cpp 66 | extra/yaml-cpp/src/scantag.cpp 67 | extra/yaml-cpp/src/singledocparser.cpp 68 | extra/yaml-cpp/src/scanner.cpp 69 | extra/yaml-cpp/src/directives.cpp 70 | extra/yaml-cpp/src/emitterstate.cpp 71 | extra/yaml-cpp/src/node_data.cpp 72 | extra/yaml-cpp/src/scanscalar.cpp 73 | extra/yaml-cpp/src/scantoken.cpp 74 | extra/yaml-cpp/src/node.cpp 75 | extra/yaml-cpp/src/regex_yaml.cpp 76 | extra/yaml-cpp/src/emitfromevents.cpp 77 | extra/yaml-cpp/src/emitterutils.cpp 78 | extra/yaml-cpp/src/tag.cpp 79 | extra/yaml-cpp/src/memory.cpp 80 | extra/yaml-cpp/src/simplekey.cpp 81 | extra/yaml-cpp/src/ostream_wrapper.cpp 82 | extra/yaml-cpp/src/emit.cpp 83 | extra/yaml-cpp/src/emitter.cpp 84 | extra/yaml-cpp/src/stream.cpp 85 | extra/yaml-cpp/src/parse.cpp 86 | 87 | ) 88 | 89 | include_directories( 90 | ${CMAKE_SOURCE_DIR}/qprogressindicator 91 | ${CMAKE_SOURCE_DIR}/extra/yaml-cpp/include/ 92 | ) 93 | 94 | # Use the Widgets module from Qt 5. 95 | target_link_libraries(openalpr_tagger Qt5::Widgets) 96 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrincipalClass 6 | NSApplication 7 | NSHumanReadableCopyright 8 | (C) 2017, Dmitry Baryshev 9 | CFBundleDevelopmentRegion 10 | en 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleIconFile 14 | plates.icns 15 | CFBundlePackageType 16 | APPL 17 | CFBundleGetInfoString 18 | OpenALPR Training Utility 19 | CFBundleSignature 20 | ???? 21 | CFBundleExecutable 22 | plates 23 | CFBundleIdentifier 24 | net.plates 25 | CFBundleName 26 | OpenALPR Training Utility 27 | CFBundleDisplayName 28 | OpenALPR Training Utility 29 | CFBundleShortVersionString 30 | 1.1.0 31 | CFBundleVersion 32 | 1.1.0 33 | 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenALPR Plate Tagger 2 | 3 | This utility is used to annotate images with the location and numbers of the license plates. These annotated images can be used to train the OpenALPR algorithm to recognize license plates accurately. 4 | 5 | The utility is a QT graphical user interface written in C++: 6 | ![Plate Image](http://www.openalpr.com/images/demoscreenshots/tagger_screenshot.jpg "Input image") 7 | 8 | ## Installation 9 | 10 | Download an installer for Windows, Ubuntu Linux, or Mac OS from the Releases tab. Alternatively, you can compile the tool yourself using `qmake` or `cmake`. Eg. on a Fedora-based system (assuming that the required tools are already installed): 11 | 12 | ```bash 13 | $ git clone https://github.com/openalpr/plate_tagger.git 14 | $ cd plate_tagger 15 | $ mkdir build && cd build 16 | $ cmake .. 17 | $ make 18 | $ ./openalpr_tagger 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /about.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "about.h" 4 | #include "ui_about.h" 5 | 6 | About::About(QWidget *parent) 7 | : QDialog(parent) 8 | , ui(new Ui::About) 9 | { 10 | ui->setupUi(this); 11 | 12 | ui->labelProduct->setText(TARGET_HUMAN_STRING); 13 | ui->labelVersion->setText(tr("Version %1").arg(VERSION_STRING)); 14 | ui->labelIcon->setPixmap(QIcon(":/images/" TARGET_STRING ".ico").pixmap(48, 48)); 15 | 16 | // %1 will be replaced with a product name 17 | ui->labelWarranty->setText(tr("%1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") 18 | .arg(TARGET_HUMAN_STRING)); 19 | 20 | #ifdef Q_OS_MAC 21 | ui->pushOK->hide(); 22 | #else 23 | setWindowTitle(tr("About")); 24 | #endif 25 | 26 | adjustSize(); 27 | } 28 | 29 | About::~About() 30 | { 31 | delete ui; 32 | } 33 | -------------------------------------------------------------------------------- /about.h: -------------------------------------------------------------------------------- 1 | #ifndef ABOUT_H 2 | #define ABOUT_H 3 | 4 | #include 5 | 6 | namespace Ui 7 | { 8 | class About; 9 | } 10 | 11 | class About : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit About(QWidget *parent = 0); 17 | ~About(); 18 | 19 | private: 20 | Ui::About *ui; 21 | }; 22 | 23 | #endif // ABOUT_H 24 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | plates (1.1.0-1) unstable; urgency=medium 2 | 3 | * Allow loading standalone non-numbered YAML files. 4 | 5 | -- Dmitry Baryshev Wed, 17 May 2017 16:35:07 +0300 6 | 7 | plates (1.0.0-1) unstable; urgency=medium 8 | 9 | * Initial release. 10 | 11 | -- Dmitry Baryshev Fri, 07 Apr 2017 14:51:50 +0300 12 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: plates 2 | Section: education 3 | Priority: extra 4 | Maintainer: Dmitry Baryshev 5 | XSBC-Original-Maintainer: Dmitry Baryshev 6 | Uploaders: Dmitry Baryshev 7 | Build-Depends: debhelper (>= 9), qtbase5-dev, qttools5-dev-tools, imagemagick 8 | Standards-Version: 3.9.4 9 | Homepage: https://github.com/openalpr/openalpr 10 | #Vcs-Git: 11 | #Vcs-Browser: 12 | 13 | Package: plates 14 | Architecture: any 15 | Multi-Arch: foreign 16 | Depends: ${misc:Depends}, ${shlibs:Depends} 17 | Description: Plates is an OpenALPR training utility 18 | to manually find and mark license plates on photos 19 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: plates 3 | Source: https://github.com/openalpr/openalpr 4 | 5 | Files: * 6 | Copyright: 2017 Dmitry Baryshev 7 | License: 8 | 9 | Files: debian/* 10 | Copyright: 2016 Dmitry Baryshev 11 | License: LGPL-2.1 12 | 13 | License: GPL-3 14 | GNU General Public License Usage 15 | . 16 | Alternatively, this file may be used under the terms of the GNU 17 | General Public License version 3.0 as published by the Free Software 18 | Foundation and appearing in the file LICENSE.GPL included in the 19 | packaging of this file. Please review the following information to 20 | ensure the GNU General Public License version 3.0 requirements will be 21 | met: http://www.gnu.org/copyleft/gpl.html. 22 | . 23 | On Debian systems, the complete text of the license can be found in 24 | `/usr/share/common-licenses/GPL-3`. 25 | 26 | License: LGPL-2.1 27 | This file may be used under the terms of the GNU Lesser 28 | General Public License version 2.1 as published by the Free Software 29 | Foundation and appearing in the file LICENSE.LGPL included in the 30 | packaging of this file. Please review the following information to 31 | ensure the GNU Lesser General Public License version 2.1 requirements 32 | will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 33 | . 34 | On Debian systems, the complete text of the LGPL-2.1 license can be found in 35 | `/usr/share/common-licenses/LGPL-2.1`, 36 | -------------------------------------------------------------------------------- /debian/extract-icons: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | if ! which identify >/dev/null 2>&1; then 4 | echo "Fatal: 'identify' is not installed" >&2 5 | exit 1 6 | fi 7 | 8 | if ! which convert >/dev/null 2>&1; then 9 | echo "Fatal: 'convert' is not installed" >&2 10 | exit 1 11 | fi 12 | 13 | ico="$1" 14 | template="$2" 15 | 16 | ###################################### 17 | 18 | identify "$ico" | while read str; do 19 | name="$(echo "$str" | awk '{ print $1 }')" 20 | res="$(echo "$str" | awk '{ print $3 }')" 21 | 22 | if [ -z "$name" -o -z "$res" ]; then 23 | echo "Cannot extract icons information" >&2 24 | exit 1 25 | fi 26 | 27 | convert "$name" "$template-$res.png" 28 | 29 | echo "$res" 30 | done 31 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) 4 | 5 | # Qt5 6 | export QT_SELECT := qt5 7 | 8 | %: 9 | dh $@ --parallel 10 | 11 | override_dh_auto_configure: 12 | qmake CONFIG+=release 13 | 14 | override_dh_auto_install: 15 | install -D -m 755 plates $(CURDIR)/debian/plates/usr/bin/plates 16 | strip $(CURDIR)/debian/plates/usr/bin/plates 17 | # extract and install icons 18 | $(CURDIR)/debian/extract-icons images/plates.ico plates | while read res; do \ 19 | install -D -m 644 plates-$${res}.png $(CURDIR)/debian/plates/usr/share/icons/hicolor/$${res}/apps/plates.png; \ 20 | rm -f plates-$${res}.png; \ 21 | done 22 | # # install icons 23 | # for i in 16 32 48 64 128 256; do install -D -m 644 plates-$${i}x$${i}.png $(CURDIR)/debian/plates/usr/share/icons/hicolor/$${i}x$${i}/apps/plates.png; done 24 | # for i in 16 32 48 64 128 256; do rm -f plates-$${i}x$${i}.png; done 25 | install -D -m 644 man/plates.1 $(CURDIR)/debian/plates/usr/share/man/man1/plates.1 26 | install -D -m 644 plates.desktop $(CURDIR)/debian/plates/usr/share/applications/plates.desktop 27 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /directoryloader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "directoryloader.h" 5 | #include "utils.h" 6 | #include "ui_directoryloader.h" 7 | 8 | DirectoryLoader::DirectoryLoader(const QString &dirPath, QWidget *parent) 9 | : QDialog(parent) 10 | , ui(new Ui::DirectoryLoader) 11 | , m_step(Step::Images) 12 | , m_heapPlates(0) 13 | { 14 | ui->setupUi(this); 15 | setWindowFlags(windowFlags() | Qt::FramelessWindowHint); 16 | 17 | // images iterator 18 | m_iterator = new QDirIterator(dirPath, 19 | Utils::imageMatchingWildcard(), 20 | QDir::Files | QDir::Readable); 21 | 22 | ui->progress->startAnimation(); 23 | 24 | // start iterating immediately 25 | QTimer::singleShot(0, this, SLOT(slotLoadNext())); 26 | } 27 | 28 | DirectoryLoader::~DirectoryLoader() 29 | { 30 | delete m_iterator; 31 | delete ui; 32 | } 33 | 34 | void DirectoryLoader::keyPressEvent(QKeyEvent *e) 35 | { 36 | if(e->key() == Qt::Key_Escape) 37 | { 38 | e->accept(); 39 | return; 40 | } 41 | 42 | QDialog::keyPressEvent(e); 43 | } 44 | 45 | void DirectoryLoader::slotLoadNext() 46 | { 47 | if(m_step == Step::Images) 48 | { 49 | if(m_iterator->hasNext()) 50 | { 51 | m_iterator->next(); 52 | 53 | // append file & update status label 54 | m_imageFiles.append(m_iterator->fileInfo()); 55 | ui->labelFound->setNum(m_imageFiles.size()); 56 | 57 | // next iteration 58 | QTimer::singleShot(0, this, SLOT(slotLoadNext())); 59 | } 60 | else 61 | { 62 | if(m_imageFiles.isEmpty()) 63 | reject(); 64 | else 65 | { 66 | m_step = Step::Plates; 67 | 68 | // YAML iterator 69 | const QString &dirPath = m_iterator->path(); 70 | ui->labelFoundText->setText(tr("Found plates:")); 71 | 72 | delete m_iterator; 73 | m_iterator = new QDirIterator(dirPath, 74 | QStringList() << "*.yaml" << "*.YAML", 75 | QDir::Files | QDir::Readable); 76 | 77 | // next iteration 78 | QTimer::singleShot(0, this, SLOT(slotLoadNext())); 79 | } 80 | } 81 | } 82 | else 83 | { 84 | if(m_iterator->hasNext()) 85 | { 86 | m_iterator->next(); 87 | 88 | PlateFile plateFileInHeap(m_iterator->fileInfo().absoluteFilePath()); 89 | 90 | if(!plateFileInHeap.isValid()) 91 | { 92 | // next iteration 93 | QTimer::singleShot(0, this, SLOT(slotLoadNext())); 94 | return; 95 | } 96 | 97 | bool handled = false; 98 | ImageFile *correspondingImageFile = nullptr; 99 | 100 | for(int i = 0;i < m_imageFiles.size();i++) 101 | { 102 | ImageFile &imageFile = m_imageFiles[i]; 103 | 104 | // found the corresponding image in cache, e.g. 105 | // YAML::image_file == image file in cache 106 | if(plateFileInHeap.imageFile() == imageFile.fileInfo().fileName()) 107 | { 108 | correspondingImageFile = &imageFile; 109 | 110 | foreach(const PlateFile &plateFile, imageFile.plates()) 111 | { 112 | // already handled (autonumbered like car-nnn.yaml) 113 | if(m_iterator->fileInfo() == QFileInfo(plateFile.plateFile())) 114 | { 115 | qDebug("Plate '%s' is already handled, skipping", qPrintable(m_iterator->fileInfo().fileName())); 116 | handled = true; 117 | break; 118 | } 119 | } 120 | 121 | break; 122 | } 123 | } 124 | 125 | // append plate & update status label 126 | if(!handled) 127 | { 128 | if(correspondingImageFile) 129 | { 130 | qDebug("New plate in heap '%s' -> '%s'", 131 | qPrintable(m_iterator->fileInfo().fileName()), 132 | qPrintable(correspondingImageFile->fileInfo().fileName())); 133 | 134 | correspondingImageFile->addPlate(m_iterator->fileInfo().absoluteFilePath()); 135 | ui->labelFound->setNum(++m_heapPlates); 136 | } 137 | else 138 | { 139 | qWarning("Lost plate with no corresponding image '%s'", qPrintable(m_iterator->fileInfo().absoluteFilePath())); 140 | m_lostPlates.append(m_iterator->fileInfo().fileName()); 141 | } 142 | } 143 | 144 | // next iteration 145 | QTimer::singleShot(0, this, SLOT(slotLoadNext())); 146 | } 147 | else 148 | { 149 | if(!m_lostPlates.isEmpty()) 150 | Utils::warning(tr("YAML files without corresponding images:\n\n%1").arg(m_lostPlates.join("\n")), this); 151 | 152 | accept(); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /directoryloader.h: -------------------------------------------------------------------------------- 1 | #ifndef DIRECTORYLOADER_H 2 | #define DIRECTORYLOADER_H 3 | 4 | #include 5 | #include 6 | 7 | #include "imagefile.h" 8 | 9 | class QDirIterator; 10 | 11 | namespace Ui 12 | { 13 | class DirectoryLoader; 14 | } 15 | 16 | /* 17 | * Directory loader with a spinning progress indicator. Calls accept() 18 | * when some files has been found 19 | */ 20 | class DirectoryLoader : public QDialog 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit DirectoryLoader(const QString &dirPath, QWidget *parent = 0); 26 | ~DirectoryLoader(); 27 | 28 | /* 29 | * Found image files 30 | */ 31 | ImageFileList imageFiles() const; 32 | 33 | protected: 34 | virtual void keyPressEvent(QKeyEvent *e) override; 35 | 36 | private slots: 37 | void slotLoadNext(); 38 | 39 | private: 40 | Ui::DirectoryLoader *ui; 41 | enum class Step { Images, Plates } m_step; 42 | QDirIterator *m_iterator; 43 | ImageFileList m_imageFiles; 44 | int m_heapPlates; 45 | QStringList m_lostPlates; 46 | }; 47 | 48 | inline 49 | ImageFileList DirectoryLoader::imageFiles() const 50 | { 51 | return m_imageFiles; 52 | } 53 | 54 | #endif // DIRECTORYLOADER_H 55 | -------------------------------------------------------------------------------- /directoryloader.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DirectoryLoader 4 | 5 | 6 | 7 | 0 8 | 0 9 | 167 10 | 40 11 | 12 | 13 | 14 | 15 | 0 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 28 | 29 | QFrame::Box 30 | 31 | 32 | 33 | 34 | 35 | Found images: 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 1 44 | 0 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 20 54 | 20 55 | 56 | 57 | 58 | 59 | 20 60 | 20 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | QProgressIndicator 73 | QWidget 74 |
QProgressIndicator.h
75 | 1 76 |
77 |
78 | 79 | 80 |
81 | -------------------------------------------------------------------------------- /dot.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "imageviewerplateselector.h" 6 | #include "utils.h" 7 | #include "dot.h" 8 | 9 | constexpr int DOT_WIDTH = 14; 10 | constexpr int DOT_HEIGHT = 14; 11 | 12 | Dot::Dot(QWidget *parent) 13 | : QWidget(parent) 14 | , inMove(false) 15 | { 16 | setMouseTracking(true); 17 | setFixedSize(DOT_WIDTH, DOT_HEIGHT); 18 | show(); 19 | } 20 | 21 | void Dot::mousePressEvent(QMouseEvent *e) 22 | { 23 | e->accept(); 24 | 25 | m_lastMousePoint = e->pos(); 26 | inMove = true; 27 | } 28 | 29 | void Dot::mouseMoveEvent(QMouseEvent *e) 30 | { 31 | e->accept(); 32 | 33 | if(!inMove) 34 | return; 35 | 36 | dragTo(e->pos()); 37 | } 38 | 39 | void Dot::mouseReleaseEvent(QMouseEvent *e) 40 | { 41 | e->accept(); 42 | 43 | dragTo(e->pos()); 44 | 45 | emit moved(); 46 | 47 | inMove = false; 48 | } 49 | 50 | void Dot::dragTo(const QPoint &pos) 51 | { 52 | ImageViewerPlateSelector *plateSelectorParent = qobject_cast(parent()); 53 | 54 | if(!plateSelectorParent) 55 | { 56 | qWarning("Parent must be of class ImageViewerPlateSelector"); 57 | return; 58 | } 59 | 60 | const QPoint &targetPos = this->pos() + (pos - m_lastMousePoint); 61 | 62 | if(plateSelectorParent->acceptableDotPosition(QRect(targetPos, size()))) 63 | { 64 | move(targetPos); 65 | emit moving(); 66 | } 67 | } 68 | 69 | void Dot::paintEvent(QPaintEvent *e) 70 | { 71 | QPainter painter(this); 72 | 73 | painter.setClipRegion(e->region()); 74 | painter.setRenderHint(QPainter::Antialiasing); 75 | 76 | painter.setPen(Utils::polygonPaintingPen()); 77 | painter.setBrush(painter.pen().brush()); 78 | 79 | // squeeze the ellipse by the pen width 80 | painter.drawEllipse(painter.pen().width(), 81 | painter.pen().width(), 82 | width() - painter.pen().width()*2, 83 | height() - painter.pen().width()*2); 84 | } 85 | -------------------------------------------------------------------------------- /dot.h: -------------------------------------------------------------------------------- 1 | #ifndef DOT_H 2 | #define DOT_H 3 | 4 | #include 5 | #include 6 | 7 | /* 8 | * Represents a single polygon dot in a plate selector 9 | */ 10 | class Dot : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | Dot(QWidget *parent = nullptr); 16 | 17 | /* 18 | * Center point of the dot in parent's coordinates 19 | */ 20 | void setCenterPoint(const QPoint ¢er); 21 | 22 | /* 23 | * Center point 24 | */ 25 | QPoint centerPoint() const; 26 | 27 | /* 28 | * Appropriate not scaled point in the original image in pixels 29 | */ 30 | void setPointInImage(const QPoint &point); 31 | QPoint pointInImage() const; 32 | 33 | protected: 34 | virtual void mousePressEvent(QMouseEvent *e) override; 35 | virtual void mouseMoveEvent(QMouseEvent *e) override; 36 | virtual void mouseReleaseEvent(QMouseEvent *e) override; 37 | virtual void paintEvent(QPaintEvent *e) override; 38 | 39 | private: 40 | QPoint relativeCenter() const; 41 | void dragTo(const QPoint &pos); 42 | 43 | signals: 44 | void moving(); 45 | void moved(); 46 | 47 | private: 48 | QPoint m_lastMousePoint; 49 | QPoint m_pointInImage; 50 | bool inMove; 51 | }; 52 | 53 | inline 54 | void Dot::setCenterPoint(const QPoint ¢er) 55 | { 56 | move(center - relativeCenter()); 57 | } 58 | 59 | inline 60 | QPoint Dot::centerPoint() const 61 | { 62 | return pos() + relativeCenter(); 63 | } 64 | 65 | inline 66 | void Dot::setPointInImage(const QPoint &point) 67 | { 68 | m_pointInImage = point; 69 | } 70 | 71 | inline 72 | QPoint Dot::pointInImage() const 73 | { 74 | return m_pointInImage; 75 | } 76 | 77 | inline 78 | QPoint Dot::relativeCenter() const 79 | { 80 | return QPoint(width()/2, height()/2); 81 | } 82 | 83 | #endif // DOT_H 84 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/anchor.h: -------------------------------------------------------------------------------- 1 | #ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | namespace YAML { 13 | typedef std::size_t anchor_t; 14 | const anchor_t NullAnchor = 0; 15 | } 16 | 17 | #endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 18 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/binary.h: -------------------------------------------------------------------------------- 1 | #ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | #include "yaml-cpp/dll.h" 14 | 15 | namespace YAML { 16 | YAML_CPP_API std::string EncodeBase64(const unsigned char *data, 17 | std::size_t size); 18 | YAML_CPP_API std::vector DecodeBase64(const std::string &input); 19 | 20 | class YAML_CPP_API Binary { 21 | public: 22 | Binary() : m_unownedData(0), m_unownedSize(0) {} 23 | Binary(const unsigned char *data_, std::size_t size_) 24 | : m_unownedData(data_), m_unownedSize(size_) {} 25 | 26 | bool owned() const { return !m_unownedData; } 27 | std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } 28 | const unsigned char *data() const { 29 | return owned() ? &m_data[0] : m_unownedData; 30 | } 31 | 32 | void swap(std::vector &rhs) { 33 | if (m_unownedData) { 34 | m_data.swap(rhs); 35 | rhs.clear(); 36 | rhs.resize(m_unownedSize); 37 | std::copy(m_unownedData, m_unownedData + m_unownedSize, rhs.begin()); 38 | m_unownedData = 0; 39 | m_unownedSize = 0; 40 | } else { 41 | m_data.swap(rhs); 42 | } 43 | } 44 | 45 | bool operator==(const Binary &rhs) const { 46 | const std::size_t s = size(); 47 | if (s != rhs.size()) 48 | return false; 49 | const unsigned char *d1 = data(); 50 | const unsigned char *d2 = rhs.data(); 51 | for (std::size_t i = 0; i < s; i++) { 52 | if (*d1++ != *d2++) 53 | return false; 54 | } 55 | return true; 56 | } 57 | 58 | bool operator!=(const Binary &rhs) const { return !(*this == rhs); } 59 | 60 | private: 61 | std::vector m_data; 62 | const unsigned char *m_unownedData; 63 | std::size_t m_unownedSize; 64 | }; 65 | } 66 | 67 | #endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 68 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/contrib/anchordict.h: -------------------------------------------------------------------------------- 1 | #ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "../anchor.h" 13 | 14 | namespace YAML { 15 | /** 16 | * An object that stores and retrieves values correlating to {@link anchor_t} 17 | * values. 18 | * 19 | *

Efficient implementation that can make assumptions about how 20 | * {@code anchor_t} values are assigned by the {@link Parser} class. 21 | */ 22 | template 23 | class AnchorDict { 24 | public: 25 | void Register(anchor_t anchor, T value) { 26 | if (anchor > m_data.size()) { 27 | m_data.resize(anchor); 28 | } 29 | m_data[anchor - 1] = value; 30 | } 31 | 32 | T Get(anchor_t anchor) const { return m_data[anchor - 1]; } 33 | 34 | private: 35 | std::vector m_data; 36 | }; 37 | } 38 | 39 | #endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 40 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/dll.h: -------------------------------------------------------------------------------- 1 | #ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | // The following ifdef block is the standard way of creating macros which make 11 | // exporting from a DLL simpler. All files within this DLL are compiled with the 12 | // yaml_cpp_EXPORTS symbol defined on the command line. This symbol should not 13 | // be defined on any project that uses this DLL. This way any other project 14 | // whose source files include this file see YAML_CPP_API functions as being 15 | // imported from a DLL, whereas this DLL sees symbols defined with this macro as 16 | // being exported. 17 | #undef YAML_CPP_API 18 | 19 | #ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined 20 | // manually) 21 | #ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake 22 | // or defined manually) 23 | // #pragma message( "Defining YAML_CPP_API for DLL export" ) 24 | #define YAML_CPP_API __declspec(dllexport) 25 | #else // yaml_cpp_EXPORTS 26 | // #pragma message( "Defining YAML_CPP_API for DLL import" ) 27 | #define YAML_CPP_API __declspec(dllimport) 28 | #endif // yaml_cpp_EXPORTS 29 | #else // YAML_CPP_DLL 30 | #define YAML_CPP_API 31 | #endif // YAML_CPP_DLL 32 | 33 | #endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 34 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/emitfromevents.h: -------------------------------------------------------------------------------- 1 | #ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "yaml-cpp/anchor.h" 13 | #include "yaml-cpp/emitterstyle.h" 14 | #include "yaml-cpp/eventhandler.h" 15 | 16 | namespace YAML { 17 | struct Mark; 18 | } // namespace YAML 19 | 20 | namespace YAML { 21 | class Emitter; 22 | 23 | class EmitFromEvents : public EventHandler { 24 | public: 25 | EmitFromEvents(Emitter& emitter); 26 | 27 | virtual void OnDocumentStart(const Mark& mark); 28 | virtual void OnDocumentEnd(); 29 | 30 | virtual void OnNull(const Mark& mark, anchor_t anchor); 31 | virtual void OnAlias(const Mark& mark, anchor_t anchor); 32 | virtual void OnScalar(const Mark& mark, const std::string& tag, 33 | anchor_t anchor, const std::string& value); 34 | 35 | virtual void OnSequenceStart(const Mark& mark, const std::string& tag, 36 | anchor_t anchor, EmitterStyle::value style); 37 | virtual void OnSequenceEnd(); 38 | 39 | virtual void OnMapStart(const Mark& mark, const std::string& tag, 40 | anchor_t anchor, EmitterStyle::value style); 41 | virtual void OnMapEnd(); 42 | 43 | private: 44 | void BeginNode(); 45 | void EmitProps(const std::string& tag, anchor_t anchor); 46 | 47 | private: 48 | Emitter& m_emitter; 49 | 50 | struct State { 51 | enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; 52 | }; 53 | std::stack m_stateStack; 54 | }; 55 | } 56 | 57 | #endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 58 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/emitterdef.h: -------------------------------------------------------------------------------- 1 | #ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | namespace YAML { 11 | struct EmitterNodeType { 12 | enum value { NoType, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; 13 | }; 14 | } 15 | 16 | #endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 17 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/emittermanip.h: -------------------------------------------------------------------------------- 1 | #ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | namespace YAML { 13 | enum EMITTER_MANIP { 14 | // general manipulators 15 | Auto, 16 | TagByKind, 17 | Newline, 18 | 19 | // output character set 20 | EmitNonAscii, 21 | EscapeNonAscii, 22 | 23 | // string manipulators 24 | // Auto, // duplicate 25 | SingleQuoted, 26 | DoubleQuoted, 27 | Literal, 28 | 29 | // bool manipulators 30 | YesNoBool, // yes, no 31 | TrueFalseBool, // true, false 32 | OnOffBool, // on, off 33 | UpperCase, // TRUE, N 34 | LowerCase, // f, yes 35 | CamelCase, // No, Off 36 | LongBool, // yes, On 37 | ShortBool, // y, t 38 | 39 | // int manipulators 40 | Dec, 41 | Hex, 42 | Oct, 43 | 44 | // document manipulators 45 | BeginDoc, 46 | EndDoc, 47 | 48 | // sequence manipulators 49 | BeginSeq, 50 | EndSeq, 51 | Flow, 52 | Block, 53 | 54 | // map manipulators 55 | BeginMap, 56 | EndMap, 57 | Key, 58 | Value, 59 | // Flow, // duplicate 60 | // Block, // duplicate 61 | // Auto, // duplicate 62 | LongKey 63 | }; 64 | 65 | struct _Indent { 66 | _Indent(int value_) : value(value_) {} 67 | int value; 68 | }; 69 | 70 | inline _Indent Indent(int value) { return _Indent(value); } 71 | 72 | struct _Alias { 73 | _Alias(const std::string& content_) : content(content_) {} 74 | std::string content; 75 | }; 76 | 77 | inline _Alias Alias(const std::string content) { return _Alias(content); } 78 | 79 | struct _Anchor { 80 | _Anchor(const std::string& content_) : content(content_) {} 81 | std::string content; 82 | }; 83 | 84 | inline _Anchor Anchor(const std::string content) { return _Anchor(content); } 85 | 86 | struct _Tag { 87 | struct Type { 88 | enum value { Verbatim, PrimaryHandle, NamedHandle }; 89 | }; 90 | 91 | explicit _Tag(const std::string& prefix_, const std::string& content_, 92 | Type::value type_) 93 | : prefix(prefix_), content(content_), type(type_) {} 94 | std::string prefix; 95 | std::string content; 96 | Type::value type; 97 | }; 98 | 99 | inline _Tag VerbatimTag(const std::string content) { 100 | return _Tag("", content, _Tag::Type::Verbatim); 101 | } 102 | 103 | inline _Tag LocalTag(const std::string content) { 104 | return _Tag("", content, _Tag::Type::PrimaryHandle); 105 | } 106 | 107 | inline _Tag LocalTag(const std::string& prefix, const std::string content) { 108 | return _Tag(prefix, content, _Tag::Type::NamedHandle); 109 | } 110 | 111 | inline _Tag SecondaryTag(const std::string content) { 112 | return _Tag("", content, _Tag::Type::NamedHandle); 113 | } 114 | 115 | struct _Comment { 116 | _Comment(const std::string& content_) : content(content_) {} 117 | std::string content; 118 | }; 119 | 120 | inline _Comment Comment(const std::string content) { return _Comment(content); } 121 | 122 | struct _Precision { 123 | _Precision(int floatPrecision_, int doublePrecision_) 124 | : floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {} 125 | 126 | int floatPrecision; 127 | int doublePrecision; 128 | }; 129 | 130 | inline _Precision FloatPrecision(int n) { return _Precision(n, -1); } 131 | 132 | inline _Precision DoublePrecision(int n) { return _Precision(-1, n); } 133 | 134 | inline _Precision Precision(int n) { return _Precision(n, n); } 135 | } 136 | 137 | #endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 138 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/emitterstyle.h: -------------------------------------------------------------------------------- 1 | #ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | namespace YAML { 11 | struct EmitterStyle { 12 | enum value { Default, Block, Flow }; 13 | }; 14 | } 15 | 16 | #endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 17 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/eventhandler.h: -------------------------------------------------------------------------------- 1 | #ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "yaml-cpp/anchor.h" 13 | #include "yaml-cpp/emitterstyle.h" 14 | 15 | namespace YAML { 16 | struct Mark; 17 | 18 | class EventHandler { 19 | public: 20 | virtual ~EventHandler() {} 21 | 22 | virtual void OnDocumentStart(const Mark& mark) = 0; 23 | virtual void OnDocumentEnd() = 0; 24 | 25 | virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; 26 | virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0; 27 | virtual void OnScalar(const Mark& mark, const std::string& tag, 28 | anchor_t anchor, const std::string& value) = 0; 29 | 30 | virtual void OnSequenceStart(const Mark& mark, const std::string& tag, 31 | anchor_t anchor, EmitterStyle::value style) = 0; 32 | virtual void OnSequenceEnd() = 0; 33 | 34 | virtual void OnMapStart(const Mark& mark, const std::string& tag, 35 | anchor_t anchor, EmitterStyle::value style) = 0; 36 | virtual void OnMapEnd() = 0; 37 | }; 38 | } 39 | 40 | #endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 41 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/mark.h: -------------------------------------------------------------------------------- 1 | #ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | 12 | namespace YAML { 13 | struct YAML_CPP_API Mark { 14 | Mark() : pos(0), line(0), column(0) {} 15 | 16 | static const Mark null_mark() { return Mark(-1, -1, -1); } 17 | 18 | bool is_null() const { return pos == -1 && line == -1 && column == -1; } 19 | 20 | int pos; 21 | int line, column; 22 | 23 | private: 24 | Mark(int pos_, int line_, int column_) 25 | : pos(pos_), line(line_), column(column_) {} 26 | }; 27 | } 28 | 29 | #endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 30 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/detail/bool_type.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | namespace YAML { 11 | namespace detail { 12 | struct unspecified_bool { 13 | struct NOT_ALLOWED; 14 | static void true_value(NOT_ALLOWED*) {} 15 | }; 16 | typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*); 17 | } 18 | } 19 | 20 | #define YAML_CPP_OPERATOR_BOOL() \ 21 | operator YAML::detail::unspecified_bool_type() const { \ 22 | return this->operator!() ? 0 \ 23 | : &YAML::detail::unspecified_bool::true_value; \ 24 | } 25 | 26 | #endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 27 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/detail/iterator.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | #include "yaml-cpp/node/ptr.h" 12 | #include "yaml-cpp/node/detail/node_iterator.h" 13 | #include 14 | #include 15 | 16 | namespace YAML { 17 | namespace detail { 18 | struct iterator_value; 19 | 20 | template 21 | class iterator_base : public std::iterator { 23 | 24 | private: 25 | template 26 | friend class iterator_base; 27 | struct enabler {}; 28 | typedef node_iterator base_type; 29 | 30 | struct proxy { 31 | explicit proxy(const V& x) : m_ref(x) {} 32 | V* operator->() { return std::addressof(m_ref); } 33 | operator V*() { return std::addressof(m_ref); } 34 | 35 | V m_ref; 36 | }; 37 | 38 | public: 39 | typedef typename iterator_base::value_type value_type; 40 | 41 | public: 42 | iterator_base() : m_iterator(), m_pMemory() {} 43 | explicit iterator_base(base_type rhs, shared_memory_holder pMemory) 44 | : m_iterator(rhs), m_pMemory(pMemory) {} 45 | 46 | template 47 | iterator_base(const iterator_base& rhs, 48 | typename std::enable_if::value, 49 | enabler>::type = enabler()) 50 | : m_iterator(rhs.m_iterator), m_pMemory(rhs.m_pMemory) {} 51 | 52 | iterator_base& operator++() { 53 | ++m_iterator; 54 | return *this; 55 | } 56 | 57 | iterator_base operator++(int) { 58 | iterator_base iterator_pre(*this); 59 | ++(*this); 60 | return iterator_pre; 61 | } 62 | 63 | template 64 | bool operator==(const iterator_base& rhs) const { 65 | return m_iterator == rhs.m_iterator; 66 | } 67 | 68 | template 69 | bool operator!=(const iterator_base& rhs) const { 70 | return m_iterator != rhs.m_iterator; 71 | } 72 | 73 | value_type operator*() const { 74 | const typename base_type::value_type& v = *m_iterator; 75 | if (v.pNode) 76 | return value_type(Node(*v, m_pMemory)); 77 | if (v.first && v.second) 78 | return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory)); 79 | return value_type(); 80 | } 81 | 82 | proxy operator->() const { return proxy(**this); } 83 | 84 | private: 85 | base_type m_iterator; 86 | shared_memory_holder m_pMemory; 87 | }; 88 | } 89 | } 90 | 91 | #endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 92 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/detail/iterator_fwd.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | #include 12 | #include 13 | #include 14 | 15 | namespace YAML { 16 | 17 | namespace detail { 18 | struct iterator_value; 19 | template 20 | class iterator_base; 21 | } 22 | 23 | typedef detail::iterator_base iterator; 24 | typedef detail::iterator_base const_iterator; 25 | } 26 | 27 | #endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 28 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/detail/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "yaml-cpp/dll.h" 13 | #include "yaml-cpp/node/ptr.h" 14 | 15 | namespace YAML { 16 | namespace detail { 17 | class node; 18 | } // namespace detail 19 | } // namespace YAML 20 | 21 | namespace YAML { 22 | namespace detail { 23 | class YAML_CPP_API memory { 24 | public: 25 | node& create_node(); 26 | void merge(const memory& rhs); 27 | 28 | private: 29 | typedef std::set Nodes; 30 | Nodes m_nodes; 31 | }; 32 | 33 | class YAML_CPP_API memory_holder { 34 | public: 35 | memory_holder() : m_pMemory(new memory) {} 36 | 37 | node& create_node() { return m_pMemory->create_node(); } 38 | void merge(memory_holder& rhs); 39 | 40 | private: 41 | shared_memory m_pMemory; 42 | }; 43 | } 44 | } 45 | 46 | #endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 47 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/detail/node_data.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "yaml-cpp/dll.h" 17 | #include "yaml-cpp/node/detail/node_iterator.h" 18 | #include "yaml-cpp/node/iterator.h" 19 | #include "yaml-cpp/node/ptr.h" 20 | #include "yaml-cpp/node/type.h" 21 | 22 | namespace YAML { 23 | namespace detail { 24 | class node; 25 | } // namespace detail 26 | } // namespace YAML 27 | 28 | namespace YAML { 29 | namespace detail { 30 | class YAML_CPP_API node_data { 31 | public: 32 | node_data(); 33 | node_data(const node_data&) = delete; 34 | node_data& operator=(const node_data&) = delete; 35 | 36 | void mark_defined(); 37 | void set_mark(const Mark& mark); 38 | void set_type(NodeType::value type); 39 | void set_tag(const std::string& tag); 40 | void set_null(); 41 | void set_scalar(const std::string& scalar); 42 | void set_style(EmitterStyle::value style); 43 | 44 | bool is_defined() const { return m_isDefined; } 45 | const Mark& mark() const { return m_mark; } 46 | NodeType::value type() const { 47 | return m_isDefined ? m_type : NodeType::Undefined; 48 | } 49 | const std::string& scalar() const { return m_scalar; } 50 | const std::string& tag() const { return m_tag; } 51 | EmitterStyle::value style() const { return m_style; } 52 | 53 | // size/iterator 54 | std::size_t size() const; 55 | 56 | const_node_iterator begin() const; 57 | node_iterator begin(); 58 | 59 | const_node_iterator end() const; 60 | node_iterator end(); 61 | 62 | // sequence 63 | void push_back(node& node, shared_memory_holder pMemory); 64 | void insert(node& key, node& value, shared_memory_holder pMemory); 65 | 66 | // indexing 67 | template 68 | node* get(const Key& key, shared_memory_holder pMemory) const; 69 | template 70 | node& get(const Key& key, shared_memory_holder pMemory); 71 | template 72 | bool remove(const Key& key, shared_memory_holder pMemory); 73 | 74 | node* get(node& key, shared_memory_holder pMemory) const; 75 | node& get(node& key, shared_memory_holder pMemory); 76 | bool remove(node& key, shared_memory_holder pMemory); 77 | 78 | // map 79 | template 80 | void force_insert(const Key& key, const Value& value, 81 | shared_memory_holder pMemory); 82 | 83 | public: 84 | static std::string empty_scalar; 85 | 86 | private: 87 | void compute_seq_size() const; 88 | void compute_map_size() const; 89 | 90 | void reset_sequence(); 91 | void reset_map(); 92 | 93 | void insert_map_pair(node& key, node& value); 94 | void convert_to_map(shared_memory_holder pMemory); 95 | void convert_sequence_to_map(shared_memory_holder pMemory); 96 | 97 | template 98 | static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); 99 | 100 | private: 101 | bool m_isDefined; 102 | Mark m_mark; 103 | NodeType::value m_type; 104 | std::string m_tag; 105 | EmitterStyle::value m_style; 106 | 107 | // scalar 108 | std::string m_scalar; 109 | 110 | // sequence 111 | typedef std::vector node_seq; 112 | node_seq m_sequence; 113 | 114 | mutable std::size_t m_seqSize; 115 | 116 | // map 117 | typedef std::vector> node_map; 118 | node_map m_map; 119 | 120 | typedef std::pair kv_pair; 121 | typedef std::list kv_pairs; 122 | mutable kv_pairs m_undefinedPairs; 123 | }; 124 | } 125 | } 126 | 127 | #endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 128 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/detail/node_ref.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | #include "yaml-cpp/node/type.h" 12 | #include "yaml-cpp/node/ptr.h" 13 | #include "yaml-cpp/node/detail/node_data.h" 14 | 15 | namespace YAML { 16 | namespace detail { 17 | class node_ref { 18 | public: 19 | node_ref() : m_pData(new node_data) {} 20 | node_ref(const node_ref&) = delete; 21 | node_ref& operator=(const node_ref&) = delete; 22 | 23 | bool is_defined() const { return m_pData->is_defined(); } 24 | const Mark& mark() const { return m_pData->mark(); } 25 | NodeType::value type() const { return m_pData->type(); } 26 | const std::string& scalar() const { return m_pData->scalar(); } 27 | const std::string& tag() const { return m_pData->tag(); } 28 | EmitterStyle::value style() const { return m_pData->style(); } 29 | 30 | void mark_defined() { m_pData->mark_defined(); } 31 | void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } 32 | 33 | void set_mark(const Mark& mark) { m_pData->set_mark(mark); } 34 | void set_type(NodeType::value type) { m_pData->set_type(type); } 35 | void set_tag(const std::string& tag) { m_pData->set_tag(tag); } 36 | void set_null() { m_pData->set_null(); } 37 | void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } 38 | void set_style(EmitterStyle::value style) { m_pData->set_style(style); } 39 | 40 | // size/iterator 41 | std::size_t size() const { return m_pData->size(); } 42 | 43 | const_node_iterator begin() const { 44 | return static_cast(*m_pData).begin(); 45 | } 46 | node_iterator begin() { return m_pData->begin(); } 47 | 48 | const_node_iterator end() const { 49 | return static_cast(*m_pData).end(); 50 | } 51 | node_iterator end() { return m_pData->end(); } 52 | 53 | // sequence 54 | void push_back(node& node, shared_memory_holder pMemory) { 55 | m_pData->push_back(node, pMemory); 56 | } 57 | void insert(node& key, node& value, shared_memory_holder pMemory) { 58 | m_pData->insert(key, value, pMemory); 59 | } 60 | 61 | // indexing 62 | template 63 | node* get(const Key& key, shared_memory_holder pMemory) const { 64 | return static_cast(*m_pData).get(key, pMemory); 65 | } 66 | template 67 | node& get(const Key& key, shared_memory_holder pMemory) { 68 | return m_pData->get(key, pMemory); 69 | } 70 | template 71 | bool remove(const Key& key, shared_memory_holder pMemory) { 72 | return m_pData->remove(key, pMemory); 73 | } 74 | 75 | node* get(node& key, shared_memory_holder pMemory) const { 76 | return static_cast(*m_pData).get(key, pMemory); 77 | } 78 | node& get(node& key, shared_memory_holder pMemory) { 79 | return m_pData->get(key, pMemory); 80 | } 81 | bool remove(node& key, shared_memory_holder pMemory) { 82 | return m_pData->remove(key, pMemory); 83 | } 84 | 85 | // map 86 | template 87 | void force_insert(const Key& key, const Value& value, 88 | shared_memory_holder pMemory) { 89 | m_pData->force_insert(key, value, pMemory); 90 | } 91 | 92 | private: 93 | shared_node_data m_pData; 94 | }; 95 | } 96 | } 97 | 98 | #endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 99 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/emit.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | #include "yaml-cpp/dll.h" 14 | 15 | namespace YAML { 16 | class Emitter; 17 | class Node; 18 | 19 | /** 20 | * Emits the node to the given {@link Emitter}. If there is an error in writing, 21 | * {@link Emitter#good} will return false. 22 | */ 23 | YAML_CPP_API Emitter& operator<<(Emitter& out, const Node& node); 24 | 25 | /** Emits the node to the given output stream. */ 26 | YAML_CPP_API std::ostream& operator<<(std::ostream& out, const Node& node); 27 | 28 | /** Converts the node to a YAML string. */ 29 | YAML_CPP_API std::string Dump(const Node& node); 30 | } // namespace YAML 31 | 32 | #endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 33 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/iterator.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | #include "yaml-cpp/node/node.h" 12 | #include "yaml-cpp/node/detail/iterator_fwd.h" 13 | #include "yaml-cpp/node/detail/iterator.h" 14 | #include 15 | #include 16 | #include 17 | 18 | namespace YAML { 19 | namespace detail { 20 | struct iterator_value : public Node, std::pair { 21 | iterator_value() {} 22 | explicit iterator_value(const Node& rhs) 23 | : Node(rhs), 24 | std::pair(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} 25 | explicit iterator_value(const Node& key, const Node& value) 26 | : Node(Node::ZombieNode), std::pair(key, value) {} 27 | }; 28 | } 29 | } 30 | 31 | #endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 32 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/node.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "yaml-cpp/dll.h" 13 | #include "yaml-cpp/emitterstyle.h" 14 | #include "yaml-cpp/mark.h" 15 | #include "yaml-cpp/node/detail/bool_type.h" 16 | #include "yaml-cpp/node/detail/iterator_fwd.h" 17 | #include "yaml-cpp/node/ptr.h" 18 | #include "yaml-cpp/node/type.h" 19 | 20 | namespace YAML { 21 | namespace detail { 22 | class node; 23 | class node_data; 24 | struct iterator_value; 25 | } // namespace detail 26 | } // namespace YAML 27 | 28 | namespace YAML { 29 | class YAML_CPP_API Node { 30 | public: 31 | friend class NodeBuilder; 32 | friend class NodeEvents; 33 | friend struct detail::iterator_value; 34 | friend class detail::node; 35 | friend class detail::node_data; 36 | template 37 | friend class detail::iterator_base; 38 | template 39 | friend struct as_if; 40 | 41 | typedef YAML::iterator iterator; 42 | typedef YAML::const_iterator const_iterator; 43 | 44 | Node(); 45 | explicit Node(NodeType::value type); 46 | template 47 | explicit Node(const T& rhs); 48 | explicit Node(const detail::iterator_value& rhs); 49 | Node(const Node& rhs); 50 | ~Node(); 51 | 52 | YAML::Mark Mark() const; 53 | NodeType::value Type() const; 54 | bool IsDefined() const; 55 | bool IsNull() const { return Type() == NodeType::Null; } 56 | bool IsScalar() const { return Type() == NodeType::Scalar; } 57 | bool IsSequence() const { return Type() == NodeType::Sequence; } 58 | bool IsMap() const { return Type() == NodeType::Map; } 59 | 60 | // bool conversions 61 | YAML_CPP_OPERATOR_BOOL() 62 | bool operator!() const { return !IsDefined(); } 63 | 64 | // access 65 | template 66 | T as() const; 67 | template 68 | T as(const S& fallback) const; 69 | const std::string& Scalar() const; 70 | 71 | const std::string& Tag() const; 72 | void SetTag(const std::string& tag); 73 | 74 | // style 75 | // WARNING: This API might change in future releases. 76 | EmitterStyle::value Style() const; 77 | void SetStyle(EmitterStyle::value style); 78 | 79 | // assignment 80 | bool is(const Node& rhs) const; 81 | template 82 | Node& operator=(const T& rhs); 83 | Node& operator=(const Node& rhs); 84 | void reset(const Node& rhs = Node()); 85 | 86 | // size/iterator 87 | std::size_t size() const; 88 | 89 | const_iterator begin() const; 90 | iterator begin(); 91 | 92 | const_iterator end() const; 93 | iterator end(); 94 | 95 | // sequence 96 | template 97 | void push_back(const T& rhs); 98 | void push_back(const Node& rhs); 99 | 100 | // indexing 101 | template 102 | const Node operator[](const Key& key) const; 103 | template 104 | Node operator[](const Key& key); 105 | template 106 | bool remove(const Key& key); 107 | 108 | const Node operator[](const Node& key) const; 109 | Node operator[](const Node& key); 110 | bool remove(const Node& key); 111 | 112 | // map 113 | template 114 | void force_insert(const Key& key, const Value& value); 115 | 116 | private: 117 | enum Zombie { ZombieNode }; 118 | explicit Node(Zombie); 119 | explicit Node(detail::node& node, detail::shared_memory_holder pMemory); 120 | 121 | void EnsureNodeExists() const; 122 | 123 | template 124 | void Assign(const T& rhs); 125 | void Assign(const char* rhs); 126 | void Assign(char* rhs); 127 | 128 | void AssignData(const Node& rhs); 129 | void AssignNode(const Node& rhs); 130 | 131 | private: 132 | bool m_isValid; 133 | mutable detail::shared_memory_holder m_pMemory; 134 | mutable detail::node* m_pNode; 135 | }; 136 | 137 | YAML_CPP_API bool operator==(const Node& lhs, const Node& rhs); 138 | 139 | YAML_CPP_API Node Clone(const Node& node); 140 | 141 | template 142 | struct convert; 143 | } 144 | 145 | #endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 146 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/parse.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "yaml-cpp/dll.h" 15 | 16 | namespace YAML { 17 | class Node; 18 | 19 | /** 20 | * Loads the input string as a single YAML document. 21 | * 22 | * @throws {@link ParserException} if it is malformed. 23 | */ 24 | YAML_CPP_API Node Load(const std::string& input); 25 | 26 | /** 27 | * Loads the input string as a single YAML document. 28 | * 29 | * @throws {@link ParserException} if it is malformed. 30 | */ 31 | YAML_CPP_API Node Load(const char* input); 32 | 33 | /** 34 | * Loads the input stream as a single YAML document. 35 | * 36 | * @throws {@link ParserException} if it is malformed. 37 | */ 38 | YAML_CPP_API Node Load(std::istream& input); 39 | 40 | /** 41 | * Loads the input file as a single YAML document. 42 | * 43 | * @throws {@link ParserException} if it is malformed. 44 | * @throws {@link BadFile} if the file cannot be loaded. 45 | */ 46 | YAML_CPP_API Node LoadFile(const std::string& filename); 47 | 48 | /** 49 | * Loads the input string as a list of YAML documents. 50 | * 51 | * @throws {@link ParserException} if it is malformed. 52 | */ 53 | YAML_CPP_API std::vector LoadAll(const std::string& input); 54 | 55 | /** 56 | * Loads the input string as a list of YAML documents. 57 | * 58 | * @throws {@link ParserException} if it is malformed. 59 | */ 60 | YAML_CPP_API std::vector LoadAll(const char* input); 61 | 62 | /** 63 | * Loads the input stream as a list of YAML documents. 64 | * 65 | * @throws {@link ParserException} if it is malformed. 66 | */ 67 | YAML_CPP_API std::vector LoadAll(std::istream& input); 68 | 69 | /** 70 | * Loads the input file as a list of YAML documents. 71 | * 72 | * @throws {@link ParserException} if it is malformed. 73 | * @throws {@link BadFile} if the file cannot be loaded. 74 | */ 75 | YAML_CPP_API std::vector LoadAllFromFile(const std::string& filename); 76 | } // namespace YAML 77 | 78 | #endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 79 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | #include 12 | 13 | namespace YAML { 14 | namespace detail { 15 | class node; 16 | class node_ref; 17 | class node_data; 18 | class memory; 19 | class memory_holder; 20 | 21 | typedef std::shared_ptr shared_node; 22 | typedef std::shared_ptr shared_node_ref; 23 | typedef std::shared_ptr shared_node_data; 24 | typedef std::shared_ptr shared_memory_holder; 25 | typedef std::shared_ptr shared_memory; 26 | } 27 | } 28 | 29 | #endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 30 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/node/type.h: -------------------------------------------------------------------------------- 1 | #ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | namespace YAML { 11 | struct NodeType { 12 | enum value { Undefined, Null, Scalar, Sequence, Map }; 13 | }; 14 | } 15 | 16 | #endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 17 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/noncopyable.h: -------------------------------------------------------------------------------- 1 | #ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | 12 | namespace YAML { 13 | // this is basically boost::noncopyable 14 | class YAML_CPP_API noncopyable { 15 | protected: 16 | noncopyable() {} 17 | ~noncopyable() {} 18 | 19 | private: 20 | noncopyable(const noncopyable&); 21 | const noncopyable& operator=(const noncopyable&); 22 | }; 23 | } 24 | 25 | #endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 26 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/null.h: -------------------------------------------------------------------------------- 1 | #ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/dll.h" 11 | #include 12 | 13 | namespace YAML { 14 | class Node; 15 | 16 | struct YAML_CPP_API _Null {}; 17 | inline bool operator==(const _Null&, const _Null&) { return true; } 18 | inline bool operator!=(const _Null&, const _Null&) { return false; } 19 | 20 | YAML_CPP_API bool IsNull(const Node& node); // old API only 21 | YAML_CPP_API bool IsNullString(const std::string& str); 22 | 23 | extern YAML_CPP_API _Null Null; 24 | } 25 | 26 | #endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 27 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/ostream_wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | #include "yaml-cpp/dll.h" 14 | 15 | namespace YAML { 16 | class YAML_CPP_API ostream_wrapper { 17 | public: 18 | ostream_wrapper(); 19 | explicit ostream_wrapper(std::ostream& stream); 20 | ~ostream_wrapper(); 21 | 22 | void write(const std::string& str); 23 | void write(const char* str, std::size_t size); 24 | 25 | void set_comment() { m_comment = true; } 26 | 27 | const char* str() const { 28 | if (m_pStream) { 29 | return 0; 30 | } else { 31 | m_buffer[m_pos] = '\0'; 32 | return &m_buffer[0]; 33 | } 34 | } 35 | 36 | std::size_t row() const { return m_row; } 37 | std::size_t col() const { return m_col; } 38 | std::size_t pos() const { return m_pos; } 39 | bool comment() const { return m_comment; } 40 | 41 | private: 42 | void update_pos(char ch); 43 | 44 | private: 45 | mutable std::vector m_buffer; 46 | std::ostream* const m_pStream; 47 | 48 | std::size_t m_pos; 49 | std::size_t m_row, m_col; 50 | bool m_comment; 51 | }; 52 | 53 | template 54 | inline ostream_wrapper& operator<<(ostream_wrapper& stream, 55 | const char(&str)[N]) { 56 | stream.write(str, N - 1); 57 | return stream; 58 | } 59 | 60 | inline ostream_wrapper& operator<<(ostream_wrapper& stream, 61 | const std::string& str) { 62 | stream.write(str); 63 | return stream; 64 | } 65 | 66 | inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) { 67 | stream.write(&ch, 1); 68 | return stream; 69 | } 70 | } 71 | 72 | #endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 73 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | #include "yaml-cpp/dll.h" 14 | #include "yaml-cpp/noncopyable.h" 15 | 16 | namespace YAML { 17 | class EventHandler; 18 | class Node; 19 | class Scanner; 20 | struct Directives; 21 | struct Token; 22 | 23 | /** 24 | * A parser turns a stream of bytes into one stream of "events" per YAML 25 | * document in the input stream. 26 | */ 27 | class YAML_CPP_API Parser : private noncopyable { 28 | public: 29 | /** Constructs an empty parser (with no input. */ 30 | Parser(); 31 | 32 | /** 33 | * Constructs a parser from the given input stream. The input stream must 34 | * live as long as the parser. 35 | */ 36 | explicit Parser(std::istream& in); 37 | 38 | ~Parser(); 39 | 40 | /** Evaluates to true if the parser has some valid input to be read. */ 41 | explicit operator bool() const; 42 | 43 | /** 44 | * Resets the parser with the given input stream. Any existing state is 45 | * erased. 46 | */ 47 | void Load(std::istream& in); 48 | 49 | /** 50 | * Handles the next document by calling events on the {@code eventHandler}. 51 | * 52 | * @throw a ParserException on error. 53 | * @return false if there are no more documents 54 | */ 55 | bool HandleNextDocument(EventHandler& eventHandler); 56 | 57 | void PrintTokens(std::ostream& out); 58 | 59 | private: 60 | /** 61 | * Reads any directives that are next in the queue, setting the internal 62 | * {@code m_pDirectives} state. 63 | */ 64 | void ParseDirectives(); 65 | 66 | void HandleDirective(const Token& token); 67 | 68 | /** 69 | * Handles a "YAML" directive, which should be of the form 'major.minor' (like 70 | * a version number). 71 | */ 72 | void HandleYamlDirective(const Token& token); 73 | 74 | /** 75 | * Handles a "TAG" directive, which should be of the form 'handle prefix', 76 | * where 'handle' is converted to 'prefix' in the file. 77 | */ 78 | void HandleTagDirective(const Token& token); 79 | 80 | private: 81 | std::unique_ptr m_pScanner; 82 | std::unique_ptr m_pDirectives; 83 | }; 84 | } 85 | 86 | #endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 87 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/stlemitter.h: -------------------------------------------------------------------------------- 1 | #ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace YAML { 16 | template 17 | inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) { 18 | emitter << BeginSeq; 19 | for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it) 20 | emitter << *it; 21 | emitter << EndSeq; 22 | return emitter; 23 | } 24 | 25 | template 26 | inline Emitter& operator<<(Emitter& emitter, const std::vector& v) { 27 | return EmitSeq(emitter, v); 28 | } 29 | 30 | template 31 | inline Emitter& operator<<(Emitter& emitter, const std::list& v) { 32 | return EmitSeq(emitter, v); 33 | } 34 | 35 | template 36 | inline Emitter& operator<<(Emitter& emitter, const std::set& v) { 37 | return EmitSeq(emitter, v); 38 | } 39 | 40 | template 41 | inline Emitter& operator<<(Emitter& emitter, const std::map& m) { 42 | typedef typename std::map map; 43 | emitter << BeginMap; 44 | for (typename map::const_iterator it = m.begin(); it != m.end(); ++it) 45 | emitter << Key << it->first << Value << it->second; 46 | emitter << EndMap; 47 | return emitter; 48 | } 49 | } 50 | 51 | #endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 52 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/traits.h: -------------------------------------------------------------------------------- 1 | #ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | namespace YAML { 11 | template 12 | struct is_numeric { 13 | enum { value = false }; 14 | }; 15 | 16 | template <> 17 | struct is_numeric { 18 | enum { value = true }; 19 | }; 20 | template <> 21 | struct is_numeric { 22 | enum { value = true }; 23 | }; 24 | template <> 25 | struct is_numeric { 26 | enum { value = true }; 27 | }; 28 | template <> 29 | struct is_numeric { 30 | enum { value = true }; 31 | }; 32 | template <> 33 | struct is_numeric { 34 | enum { value = true }; 35 | }; 36 | template <> 37 | struct is_numeric { 38 | enum { value = true }; 39 | }; 40 | template <> 41 | struct is_numeric { 42 | enum { value = true }; 43 | }; 44 | template <> 45 | struct is_numeric { 46 | enum { value = true }; 47 | }; 48 | #if defined(_MSC_VER) && (_MSC_VER < 1310) 49 | template <> 50 | struct is_numeric<__int64> { 51 | enum { value = true }; 52 | }; 53 | template <> 54 | struct is_numeric { 55 | enum { value = true }; 56 | }; 57 | #else 58 | template <> 59 | struct is_numeric { 60 | enum { value = true }; 61 | }; 62 | template <> 63 | struct is_numeric { 64 | enum { value = true }; 65 | }; 66 | #endif 67 | template <> 68 | struct is_numeric { 69 | enum { value = true }; 70 | }; 71 | template <> 72 | struct is_numeric { 73 | enum { value = true }; 74 | }; 75 | template <> 76 | struct is_numeric { 77 | enum { value = true }; 78 | }; 79 | 80 | template 81 | struct enable_if_c { 82 | typedef T type; 83 | }; 84 | 85 | template 86 | struct enable_if_c {}; 87 | 88 | template 89 | struct enable_if : public enable_if_c {}; 90 | 91 | template 92 | struct disable_if_c { 93 | typedef T type; 94 | }; 95 | 96 | template 97 | struct disable_if_c {}; 98 | 99 | template 100 | struct disable_if : public disable_if_c {}; 101 | } 102 | 103 | #endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 104 | -------------------------------------------------------------------------------- /extra/yaml-cpp/include/yaml-cpp/yaml.h: -------------------------------------------------------------------------------- 1 | #ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/parser.h" 11 | #include "yaml-cpp/emitter.h" 12 | #include "yaml-cpp/emitterstyle.h" 13 | #include "yaml-cpp/stlemitter.h" 14 | #include "yaml-cpp/exceptions.h" 15 | 16 | #include "yaml-cpp/node/node.h" 17 | #include "yaml-cpp/node/impl.h" 18 | #include "yaml-cpp/node/convert.h" 19 | #include "yaml-cpp/node/iterator.h" 20 | #include "yaml-cpp/node/detail/impl.h" 21 | #include "yaml-cpp/node/parse.h" 22 | #include "yaml-cpp/node/emit.h" 23 | 24 | #endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 25 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/binary.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/binary.h" 2 | 3 | namespace YAML { 4 | static const char encoding[] = 5 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 6 | 7 | std::string EncodeBase64(const unsigned char *data, std::size_t size) { 8 | const char PAD = '='; 9 | 10 | std::string ret; 11 | ret.resize(4 * size / 3 + 3); 12 | char *out = &ret[0]; 13 | 14 | std::size_t chunks = size / 3; 15 | std::size_t remainder = size % 3; 16 | 17 | for (std::size_t i = 0; i < chunks; i++, data += 3) { 18 | *out++ = encoding[data[0] >> 2]; 19 | *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; 20 | *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)]; 21 | *out++ = encoding[data[2] & 0x3f]; 22 | } 23 | 24 | switch (remainder) { 25 | case 0: 26 | break; 27 | case 1: 28 | *out++ = encoding[data[0] >> 2]; 29 | *out++ = encoding[((data[0] & 0x3) << 4)]; 30 | *out++ = PAD; 31 | *out++ = PAD; 32 | break; 33 | case 2: 34 | *out++ = encoding[data[0] >> 2]; 35 | *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; 36 | *out++ = encoding[((data[1] & 0xf) << 2)]; 37 | *out++ = PAD; 38 | break; 39 | } 40 | 41 | ret.resize(out - &ret[0]); 42 | return ret; 43 | } 44 | 45 | static const unsigned char decoding[] = { 46 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 47 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 48 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 49 | 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 50 | 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 51 | 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 52 | 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 53 | 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 54 | 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 55 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 57 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 58 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 59 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 60 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 61 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 63 | 255, 64 | }; 65 | 66 | std::vector DecodeBase64(const std::string &input) { 67 | typedef std::vector ret_type; 68 | if (input.empty()) 69 | return ret_type(); 70 | 71 | ret_type ret(3 * input.size() / 4 + 1); 72 | unsigned char *out = &ret[0]; 73 | 74 | unsigned value = 0; 75 | for (std::size_t i = 0; i < input.size(); i++) { 76 | unsigned char d = decoding[static_cast(input[i])]; 77 | if (d == 255) 78 | return ret_type(); 79 | 80 | value = (value << 6) | d; 81 | if (i % 4 == 3) { 82 | *out++ = value >> 16; 83 | if (i > 0 && input[i - 1] != '=') 84 | *out++ = value >> 8; 85 | if (input[i] != '=') 86 | *out++ = value; 87 | } 88 | } 89 | 90 | ret.resize(out - &ret[0]); 91 | return ret; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/collectionstack.h: -------------------------------------------------------------------------------- 1 | #ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | namespace YAML { 14 | struct CollectionType { 15 | enum value { NoCollection, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap }; 16 | }; 17 | 18 | class CollectionStack { 19 | public: 20 | CollectionType::value GetCurCollectionType() const { 21 | if (collectionStack.empty()) 22 | return CollectionType::NoCollection; 23 | return collectionStack.top(); 24 | } 25 | 26 | void PushCollectionType(CollectionType::value type) { 27 | collectionStack.push(type); 28 | } 29 | void PopCollectionType(CollectionType::value type) { 30 | assert(type == GetCurCollectionType()); 31 | collectionStack.pop(); 32 | } 33 | 34 | private: 35 | std::stack collectionStack; 36 | }; 37 | } 38 | 39 | #endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 40 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/contrib/graphbuilder.cpp: -------------------------------------------------------------------------------- 1 | #include "graphbuilderadapter.h" 2 | 3 | #include "yaml-cpp/parser.h" // IWYU pragma: keep 4 | 5 | namespace YAML { 6 | class GraphBuilderInterface; 7 | 8 | void* BuildGraphOfNextDocument(Parser& parser, 9 | GraphBuilderInterface& graphBuilder) { 10 | GraphBuilderAdapter eventHandler(graphBuilder); 11 | if (parser.HandleNextDocument(eventHandler)) { 12 | return eventHandler.RootNode(); 13 | } else { 14 | return NULL; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/contrib/graphbuilderadapter.cpp: -------------------------------------------------------------------------------- 1 | #include "graphbuilderadapter.h" 2 | #include "yaml-cpp/contrib/graphbuilder.h" 3 | 4 | namespace YAML { 5 | struct Mark; 6 | 7 | int GraphBuilderAdapter::ContainerFrame::sequenceMarker; 8 | 9 | void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) { 10 | void *pParent = GetCurrentParent(); 11 | void *pNode = m_builder.NewNull(mark, pParent); 12 | RegisterAnchor(anchor, pNode); 13 | 14 | DispositionNode(pNode); 15 | } 16 | 17 | void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) { 18 | void *pReffedNode = m_anchors.Get(anchor); 19 | DispositionNode(m_builder.AnchorReference(mark, pReffedNode)); 20 | } 21 | 22 | void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag, 23 | anchor_t anchor, const std::string &value) { 24 | void *pParent = GetCurrentParent(); 25 | void *pNode = m_builder.NewScalar(mark, tag, pParent, value); 26 | RegisterAnchor(anchor, pNode); 27 | 28 | DispositionNode(pNode); 29 | } 30 | 31 | void GraphBuilderAdapter::OnSequenceStart(const Mark &mark, 32 | const std::string &tag, 33 | anchor_t anchor, 34 | EmitterStyle::value /* style */) { 35 | void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent()); 36 | m_containers.push(ContainerFrame(pNode)); 37 | RegisterAnchor(anchor, pNode); 38 | } 39 | 40 | void GraphBuilderAdapter::OnSequenceEnd() { 41 | void *pSequence = m_containers.top().pContainer; 42 | m_containers.pop(); 43 | 44 | DispositionNode(pSequence); 45 | } 46 | 47 | void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag, 48 | anchor_t anchor, 49 | EmitterStyle::value /* style */) { 50 | void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent()); 51 | m_containers.push(ContainerFrame(pNode, m_pKeyNode)); 52 | m_pKeyNode = NULL; 53 | RegisterAnchor(anchor, pNode); 54 | } 55 | 56 | void GraphBuilderAdapter::OnMapEnd() { 57 | void *pMap = m_containers.top().pContainer; 58 | m_pKeyNode = m_containers.top().pPrevKeyNode; 59 | m_containers.pop(); 60 | DispositionNode(pMap); 61 | } 62 | 63 | void *GraphBuilderAdapter::GetCurrentParent() const { 64 | if (m_containers.empty()) { 65 | return NULL; 66 | } 67 | return m_containers.top().pContainer; 68 | } 69 | 70 | void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) { 71 | if (anchor) { 72 | m_anchors.Register(anchor, pNode); 73 | } 74 | } 75 | 76 | void GraphBuilderAdapter::DispositionNode(void *pNode) { 77 | if (m_containers.empty()) { 78 | m_pRootNode = pNode; 79 | return; 80 | } 81 | 82 | void *pContainer = m_containers.top().pContainer; 83 | if (m_containers.top().isMap()) { 84 | if (m_pKeyNode) { 85 | m_builder.AssignInMap(pContainer, m_pKeyNode, pNode); 86 | m_pKeyNode = NULL; 87 | } else { 88 | m_pKeyNode = pNode; 89 | } 90 | } else { 91 | m_builder.AppendToSequence(pContainer, pNode); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/contrib/graphbuilderadapter.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "yaml-cpp/anchor.h" 15 | #include "yaml-cpp/contrib/anchordict.h" 16 | #include "yaml-cpp/contrib/graphbuilder.h" 17 | #include "yaml-cpp/emitterstyle.h" 18 | #include "yaml-cpp/eventhandler.h" 19 | 20 | namespace YAML { 21 | class GraphBuilderInterface; 22 | struct Mark; 23 | } // namespace YAML 24 | 25 | namespace YAML { 26 | class GraphBuilderAdapter : public EventHandler { 27 | public: 28 | GraphBuilderAdapter(GraphBuilderInterface& builder) 29 | : m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) {} 30 | 31 | virtual void OnDocumentStart(const Mark& mark) { (void)mark; } 32 | virtual void OnDocumentEnd() {} 33 | 34 | virtual void OnNull(const Mark& mark, anchor_t anchor); 35 | virtual void OnAlias(const Mark& mark, anchor_t anchor); 36 | virtual void OnScalar(const Mark& mark, const std::string& tag, 37 | anchor_t anchor, const std::string& value); 38 | 39 | virtual void OnSequenceStart(const Mark& mark, const std::string& tag, 40 | anchor_t anchor, EmitterStyle::value style); 41 | virtual void OnSequenceEnd(); 42 | 43 | virtual void OnMapStart(const Mark& mark, const std::string& tag, 44 | anchor_t anchor, EmitterStyle::value style); 45 | virtual void OnMapEnd(); 46 | 47 | void* RootNode() const { return m_pRootNode; } 48 | 49 | private: 50 | struct ContainerFrame { 51 | ContainerFrame(void* pSequence) 52 | : pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {} 53 | ContainerFrame(void* pMap, void* pPrevKeyNode) 54 | : pContainer(pMap), pPrevKeyNode(pPrevKeyNode) {} 55 | 56 | void* pContainer; 57 | void* pPrevKeyNode; 58 | 59 | bool isMap() const { return pPrevKeyNode != &sequenceMarker; } 60 | 61 | private: 62 | static int sequenceMarker; 63 | }; 64 | typedef std::stack ContainerStack; 65 | typedef AnchorDict AnchorMap; 66 | 67 | GraphBuilderInterface& m_builder; 68 | ContainerStack m_containers; 69 | AnchorMap m_anchors; 70 | void* m_pRootNode; 71 | void* m_pKeyNode; 72 | 73 | void* GetCurrentParent() const; 74 | void RegisterAnchor(anchor_t anchor, void* pNode); 75 | void DispositionNode(void* pNode); 76 | }; 77 | } 78 | 79 | #endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 80 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/convert.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "yaml-cpp/node/convert.h" 4 | 5 | namespace { 6 | // we're not gonna mess with the mess that is all the isupper/etc. functions 7 | bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; } 8 | bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; } 9 | char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; } 10 | 11 | std::string tolower(const std::string& str) { 12 | std::string s(str); 13 | std::transform(s.begin(), s.end(), s.begin(), ToLower); 14 | return s; 15 | } 16 | 17 | template 18 | bool IsEntirely(const std::string& str, T func) { 19 | for (std::size_t i = 0; i < str.size(); i++) 20 | if (!func(str[i])) 21 | return false; 22 | 23 | return true; 24 | } 25 | 26 | // IsFlexibleCase 27 | // . Returns true if 'str' is: 28 | // . UPPERCASE 29 | // . lowercase 30 | // . Capitalized 31 | bool IsFlexibleCase(const std::string& str) { 32 | if (str.empty()) 33 | return true; 34 | 35 | if (IsEntirely(str, IsLower)) 36 | return true; 37 | 38 | bool firstcaps = IsUpper(str[0]); 39 | std::string rest = str.substr(1); 40 | return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper)); 41 | } 42 | } 43 | 44 | namespace YAML { 45 | bool convert::decode(const Node& node, bool& rhs) { 46 | if (!node.IsScalar()) 47 | return false; 48 | 49 | // we can't use iostream bool extraction operators as they don't 50 | // recognize all possible values in the table below (taken from 51 | // http://yaml.org/type/bool.html) 52 | static const struct { 53 | std::string truename, falsename; 54 | } names[] = { 55 | {"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"}, 56 | }; 57 | 58 | if (!IsFlexibleCase(node.Scalar())) 59 | return false; 60 | 61 | for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) { 62 | if (names[i].truename == tolower(node.Scalar())) { 63 | rhs = true; 64 | return true; 65 | } 66 | 67 | if (names[i].falsename == tolower(node.Scalar())) { 68 | rhs = false; 69 | return true; 70 | } 71 | } 72 | 73 | return false; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/directives.cpp: -------------------------------------------------------------------------------- 1 | #include "directives.h" 2 | 3 | namespace YAML { 4 | Directives::Directives() { 5 | // version 6 | version.isDefault = true; 7 | version.major = 1; 8 | version.minor = 2; 9 | } 10 | 11 | const std::string Directives::TranslateTagHandle( 12 | const std::string& handle) const { 13 | std::map::const_iterator it = tags.find(handle); 14 | if (it == tags.end()) { 15 | if (handle == "!!") 16 | return "tag:yaml.org,2002:"; 17 | return handle; 18 | } 19 | 20 | return it->second; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/directives.h: -------------------------------------------------------------------------------- 1 | #ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | namespace YAML { 14 | struct Version { 15 | bool isDefault; 16 | int major, minor; 17 | }; 18 | 19 | struct Directives { 20 | Directives(); 21 | 22 | const std::string TranslateTagHandle(const std::string& handle) const; 23 | 24 | Version version; 25 | std::map tags; 26 | }; 27 | } 28 | 29 | #endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 30 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/emit.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/node/emit.h" 2 | #include "yaml-cpp/emitfromevents.h" 3 | #include "yaml-cpp/emitter.h" 4 | #include "nodeevents.h" 5 | 6 | namespace YAML { 7 | Emitter& operator<<(Emitter& out, const Node& node) { 8 | EmitFromEvents emitFromEvents(out); 9 | NodeEvents events(node); 10 | events.Emit(emitFromEvents); 11 | return out; 12 | } 13 | 14 | std::ostream& operator<<(std::ostream& out, const Node& node) { 15 | Emitter emitter(out); 16 | emitter << node; 17 | return out; 18 | } 19 | 20 | std::string Dump(const Node& node) { 21 | Emitter emitter; 22 | emitter << node; 23 | return emitter.c_str(); 24 | } 25 | } // namespace YAML 26 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/emitfromevents.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "yaml-cpp/emitfromevents.h" 5 | #include "yaml-cpp/emitter.h" 6 | #include "yaml-cpp/emittermanip.h" 7 | #include "yaml-cpp/null.h" 8 | 9 | namespace YAML { 10 | struct Mark; 11 | } // namespace YAML 12 | 13 | namespace { 14 | std::string ToString(YAML::anchor_t anchor) { 15 | std::stringstream stream; 16 | stream << anchor; 17 | return stream.str(); 18 | } 19 | } 20 | 21 | namespace YAML { 22 | EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {} 23 | 24 | void EmitFromEvents::OnDocumentStart(const Mark&) {} 25 | 26 | void EmitFromEvents::OnDocumentEnd() {} 27 | 28 | void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) { 29 | BeginNode(); 30 | EmitProps("", anchor); 31 | m_emitter << Null; 32 | } 33 | 34 | void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) { 35 | BeginNode(); 36 | m_emitter << Alias(ToString(anchor)); 37 | } 38 | 39 | void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, 40 | anchor_t anchor, const std::string& value) { 41 | BeginNode(); 42 | EmitProps(tag, anchor); 43 | m_emitter << value; 44 | } 45 | 46 | void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, 47 | anchor_t anchor, 48 | EmitterStyle::value style) { 49 | BeginNode(); 50 | EmitProps(tag, anchor); 51 | switch (style) { 52 | case EmitterStyle::Block: 53 | m_emitter << Block; 54 | break; 55 | case EmitterStyle::Flow: 56 | m_emitter << Flow; 57 | break; 58 | default: 59 | break; 60 | } 61 | m_emitter << BeginSeq; 62 | m_stateStack.push(State::WaitingForSequenceEntry); 63 | } 64 | 65 | void EmitFromEvents::OnSequenceEnd() { 66 | m_emitter << EndSeq; 67 | assert(m_stateStack.top() == State::WaitingForSequenceEntry); 68 | m_stateStack.pop(); 69 | } 70 | 71 | void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, 72 | anchor_t anchor, EmitterStyle::value style) { 73 | BeginNode(); 74 | EmitProps(tag, anchor); 75 | switch (style) { 76 | case EmitterStyle::Block: 77 | m_emitter << Block; 78 | break; 79 | case EmitterStyle::Flow: 80 | m_emitter << Flow; 81 | break; 82 | default: 83 | break; 84 | } 85 | m_emitter << BeginMap; 86 | m_stateStack.push(State::WaitingForKey); 87 | } 88 | 89 | void EmitFromEvents::OnMapEnd() { 90 | m_emitter << EndMap; 91 | assert(m_stateStack.top() == State::WaitingForKey); 92 | m_stateStack.pop(); 93 | } 94 | 95 | void EmitFromEvents::BeginNode() { 96 | if (m_stateStack.empty()) 97 | return; 98 | 99 | switch (m_stateStack.top()) { 100 | case State::WaitingForKey: 101 | m_emitter << Key; 102 | m_stateStack.top() = State::WaitingForValue; 103 | break; 104 | case State::WaitingForValue: 105 | m_emitter << Value; 106 | m_stateStack.top() = State::WaitingForKey; 107 | break; 108 | default: 109 | break; 110 | } 111 | } 112 | 113 | void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) { 114 | if (!tag.empty() && tag != "?" && tag != "!") 115 | m_emitter << VerbatimTag(tag); 116 | if (anchor) 117 | m_emitter << Anchor(ToString(anchor)); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/emitterutils.h: -------------------------------------------------------------------------------- 1 | #ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "emitterstate.h" 13 | #include "yaml-cpp/emittermanip.h" 14 | #include "yaml-cpp/ostream_wrapper.h" 15 | 16 | namespace YAML { 17 | class ostream_wrapper; 18 | } // namespace YAML 19 | 20 | namespace YAML { 21 | class Binary; 22 | 23 | struct StringFormat { 24 | enum value { Plain, SingleQuoted, DoubleQuoted, Literal }; 25 | }; 26 | 27 | namespace Utils { 28 | StringFormat::value ComputeStringFormat(const std::string& str, 29 | EMITTER_MANIP strFormat, 30 | FlowType::value flowType, 31 | bool escapeNonAscii); 32 | 33 | bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str); 34 | bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, 35 | bool escapeNonAscii); 36 | bool WriteLiteralString(ostream_wrapper& out, const std::string& str, 37 | std::size_t indent); 38 | bool WriteChar(ostream_wrapper& out, char ch); 39 | bool WriteComment(ostream_wrapper& out, const std::string& str, 40 | std::size_t postCommentIndent); 41 | bool WriteAlias(ostream_wrapper& out, const std::string& str); 42 | bool WriteAnchor(ostream_wrapper& out, const std::string& str); 43 | bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim); 44 | bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, 45 | const std::string& tag); 46 | bool WriteBinary(ostream_wrapper& out, const Binary& binary); 47 | } 48 | } 49 | 50 | #endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 51 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/exceptions.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/exceptions.h" 2 | 3 | namespace YAML { 4 | 5 | // These destructors are defined out-of-line so the vtable is only emitted once. 6 | Exception::~Exception() noexcept {} 7 | ParserException::~ParserException() noexcept {} 8 | RepresentationException::~RepresentationException() noexcept {} 9 | InvalidScalar::~InvalidScalar() noexcept {} 10 | KeyNotFound::~KeyNotFound() noexcept {} 11 | InvalidNode::~InvalidNode() noexcept {} 12 | BadConversion::~BadConversion() noexcept {} 13 | BadDereference::~BadDereference() noexcept {} 14 | BadSubscript::~BadSubscript() noexcept {} 15 | BadPushback::~BadPushback() noexcept {} 16 | BadInsert::~BadInsert() noexcept {} 17 | EmitterException::~EmitterException() noexcept {} 18 | BadFile::~BadFile() noexcept {} 19 | } 20 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/exp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "exp.h" 4 | #include "stream.h" 5 | #include "yaml-cpp/exceptions.h" // IWYU pragma: keep 6 | 7 | namespace YAML { 8 | struct Mark; 9 | } // namespace YAML 10 | 11 | namespace YAML { 12 | namespace Exp { 13 | unsigned ParseHex(const std::string& str, const Mark& mark) { 14 | unsigned value = 0; 15 | for (std::size_t i = 0; i < str.size(); i++) { 16 | char ch = str[i]; 17 | int digit = 0; 18 | if ('a' <= ch && ch <= 'f') 19 | digit = ch - 'a' + 10; 20 | else if ('A' <= ch && ch <= 'F') 21 | digit = ch - 'A' + 10; 22 | else if ('0' <= ch && ch <= '9') 23 | digit = ch - '0'; 24 | else 25 | throw ParserException(mark, ErrorMsg::INVALID_HEX); 26 | 27 | value = (value << 4) + digit; 28 | } 29 | 30 | return value; 31 | } 32 | 33 | std::string Str(unsigned ch) { return std::string(1, static_cast(ch)); } 34 | 35 | // Escape 36 | // . Translates the next 'codeLength' characters into a hex number and returns 37 | // the result. 38 | // . Throws if it's not actually hex. 39 | std::string Escape(Stream& in, int codeLength) { 40 | // grab string 41 | std::string str; 42 | for (int i = 0; i < codeLength; i++) 43 | str += in.get(); 44 | 45 | // get the value 46 | unsigned value = ParseHex(str, in.mark()); 47 | 48 | // legal unicode? 49 | if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { 50 | std::stringstream msg; 51 | msg << ErrorMsg::INVALID_UNICODE << value; 52 | throw ParserException(in.mark(), msg.str()); 53 | } 54 | 55 | // now break it up into chars 56 | if (value <= 0x7F) 57 | return Str(value); 58 | else if (value <= 0x7FF) 59 | return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F)); 60 | else if (value <= 0xFFFF) 61 | return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + 62 | Str(0x80 + (value & 0x3F)); 63 | else 64 | return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + 65 | Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); 66 | } 67 | 68 | // Escape 69 | // . Escapes the sequence starting 'in' (it must begin with a '\' or single 70 | // quote) 71 | // and returns the result. 72 | // . Throws if it's an unknown escape character. 73 | std::string Escape(Stream& in) { 74 | // eat slash 75 | char escape = in.get(); 76 | 77 | // switch on escape character 78 | char ch = in.get(); 79 | 80 | // first do single quote, since it's easier 81 | if (escape == '\'' && ch == '\'') 82 | return "\'"; 83 | 84 | // now do the slash (we're not gonna check if it's a slash - you better pass 85 | // one!) 86 | switch (ch) { 87 | case '0': 88 | return std::string(1, '\x00'); 89 | case 'a': 90 | return "\x07"; 91 | case 'b': 92 | return "\x08"; 93 | case 't': 94 | case '\t': 95 | return "\x09"; 96 | case 'n': 97 | return "\x0A"; 98 | case 'v': 99 | return "\x0B"; 100 | case 'f': 101 | return "\x0C"; 102 | case 'r': 103 | return "\x0D"; 104 | case 'e': 105 | return "\x1B"; 106 | case ' ': 107 | return "\x20"; 108 | case '\"': 109 | return "\""; 110 | case '\'': 111 | return "\'"; 112 | case '\\': 113 | return "\\"; 114 | case '/': 115 | return "/"; 116 | case 'N': 117 | return "\x85"; 118 | case '_': 119 | return "\xA0"; 120 | case 'L': 121 | return "\xE2\x80\xA8"; // LS (#x2028) 122 | case 'P': 123 | return "\xE2\x80\xA9"; // PS (#x2029) 124 | case 'x': 125 | return Escape(in, 2); 126 | case 'u': 127 | return Escape(in, 4); 128 | case 'U': 129 | return Escape(in, 8); 130 | } 131 | 132 | std::stringstream msg; 133 | throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch); 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/indentation.h: -------------------------------------------------------------------------------- 1 | #ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | #include "yaml-cpp/ostream_wrapper.h" 14 | 15 | namespace YAML { 16 | struct Indentation { 17 | Indentation(std::size_t n_) : n(n_) {} 18 | std::size_t n; 19 | }; 20 | 21 | inline ostream_wrapper& operator<<(ostream_wrapper& out, 22 | const Indentation& indent) { 23 | for (std::size_t i = 0; i < indent.n; i++) 24 | out << ' '; 25 | return out; 26 | } 27 | 28 | struct IndentTo { 29 | IndentTo(std::size_t n_) : n(n_) {} 30 | std::size_t n; 31 | }; 32 | 33 | inline ostream_wrapper& operator<<(ostream_wrapper& out, 34 | const IndentTo& indent) { 35 | while (out.col() < indent.n) 36 | out << ' '; 37 | return out; 38 | } 39 | } 40 | 41 | #endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 42 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/memory.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/node/detail/memory.h" 2 | #include "yaml-cpp/node/detail/node.h" // IWYU pragma: keep 3 | #include "yaml-cpp/node/ptr.h" 4 | 5 | namespace YAML { 6 | namespace detail { 7 | 8 | void memory_holder::merge(memory_holder& rhs) { 9 | if (m_pMemory == rhs.m_pMemory) 10 | return; 11 | 12 | m_pMemory->merge(*rhs.m_pMemory); 13 | rhs.m_pMemory = m_pMemory; 14 | } 15 | 16 | node& memory::create_node() { 17 | shared_node pNode(new node); 18 | m_nodes.insert(pNode); 19 | return *pNode; 20 | } 21 | 22 | void memory::merge(const memory& rhs) { 23 | m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/node.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/node/node.h" 2 | #include "nodebuilder.h" 3 | #include "nodeevents.h" 4 | 5 | namespace YAML { 6 | Node Clone(const Node& node) { 7 | NodeEvents events(node); 8 | NodeBuilder builder; 9 | events.Emit(builder); 10 | return builder.Root(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/nodebuilder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "nodebuilder.h" 5 | #include "yaml-cpp/node/detail/node.h" 6 | #include "yaml-cpp/node/impl.h" 7 | #include "yaml-cpp/node/node.h" 8 | #include "yaml-cpp/node/type.h" 9 | 10 | namespace YAML { 11 | struct Mark; 12 | 13 | NodeBuilder::NodeBuilder() 14 | : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) { 15 | m_anchors.push_back(0); // since the anchors start at 1 16 | } 17 | 18 | NodeBuilder::~NodeBuilder() {} 19 | 20 | Node NodeBuilder::Root() { 21 | if (!m_pRoot) 22 | return Node(); 23 | 24 | return Node(*m_pRoot, m_pMemory); 25 | } 26 | 27 | void NodeBuilder::OnDocumentStart(const Mark&) {} 28 | 29 | void NodeBuilder::OnDocumentEnd() {} 30 | 31 | void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) { 32 | detail::node& node = Push(mark, anchor); 33 | node.set_null(); 34 | Pop(); 35 | } 36 | 37 | void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) { 38 | detail::node& node = *m_anchors[anchor]; 39 | Push(node); 40 | Pop(); 41 | } 42 | 43 | void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag, 44 | anchor_t anchor, const std::string& value) { 45 | detail::node& node = Push(mark, anchor); 46 | node.set_scalar(value); 47 | node.set_tag(tag); 48 | Pop(); 49 | } 50 | 51 | void NodeBuilder::OnSequenceStart(const Mark& mark, const std::string& tag, 52 | anchor_t anchor, EmitterStyle::value style) { 53 | detail::node& node = Push(mark, anchor); 54 | node.set_tag(tag); 55 | node.set_type(NodeType::Sequence); 56 | node.set_style(style); 57 | } 58 | 59 | void NodeBuilder::OnSequenceEnd() { Pop(); } 60 | 61 | void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag, 62 | anchor_t anchor, EmitterStyle::value style) { 63 | detail::node& node = Push(mark, anchor); 64 | node.set_type(NodeType::Map); 65 | node.set_tag(tag); 66 | node.set_style(style); 67 | m_mapDepth++; 68 | } 69 | 70 | void NodeBuilder::OnMapEnd() { 71 | assert(m_mapDepth > 0); 72 | m_mapDepth--; 73 | Pop(); 74 | } 75 | 76 | detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) { 77 | detail::node& node = m_pMemory->create_node(); 78 | node.set_mark(mark); 79 | RegisterAnchor(anchor, node); 80 | Push(node); 81 | return node; 82 | } 83 | 84 | void NodeBuilder::Push(detail::node& node) { 85 | const bool needsKey = 86 | (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && 87 | m_keys.size() < m_mapDepth); 88 | 89 | m_stack.push_back(&node); 90 | if (needsKey) 91 | m_keys.push_back(PushedKey(&node, false)); 92 | } 93 | 94 | void NodeBuilder::Pop() { 95 | assert(!m_stack.empty()); 96 | if (m_stack.size() == 1) { 97 | m_pRoot = m_stack[0]; 98 | m_stack.pop_back(); 99 | return; 100 | } 101 | 102 | detail::node& node = *m_stack.back(); 103 | m_stack.pop_back(); 104 | 105 | detail::node& collection = *m_stack.back(); 106 | 107 | if (collection.type() == NodeType::Sequence) { 108 | collection.push_back(node, m_pMemory); 109 | } else if (collection.type() == NodeType::Map) { 110 | assert(!m_keys.empty()); 111 | PushedKey& key = m_keys.back(); 112 | if (key.second) { 113 | collection.insert(*key.first, node, m_pMemory); 114 | m_keys.pop_back(); 115 | } else { 116 | key.second = true; 117 | } 118 | } else { 119 | assert(false); 120 | m_stack.clear(); 121 | } 122 | } 123 | 124 | void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) { 125 | if (anchor) { 126 | assert(anchor == m_anchors.size()); 127 | m_anchors.push_back(&node); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/nodebuilder.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "yaml-cpp/anchor.h" 13 | #include "yaml-cpp/emitterstyle.h" 14 | #include "yaml-cpp/eventhandler.h" 15 | #include "yaml-cpp/node/ptr.h" 16 | 17 | namespace YAML { 18 | namespace detail { 19 | class node; 20 | } // namespace detail 21 | struct Mark; 22 | } // namespace YAML 23 | 24 | namespace YAML { 25 | class Node; 26 | 27 | class NodeBuilder : public EventHandler { 28 | public: 29 | NodeBuilder(); 30 | virtual ~NodeBuilder(); 31 | 32 | Node Root(); 33 | 34 | virtual void OnDocumentStart(const Mark& mark); 35 | virtual void OnDocumentEnd(); 36 | 37 | virtual void OnNull(const Mark& mark, anchor_t anchor); 38 | virtual void OnAlias(const Mark& mark, anchor_t anchor); 39 | virtual void OnScalar(const Mark& mark, const std::string& tag, 40 | anchor_t anchor, const std::string& value); 41 | 42 | virtual void OnSequenceStart(const Mark& mark, const std::string& tag, 43 | anchor_t anchor, EmitterStyle::value style); 44 | virtual void OnSequenceEnd(); 45 | 46 | virtual void OnMapStart(const Mark& mark, const std::string& tag, 47 | anchor_t anchor, EmitterStyle::value style); 48 | virtual void OnMapEnd(); 49 | 50 | private: 51 | detail::node& Push(const Mark& mark, anchor_t anchor); 52 | void Push(detail::node& node); 53 | void Pop(); 54 | void RegisterAnchor(anchor_t anchor, detail::node& node); 55 | 56 | private: 57 | detail::shared_memory_holder m_pMemory; 58 | detail::node* m_pRoot; 59 | 60 | typedef std::vector Nodes; 61 | Nodes m_stack; 62 | Nodes m_anchors; 63 | 64 | typedef std::pair PushedKey; 65 | std::vector m_keys; 66 | std::size_t m_mapDepth; 67 | }; 68 | } 69 | 70 | #endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 71 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/nodeevents.cpp: -------------------------------------------------------------------------------- 1 | #include "nodeevents.h" 2 | #include "yaml-cpp/eventhandler.h" 3 | #include "yaml-cpp/mark.h" 4 | #include "yaml-cpp/node/detail/node.h" 5 | #include "yaml-cpp/node/detail/node_iterator.h" 6 | #include "yaml-cpp/node/node.h" 7 | #include "yaml-cpp/node/type.h" 8 | 9 | namespace YAML { 10 | void NodeEvents::AliasManager::RegisterReference(const detail::node& node) { 11 | m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor())); 12 | } 13 | 14 | anchor_t NodeEvents::AliasManager::LookupAnchor( 15 | const detail::node& node) const { 16 | AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref()); 17 | if (it == m_anchorByIdentity.end()) 18 | return 0; 19 | return it->second; 20 | } 21 | 22 | NodeEvents::NodeEvents(const Node& node) 23 | : m_pMemory(node.m_pMemory), m_root(node.m_pNode) { 24 | if (m_root) 25 | Setup(*m_root); 26 | } 27 | 28 | void NodeEvents::Setup(const detail::node& node) { 29 | int& refCount = m_refCount[node.ref()]; 30 | refCount++; 31 | if (refCount > 1) 32 | return; 33 | 34 | if (node.type() == NodeType::Sequence) { 35 | for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it) 36 | Setup(**it); 37 | } else if (node.type() == NodeType::Map) { 38 | for (detail::const_node_iterator it = node.begin(); it != node.end(); 39 | ++it) { 40 | Setup(*it->first); 41 | Setup(*it->second); 42 | } 43 | } 44 | } 45 | 46 | void NodeEvents::Emit(EventHandler& handler) { 47 | AliasManager am; 48 | 49 | handler.OnDocumentStart(Mark()); 50 | if (m_root) 51 | Emit(*m_root, handler, am); 52 | handler.OnDocumentEnd(); 53 | } 54 | 55 | void NodeEvents::Emit(const detail::node& node, EventHandler& handler, 56 | AliasManager& am) const { 57 | anchor_t anchor = NullAnchor; 58 | if (IsAliased(node)) { 59 | anchor = am.LookupAnchor(node); 60 | if (anchor) { 61 | handler.OnAlias(Mark(), anchor); 62 | return; 63 | } 64 | 65 | am.RegisterReference(node); 66 | anchor = am.LookupAnchor(node); 67 | } 68 | 69 | switch (node.type()) { 70 | case NodeType::Undefined: 71 | break; 72 | case NodeType::Null: 73 | handler.OnNull(Mark(), anchor); 74 | break; 75 | case NodeType::Scalar: 76 | handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); 77 | break; 78 | case NodeType::Sequence: 79 | handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style()); 80 | for (detail::const_node_iterator it = node.begin(); it != node.end(); 81 | ++it) 82 | Emit(**it, handler, am); 83 | handler.OnSequenceEnd(); 84 | break; 85 | case NodeType::Map: 86 | handler.OnMapStart(Mark(), node.tag(), anchor, node.style()); 87 | for (detail::const_node_iterator it = node.begin(); it != node.end(); 88 | ++it) { 89 | Emit(*it->first, handler, am); 90 | Emit(*it->second, handler, am); 91 | } 92 | handler.OnMapEnd(); 93 | break; 94 | } 95 | } 96 | 97 | bool NodeEvents::IsAliased(const detail::node& node) const { 98 | RefCount::const_iterator it = m_refCount.find(node.ref()); 99 | return it != m_refCount.end() && it->second > 1; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/nodeevents.h: -------------------------------------------------------------------------------- 1 | #ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | #include "yaml-cpp/anchor.h" 14 | #include "yaml-cpp/node/ptr.h" 15 | 16 | namespace YAML { 17 | namespace detail { 18 | class node; 19 | } // namespace detail 20 | } // namespace YAML 21 | 22 | namespace YAML { 23 | class EventHandler; 24 | class Node; 25 | 26 | class NodeEvents { 27 | public: 28 | explicit NodeEvents(const Node& node); 29 | 30 | void Emit(EventHandler& handler); 31 | 32 | private: 33 | class AliasManager { 34 | public: 35 | AliasManager() : m_curAnchor(0) {} 36 | 37 | void RegisterReference(const detail::node& node); 38 | anchor_t LookupAnchor(const detail::node& node) const; 39 | 40 | private: 41 | anchor_t _CreateNewAnchor() { return ++m_curAnchor; } 42 | 43 | private: 44 | typedef std::map AnchorByIdentity; 45 | AnchorByIdentity m_anchorByIdentity; 46 | 47 | anchor_t m_curAnchor; 48 | }; 49 | 50 | void Setup(const detail::node& node); 51 | void Emit(const detail::node& node, EventHandler& handler, 52 | AliasManager& am) const; 53 | bool IsAliased(const detail::node& node) const; 54 | 55 | private: 56 | detail::shared_memory_holder m_pMemory; 57 | detail::node* m_root; 58 | 59 | typedef std::map RefCount; 60 | RefCount m_refCount; 61 | }; 62 | } 63 | 64 | #endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 65 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/null.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/null.h" 2 | 3 | namespace YAML { 4 | _Null Null; 5 | 6 | bool IsNullString(const std::string& str) { 7 | return str.empty() || str == "~" || str == "null" || str == "Null" || 8 | str == "NULL"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/ostream_wrapper.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/ostream_wrapper.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace YAML { 8 | ostream_wrapper::ostream_wrapper() 9 | : m_buffer(1, '\0'), 10 | m_pStream(0), 11 | m_pos(0), 12 | m_row(0), 13 | m_col(0), 14 | m_comment(false) {} 15 | 16 | ostream_wrapper::ostream_wrapper(std::ostream& stream) 17 | : m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {} 18 | 19 | ostream_wrapper::~ostream_wrapper() {} 20 | 21 | void ostream_wrapper::write(const std::string& str) { 22 | if (m_pStream) { 23 | m_pStream->write(str.c_str(), str.size()); 24 | } else { 25 | m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); 26 | std::copy(str.begin(), str.end(), m_buffer.begin() + m_pos); 27 | } 28 | 29 | for (std::size_t i = 0; i < str.size(); i++) { 30 | update_pos(str[i]); 31 | } 32 | } 33 | 34 | void ostream_wrapper::write(const char* str, std::size_t size) { 35 | if (m_pStream) { 36 | m_pStream->write(str, size); 37 | } else { 38 | m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1)); 39 | std::copy(str, str + size, m_buffer.begin() + m_pos); 40 | } 41 | 42 | for (std::size_t i = 0; i < size; i++) { 43 | update_pos(str[i]); 44 | } 45 | } 46 | 47 | void ostream_wrapper::update_pos(char ch) { 48 | m_pos++; 49 | m_col++; 50 | 51 | if (ch == '\n') { 52 | m_row++; 53 | m_col = 0; 54 | m_comment = false; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/parse.cpp: -------------------------------------------------------------------------------- 1 | #include "yaml-cpp/node/parse.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "yaml-cpp/node/node.h" 7 | #include "yaml-cpp/node/impl.h" 8 | #include "yaml-cpp/parser.h" 9 | #include "nodebuilder.h" 10 | 11 | namespace YAML { 12 | Node Load(const std::string& input) { 13 | std::stringstream stream(input); 14 | return Load(stream); 15 | } 16 | 17 | Node Load(const char* input) { 18 | std::stringstream stream(input); 19 | return Load(stream); 20 | } 21 | 22 | Node Load(std::istream& input) { 23 | Parser parser(input); 24 | NodeBuilder builder; 25 | if (!parser.HandleNextDocument(builder)) { 26 | return Node(); 27 | } 28 | 29 | return builder.Root(); 30 | } 31 | 32 | Node LoadFile(const std::string& filename) { 33 | std::ifstream fin(filename.c_str()); 34 | if (!fin) { 35 | throw BadFile(); 36 | } 37 | return Load(fin); 38 | } 39 | 40 | std::vector LoadAll(const std::string& input) { 41 | std::stringstream stream(input); 42 | return LoadAll(stream); 43 | } 44 | 45 | std::vector LoadAll(const char* input) { 46 | std::stringstream stream(input); 47 | return LoadAll(stream); 48 | } 49 | 50 | std::vector LoadAll(std::istream& input) { 51 | std::vector docs; 52 | 53 | Parser parser(input); 54 | while (1) { 55 | NodeBuilder builder; 56 | if (!parser.HandleNextDocument(builder)) { 57 | break; 58 | } 59 | docs.push_back(builder.Root()); 60 | } 61 | 62 | return docs; 63 | } 64 | 65 | std::vector LoadAllFromFile(const std::string& filename) { 66 | std::ifstream fin(filename.c_str()); 67 | if (!fin) { 68 | throw BadFile(); 69 | } 70 | return LoadAll(fin); 71 | } 72 | } // namespace YAML 73 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/parser.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "directives.h" // IWYU pragma: keep 5 | #include "scanner.h" // IWYU pragma: keep 6 | #include "singledocparser.h" 7 | #include "token.h" 8 | #include "yaml-cpp/exceptions.h" // IWYU pragma: keep 9 | #include "yaml-cpp/parser.h" 10 | 11 | namespace YAML { 12 | class EventHandler; 13 | 14 | Parser::Parser() {} 15 | 16 | Parser::Parser(std::istream& in) { Load(in); } 17 | 18 | Parser::~Parser() {} 19 | 20 | Parser::operator bool() const { 21 | return m_pScanner.get() && !m_pScanner->empty(); 22 | } 23 | 24 | void Parser::Load(std::istream& in) { 25 | m_pScanner.reset(new Scanner(in)); 26 | m_pDirectives.reset(new Directives); 27 | } 28 | 29 | bool Parser::HandleNextDocument(EventHandler& eventHandler) { 30 | if (!m_pScanner.get()) 31 | return false; 32 | 33 | ParseDirectives(); 34 | if (m_pScanner->empty()) { 35 | return false; 36 | } 37 | 38 | SingleDocParser sdp(*m_pScanner, *m_pDirectives); 39 | sdp.HandleDocument(eventHandler); 40 | return true; 41 | } 42 | 43 | void Parser::ParseDirectives() { 44 | bool readDirective = false; 45 | 46 | while (1) { 47 | if (m_pScanner->empty()) { 48 | break; 49 | } 50 | 51 | Token& token = m_pScanner->peek(); 52 | if (token.type != Token::DIRECTIVE) { 53 | break; 54 | } 55 | 56 | // we keep the directives from the last document if none are specified; 57 | // but if any directives are specific, then we reset them 58 | if (!readDirective) { 59 | m_pDirectives.reset(new Directives); 60 | } 61 | 62 | readDirective = true; 63 | HandleDirective(token); 64 | m_pScanner->pop(); 65 | } 66 | } 67 | 68 | void Parser::HandleDirective(const Token& token) { 69 | if (token.value == "YAML") { 70 | HandleYamlDirective(token); 71 | } else if (token.value == "TAG") { 72 | HandleTagDirective(token); 73 | } 74 | } 75 | 76 | void Parser::HandleYamlDirective(const Token& token) { 77 | if (token.params.size() != 1) { 78 | throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS); 79 | } 80 | 81 | if (!m_pDirectives->version.isDefault) { 82 | throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE); 83 | } 84 | 85 | std::stringstream str(token.params[0]); 86 | str >> m_pDirectives->version.major; 87 | str.get(); 88 | str >> m_pDirectives->version.minor; 89 | if (!str || str.peek() != EOF) { 90 | throw ParserException( 91 | token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]); 92 | } 93 | 94 | if (m_pDirectives->version.major > 1) { 95 | throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION); 96 | } 97 | 98 | m_pDirectives->version.isDefault = false; 99 | // TODO: warning on major == 1, minor > 2? 100 | } 101 | 102 | void Parser::HandleTagDirective(const Token& token) { 103 | if (token.params.size() != 2) 104 | throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS); 105 | 106 | const std::string& handle = token.params[0]; 107 | const std::string& prefix = token.params[1]; 108 | if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) { 109 | throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE); 110 | } 111 | 112 | m_pDirectives->tags[handle] = prefix; 113 | } 114 | 115 | void Parser::PrintTokens(std::ostream& out) { 116 | if (!m_pScanner.get()) { 117 | return; 118 | } 119 | 120 | while (1) { 121 | if (m_pScanner->empty()) { 122 | break; 123 | } 124 | 125 | out << m_pScanner->peek() << "\n"; 126 | m_pScanner->pop(); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/ptr_vector.h: -------------------------------------------------------------------------------- 1 | #ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "yaml-cpp/noncopyable.h" 16 | 17 | namespace YAML { 18 | 19 | // TODO: This class is no longer needed 20 | template 21 | class ptr_vector : private YAML::noncopyable { 22 | public: 23 | ptr_vector() {} 24 | 25 | void clear() { m_data.clear(); } 26 | 27 | std::size_t size() const { return m_data.size(); } 28 | bool empty() const { return m_data.empty(); } 29 | 30 | void push_back(std::unique_ptr&& t) { m_data.push_back(std::move(t)); } 31 | T& operator[](std::size_t i) { return *m_data[i]; } 32 | const T& operator[](std::size_t i) const { return *m_data[i]; } 33 | 34 | T& back() { return *(m_data.back().get()); } 35 | 36 | const T& back() const { return *(m_data.back().get()); } 37 | 38 | private: 39 | std::vector> m_data; 40 | }; 41 | } 42 | 43 | #endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 44 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/regex_yaml.cpp: -------------------------------------------------------------------------------- 1 | #include "regex_yaml.h" 2 | 3 | namespace YAML { 4 | // constructors 5 | RegEx::RegEx() : m_op(REGEX_EMPTY) {} 6 | 7 | RegEx::RegEx(REGEX_OP op) : m_op(op) {} 8 | 9 | RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {} 10 | 11 | RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {} 12 | 13 | RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) { 14 | for (std::size_t i = 0; i < str.size(); i++) 15 | m_params.push_back(RegEx(str[i])); 16 | } 17 | 18 | // combination constructors 19 | RegEx operator!(const RegEx& ex) { 20 | RegEx ret(REGEX_NOT); 21 | ret.m_params.push_back(ex); 22 | return ret; 23 | } 24 | 25 | RegEx operator||(const RegEx& ex1, const RegEx& ex2) { 26 | RegEx ret(REGEX_OR); 27 | ret.m_params.push_back(ex1); 28 | ret.m_params.push_back(ex2); 29 | return ret; 30 | } 31 | 32 | RegEx operator&&(const RegEx& ex1, const RegEx& ex2) { 33 | RegEx ret(REGEX_AND); 34 | ret.m_params.push_back(ex1); 35 | ret.m_params.push_back(ex2); 36 | return ret; 37 | } 38 | 39 | RegEx operator+(const RegEx& ex1, const RegEx& ex2) { 40 | RegEx ret(REGEX_SEQ); 41 | ret.m_params.push_back(ex1); 42 | ret.m_params.push_back(ex2); 43 | return ret; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/regex_yaml.h: -------------------------------------------------------------------------------- 1 | #ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | 13 | #include "yaml-cpp/dll.h" 14 | 15 | namespace YAML { 16 | class Stream; 17 | 18 | enum REGEX_OP { 19 | REGEX_EMPTY, 20 | REGEX_MATCH, 21 | REGEX_RANGE, 22 | REGEX_OR, 23 | REGEX_AND, 24 | REGEX_NOT, 25 | REGEX_SEQ 26 | }; 27 | 28 | // simplified regular expressions 29 | // . Only straightforward matches (no repeated characters) 30 | // . Only matches from start of string 31 | class YAML_CPP_API RegEx { 32 | public: 33 | RegEx(); 34 | RegEx(char ch); 35 | RegEx(char a, char z); 36 | RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ); 37 | ~RegEx() {} 38 | 39 | friend YAML_CPP_API RegEx operator!(const RegEx& ex); 40 | friend YAML_CPP_API RegEx operator||(const RegEx& ex1, const RegEx& ex2); 41 | friend YAML_CPP_API RegEx operator&&(const RegEx& ex1, const RegEx& ex2); 42 | friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2); 43 | 44 | bool Matches(char ch) const; 45 | bool Matches(const std::string& str) const; 46 | bool Matches(const Stream& in) const; 47 | template 48 | bool Matches(const Source& source) const; 49 | 50 | int Match(const std::string& str) const; 51 | int Match(const Stream& in) const; 52 | template 53 | int Match(const Source& source) const; 54 | 55 | private: 56 | RegEx(REGEX_OP op); 57 | 58 | template 59 | bool IsValidSource(const Source& source) const; 60 | template 61 | int MatchUnchecked(const Source& source) const; 62 | 63 | template 64 | int MatchOpEmpty(const Source& source) const; 65 | template 66 | int MatchOpMatch(const Source& source) const; 67 | template 68 | int MatchOpRange(const Source& source) const; 69 | template 70 | int MatchOpOr(const Source& source) const; 71 | template 72 | int MatchOpAnd(const Source& source) const; 73 | template 74 | int MatchOpNot(const Source& source) const; 75 | template 76 | int MatchOpSeq(const Source& source) const; 77 | 78 | private: 79 | REGEX_OP m_op; 80 | char m_a, m_z; 81 | std::vector m_params; 82 | }; 83 | } 84 | 85 | #include "regeximpl.h" 86 | 87 | #endif // REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 88 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/scanscalar.h: -------------------------------------------------------------------------------- 1 | #ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | #include "regex_yaml.h" 13 | #include "stream.h" 14 | 15 | namespace YAML { 16 | enum CHOMP { STRIP = -1, CLIP, KEEP }; 17 | enum ACTION { NONE, BREAK, THROW }; 18 | enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW }; 19 | 20 | struct ScanScalarParams { 21 | ScanScalarParams() 22 | : end(nullptr), 23 | eatEnd(false), 24 | indent(0), 25 | detectIndent(false), 26 | eatLeadingWhitespace(0), 27 | escape(0), 28 | fold(DONT_FOLD), 29 | trimTrailingSpaces(0), 30 | chomp(CLIP), 31 | onDocIndicator(NONE), 32 | onTabInIndentation(NONE), 33 | leadingSpaces(false) {} 34 | 35 | // input: 36 | const RegEx* end; // what condition ends this scalar? 37 | // unowned. 38 | bool eatEnd; // should we eat that condition when we see it? 39 | int indent; // what level of indentation should be eaten and ignored? 40 | bool detectIndent; // should we try to autodetect the indent? 41 | bool eatLeadingWhitespace; // should we continue eating this delicious 42 | // indentation after 'indent' spaces? 43 | char escape; // what character do we escape on (i.e., slash or single quote) 44 | // (0 for none) 45 | FOLD fold; // how do we fold line ends? 46 | bool trimTrailingSpaces; // do we remove all trailing spaces (at the very 47 | // end) 48 | CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very 49 | // end) 50 | // Note: strip means kill all, clip means keep at most one, keep means keep 51 | // all 52 | ACTION onDocIndicator; // what do we do if we see a document indicator? 53 | ACTION onTabInIndentation; // what do we do if we see a tab where we should 54 | // be seeing indentation spaces 55 | 56 | // output: 57 | bool leadingSpaces; 58 | }; 59 | 60 | std::string ScanScalar(Stream& INPUT, ScanScalarParams& info); 61 | } 62 | 63 | #endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 64 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/scantag.cpp: -------------------------------------------------------------------------------- 1 | #include "exp.h" 2 | #include "regex_yaml.h" 3 | #include "regeximpl.h" 4 | #include "stream.h" 5 | #include "yaml-cpp/exceptions.h" // IWYU pragma: keep 6 | #include "yaml-cpp/mark.h" 7 | 8 | namespace YAML { 9 | const std::string ScanVerbatimTag(Stream& INPUT) { 10 | std::string tag; 11 | 12 | // eat the start character 13 | INPUT.get(); 14 | 15 | while (INPUT) { 16 | if (INPUT.peek() == Keys::VerbatimTagEnd) { 17 | // eat the end character 18 | INPUT.get(); 19 | return tag; 20 | } 21 | 22 | int n = Exp::URI().Match(INPUT); 23 | if (n <= 0) 24 | break; 25 | 26 | tag += INPUT.get(n); 27 | } 28 | 29 | throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG); 30 | } 31 | 32 | const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) { 33 | std::string tag; 34 | canBeHandle = true; 35 | Mark firstNonWordChar; 36 | 37 | while (INPUT) { 38 | if (INPUT.peek() == Keys::Tag) { 39 | if (!canBeHandle) 40 | throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE); 41 | break; 42 | } 43 | 44 | int n = 0; 45 | if (canBeHandle) { 46 | n = Exp::Word().Match(INPUT); 47 | if (n <= 0) { 48 | canBeHandle = false; 49 | firstNonWordChar = INPUT.mark(); 50 | } 51 | } 52 | 53 | if (!canBeHandle) 54 | n = Exp::Tag().Match(INPUT); 55 | 56 | if (n <= 0) 57 | break; 58 | 59 | tag += INPUT.get(n); 60 | } 61 | 62 | return tag; 63 | } 64 | 65 | const std::string ScanTagSuffix(Stream& INPUT) { 66 | std::string tag; 67 | 68 | while (INPUT) { 69 | int n = Exp::Tag().Match(INPUT); 70 | if (n <= 0) 71 | break; 72 | 73 | tag += INPUT.get(n); 74 | } 75 | 76 | if (tag.empty()) 77 | throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX); 78 | 79 | return tag; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/scantag.h: -------------------------------------------------------------------------------- 1 | #ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include "stream.h" 12 | 13 | namespace YAML { 14 | const std::string ScanVerbatimTag(Stream& INPUT); 15 | const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle); 16 | const std::string ScanTagSuffix(Stream& INPUT); 17 | } 18 | 19 | #endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 20 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/setting.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | #include "yaml-cpp/noncopyable.h" 13 | 14 | namespace YAML { 15 | class SettingChangeBase; 16 | 17 | template 18 | class Setting { 19 | public: 20 | Setting() : m_value() {} 21 | 22 | const T get() const { return m_value; } 23 | std::unique_ptr set(const T& value); 24 | void restore(const Setting& oldSetting) { m_value = oldSetting.get(); } 25 | 26 | private: 27 | T m_value; 28 | }; 29 | 30 | class SettingChangeBase { 31 | public: 32 | virtual ~SettingChangeBase() {} 33 | virtual void pop() = 0; 34 | }; 35 | 36 | template 37 | class SettingChange : public SettingChangeBase { 38 | public: 39 | SettingChange(Setting* pSetting) : m_pCurSetting(pSetting) { 40 | // copy old setting to save its state 41 | m_oldSetting = *pSetting; 42 | } 43 | 44 | virtual void pop() { m_pCurSetting->restore(m_oldSetting); } 45 | 46 | private: 47 | Setting* m_pCurSetting; 48 | Setting m_oldSetting; 49 | }; 50 | 51 | template 52 | inline std::unique_ptr Setting::set(const T& value) { 53 | std::unique_ptr pChange(new SettingChange(this)); 54 | m_value = value; 55 | return pChange; 56 | } 57 | 58 | class SettingChanges : private noncopyable { 59 | public: 60 | SettingChanges() {} 61 | ~SettingChanges() { clear(); } 62 | 63 | void clear() { 64 | restore(); 65 | m_settingChanges.clear(); 66 | } 67 | 68 | void restore() { 69 | for (setting_changes::const_iterator it = m_settingChanges.begin(); 70 | it != m_settingChanges.end(); ++it) 71 | (*it)->pop(); 72 | } 73 | 74 | void push(std::unique_ptr pSettingChange) { 75 | m_settingChanges.push_back(std::move(pSettingChange)); 76 | } 77 | 78 | // like std::unique_ptr - assignment is transfer of ownership 79 | SettingChanges& operator=(SettingChanges&& rhs) { 80 | if (this == &rhs) 81 | return *this; 82 | 83 | clear(); 84 | std::swap(m_settingChanges, rhs.m_settingChanges); 85 | 86 | return *this; 87 | } 88 | 89 | private: 90 | typedef std::vector> setting_changes; 91 | setting_changes m_settingChanges; 92 | }; 93 | } 94 | 95 | #endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 96 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/simplekey.cpp: -------------------------------------------------------------------------------- 1 | #include "scanner.h" 2 | #include "token.h" 3 | 4 | namespace YAML { 5 | struct Mark; 6 | 7 | Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_) 8 | : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {} 9 | 10 | void Scanner::SimpleKey::Validate() { 11 | // Note: pIndent will *not* be garbage here; 12 | // we "garbage collect" them so we can 13 | // always refer to them 14 | if (pIndent) 15 | pIndent->status = IndentMarker::VALID; 16 | if (pMapStart) 17 | pMapStart->status = Token::VALID; 18 | if (pKey) 19 | pKey->status = Token::VALID; 20 | } 21 | 22 | void Scanner::SimpleKey::Invalidate() { 23 | if (pIndent) 24 | pIndent->status = IndentMarker::INVALID; 25 | if (pMapStart) 26 | pMapStart->status = Token::INVALID; 27 | if (pKey) 28 | pKey->status = Token::INVALID; 29 | } 30 | 31 | // CanInsertPotentialSimpleKey 32 | bool Scanner::CanInsertPotentialSimpleKey() const { 33 | if (!m_simpleKeyAllowed) 34 | return false; 35 | 36 | return !ExistsActiveSimpleKey(); 37 | } 38 | 39 | // ExistsActiveSimpleKey 40 | // . Returns true if there's a potential simple key at our flow level 41 | // (there's allowed at most one per flow level, i.e., at the start of the flow 42 | // start token) 43 | bool Scanner::ExistsActiveSimpleKey() const { 44 | if (m_simpleKeys.empty()) 45 | return false; 46 | 47 | const SimpleKey& key = m_simpleKeys.top(); 48 | return key.flowLevel == GetFlowLevel(); 49 | } 50 | 51 | // InsertPotentialSimpleKey 52 | // . If we can, add a potential simple key to the queue, 53 | // and save it on a stack. 54 | void Scanner::InsertPotentialSimpleKey() { 55 | if (!CanInsertPotentialSimpleKey()) 56 | return; 57 | 58 | SimpleKey key(INPUT.mark(), GetFlowLevel()); 59 | 60 | // first add a map start, if necessary 61 | if (InBlockContext()) { 62 | key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP); 63 | if (key.pIndent) { 64 | key.pIndent->status = IndentMarker::UNKNOWN; 65 | key.pMapStart = key.pIndent->pStartToken; 66 | key.pMapStart->status = Token::UNVERIFIED; 67 | } 68 | } 69 | 70 | // then add the (now unverified) key 71 | m_tokens.push(Token(Token::KEY, INPUT.mark())); 72 | key.pKey = &m_tokens.back(); 73 | key.pKey->status = Token::UNVERIFIED; 74 | 75 | m_simpleKeys.push(key); 76 | } 77 | 78 | // InvalidateSimpleKey 79 | // . Automatically invalidate the simple key in our flow level 80 | void Scanner::InvalidateSimpleKey() { 81 | if (m_simpleKeys.empty()) 82 | return; 83 | 84 | // grab top key 85 | SimpleKey& key = m_simpleKeys.top(); 86 | if (key.flowLevel != GetFlowLevel()) 87 | return; 88 | 89 | key.Invalidate(); 90 | m_simpleKeys.pop(); 91 | } 92 | 93 | // VerifySimpleKey 94 | // . Determines whether the latest simple key to be added is valid, 95 | // and if so, makes it valid. 96 | bool Scanner::VerifySimpleKey() { 97 | if (m_simpleKeys.empty()) 98 | return false; 99 | 100 | // grab top key 101 | SimpleKey key = m_simpleKeys.top(); 102 | 103 | // only validate if we're in the correct flow level 104 | if (key.flowLevel != GetFlowLevel()) 105 | return false; 106 | 107 | m_simpleKeys.pop(); 108 | 109 | bool isValid = true; 110 | 111 | // needs to be less than 1024 characters and inline 112 | if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) 113 | isValid = false; 114 | 115 | // invalidate key 116 | if (isValid) 117 | key.Validate(); 118 | else 119 | key.Invalidate(); 120 | 121 | return isValid; 122 | } 123 | 124 | void Scanner::PopAllSimpleKeys() { 125 | while (!m_simpleKeys.empty()) 126 | m_simpleKeys.pop(); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/singledocparser.h: -------------------------------------------------------------------------------- 1 | #ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "yaml-cpp/anchor.h" 15 | #include "yaml-cpp/noncopyable.h" 16 | 17 | namespace YAML { 18 | class CollectionStack; 19 | class EventHandler; 20 | class Node; 21 | class Scanner; 22 | struct Directives; 23 | struct Mark; 24 | struct Token; 25 | 26 | class SingleDocParser : private noncopyable { 27 | public: 28 | SingleDocParser(Scanner& scanner, const Directives& directives); 29 | ~SingleDocParser(); 30 | 31 | void HandleDocument(EventHandler& eventHandler); 32 | 33 | private: 34 | void HandleNode(EventHandler& eventHandler); 35 | 36 | void HandleSequence(EventHandler& eventHandler); 37 | void HandleBlockSequence(EventHandler& eventHandler); 38 | void HandleFlowSequence(EventHandler& eventHandler); 39 | 40 | void HandleMap(EventHandler& eventHandler); 41 | void HandleBlockMap(EventHandler& eventHandler); 42 | void HandleFlowMap(EventHandler& eventHandler); 43 | void HandleCompactMap(EventHandler& eventHandler); 44 | void HandleCompactMapWithNoKey(EventHandler& eventHandler); 45 | 46 | void ParseProperties(std::string& tag, anchor_t& anchor); 47 | void ParseTag(std::string& tag); 48 | void ParseAnchor(anchor_t& anchor); 49 | 50 | anchor_t RegisterAnchor(const std::string& name); 51 | anchor_t LookupAnchor(const Mark& mark, const std::string& name) const; 52 | 53 | private: 54 | Scanner& m_scanner; 55 | const Directives& m_directives; 56 | std::unique_ptr m_pCollectionStack; 57 | 58 | typedef std::map Anchors; 59 | Anchors m_anchors; 60 | 61 | anchor_t m_curAnchor; 62 | }; 63 | } 64 | 65 | #endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 66 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/stream.h: -------------------------------------------------------------------------------- 1 | #ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/noncopyable.h" 11 | #include "yaml-cpp/mark.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace YAML { 20 | class Stream : private noncopyable { 21 | public: 22 | friend class StreamCharSource; 23 | 24 | Stream(std::istream& input); 25 | ~Stream(); 26 | 27 | operator bool() const; 28 | bool operator!() const { return !static_cast(*this); } 29 | 30 | char peek() const; 31 | char get(); 32 | std::string get(int n); 33 | void eat(int n = 1); 34 | 35 | static char eof() { return 0x04; } 36 | 37 | const Mark mark() const { return m_mark; } 38 | int pos() const { return m_mark.pos; } 39 | int line() const { return m_mark.line; } 40 | int column() const { return m_mark.column; } 41 | void ResetColumn() { m_mark.column = 0; } 42 | 43 | private: 44 | enum CharacterSet { utf8, utf16le, utf16be, utf32le, utf32be }; 45 | 46 | std::istream& m_input; 47 | Mark m_mark; 48 | 49 | CharacterSet m_charSet; 50 | mutable std::deque m_readahead; 51 | unsigned char* const m_pPrefetched; 52 | mutable size_t m_nPrefetchedAvailable; 53 | mutable size_t m_nPrefetchedUsed; 54 | 55 | void AdvanceCurrent(); 56 | char CharAt(size_t i) const; 57 | bool ReadAheadTo(size_t i) const; 58 | bool _ReadAheadTo(size_t i) const; 59 | void StreamInUtf8() const; 60 | void StreamInUtf16() const; 61 | void StreamInUtf32() const; 62 | unsigned char GetNextByte() const; 63 | }; 64 | 65 | // CharAt 66 | // . Unchecked access 67 | inline char Stream::CharAt(size_t i) const { return m_readahead[i]; } 68 | 69 | inline bool Stream::ReadAheadTo(size_t i) const { 70 | if (m_readahead.size() > i) 71 | return true; 72 | return _ReadAheadTo(i); 73 | } 74 | } 75 | 76 | #endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 77 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/streamcharsource.h: -------------------------------------------------------------------------------- 1 | #ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/noncopyable.h" 11 | #include 12 | 13 | namespace YAML { 14 | class StreamCharSource { 15 | public: 16 | StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {} 17 | StreamCharSource(const StreamCharSource& source) 18 | : m_offset(source.m_offset), m_stream(source.m_stream) {} 19 | ~StreamCharSource() {} 20 | 21 | operator bool() const; 22 | char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); } 23 | bool operator!() const { return !static_cast(*this); } 24 | 25 | const StreamCharSource operator+(int i) const; 26 | 27 | private: 28 | std::size_t m_offset; 29 | const Stream& m_stream; 30 | 31 | StreamCharSource& operator=(const StreamCharSource&); // non-assignable 32 | }; 33 | 34 | inline StreamCharSource::operator bool() const { 35 | return m_stream.ReadAheadTo(m_offset); 36 | } 37 | 38 | inline const StreamCharSource StreamCharSource::operator+(int i) const { 39 | StreamCharSource source(*this); 40 | if (static_cast(source.m_offset) + i >= 0) 41 | source.m_offset += i; 42 | else 43 | source.m_offset = 0; 44 | return source; 45 | } 46 | } 47 | 48 | #endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 49 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/stringsource.h: -------------------------------------------------------------------------------- 1 | #ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | namespace YAML { 13 | class StringCharSource { 14 | public: 15 | StringCharSource(const char* str, std::size_t size) 16 | : m_str(str), m_size(size), m_offset(0) {} 17 | 18 | operator bool() const { return m_offset < m_size; } 19 | char operator[](std::size_t i) const { return m_str[m_offset + i]; } 20 | bool operator!() const { return !static_cast(*this); } 21 | 22 | const StringCharSource operator+(int i) const { 23 | StringCharSource source(*this); 24 | if (static_cast(source.m_offset) + i >= 0) 25 | source.m_offset += i; 26 | else 27 | source.m_offset = 0; 28 | return source; 29 | } 30 | 31 | StringCharSource& operator++() { 32 | ++m_offset; 33 | return *this; 34 | } 35 | 36 | StringCharSource& operator+=(std::size_t offset) { 37 | m_offset += offset; 38 | return *this; 39 | } 40 | 41 | private: 42 | const char* m_str; 43 | std::size_t m_size; 44 | std::size_t m_offset; 45 | }; 46 | } 47 | 48 | #endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 49 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/tag.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "directives.h" // IWYU pragma: keep 5 | #include "tag.h" 6 | #include "token.h" 7 | 8 | namespace YAML { 9 | Tag::Tag(const Token& token) : type(static_cast(token.data)) { 10 | switch (type) { 11 | case VERBATIM: 12 | value = token.value; 13 | break; 14 | case PRIMARY_HANDLE: 15 | value = token.value; 16 | break; 17 | case SECONDARY_HANDLE: 18 | value = token.value; 19 | break; 20 | case NAMED_HANDLE: 21 | handle = token.value; 22 | value = token.params[0]; 23 | break; 24 | case NON_SPECIFIC: 25 | break; 26 | default: 27 | assert(false); 28 | } 29 | } 30 | 31 | const std::string Tag::Translate(const Directives& directives) { 32 | switch (type) { 33 | case VERBATIM: 34 | return value; 35 | case PRIMARY_HANDLE: 36 | return directives.TranslateTagHandle("!") + value; 37 | case SECONDARY_HANDLE: 38 | return directives.TranslateTagHandle("!!") + value; 39 | case NAMED_HANDLE: 40 | return directives.TranslateTagHandle("!" + handle + "!") + value; 41 | case NON_SPECIFIC: 42 | // TODO: 43 | return "!"; 44 | default: 45 | assert(false); 46 | } 47 | throw std::runtime_error("yaml-cpp: internal error, bad tag type"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/tag.h: -------------------------------------------------------------------------------- 1 | #ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include 11 | 12 | namespace YAML { 13 | struct Directives; 14 | struct Token; 15 | 16 | struct Tag { 17 | enum TYPE { 18 | VERBATIM, 19 | PRIMARY_HANDLE, 20 | SECONDARY_HANDLE, 21 | NAMED_HANDLE, 22 | NON_SPECIFIC 23 | }; 24 | 25 | Tag(const Token& token); 26 | const std::string Translate(const Directives& directives); 27 | 28 | TYPE type; 29 | std::string handle, value; 30 | }; 31 | } 32 | 33 | #endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 34 | -------------------------------------------------------------------------------- /extra/yaml-cpp/src/token.h: -------------------------------------------------------------------------------- 1 | #ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 | #define TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 | 4 | #if defined(_MSC_VER) || \ 5 | (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 | (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 | #pragma once 8 | #endif 9 | 10 | #include "yaml-cpp/mark.h" 11 | #include 12 | #include 13 | #include 14 | 15 | namespace YAML { 16 | const std::string TokenNames[] = { 17 | "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START", "BLOCK_MAP_START", 18 | "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY", "FLOW_SEQ_START", 19 | "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END", "FLOW_MAP_COMPACT", 20 | "FLOW_ENTRY", "KEY", "VALUE", "ANCHOR", "ALIAS", "TAG", "SCALAR"}; 21 | 22 | struct Token { 23 | // enums 24 | enum STATUS { VALID, INVALID, UNVERIFIED }; 25 | enum TYPE { 26 | DIRECTIVE, 27 | DOC_START, 28 | DOC_END, 29 | BLOCK_SEQ_START, 30 | BLOCK_MAP_START, 31 | BLOCK_SEQ_END, 32 | BLOCK_MAP_END, 33 | BLOCK_ENTRY, 34 | FLOW_SEQ_START, 35 | FLOW_MAP_START, 36 | FLOW_SEQ_END, 37 | FLOW_MAP_END, 38 | FLOW_MAP_COMPACT, 39 | FLOW_ENTRY, 40 | KEY, 41 | VALUE, 42 | ANCHOR, 43 | ALIAS, 44 | TAG, 45 | PLAIN_SCALAR, 46 | NON_PLAIN_SCALAR 47 | }; 48 | 49 | // data 50 | Token(TYPE type_, const Mark& mark_) 51 | : status(VALID), type(type_), mark(mark_), data(0) {} 52 | 53 | friend std::ostream& operator<<(std::ostream& out, const Token& token) { 54 | out << TokenNames[token.type] << std::string(": ") << token.value; 55 | for (std::size_t i = 0; i < token.params.size(); i++) 56 | out << std::string(" ") << token.params[i]; 57 | return out; 58 | } 59 | 60 | STATUS status; 61 | TYPE type; 62 | Mark mark; 63 | std::string value; 64 | std::vector params; 65 | int data; 66 | }; 67 | } 68 | 69 | #endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 70 | -------------------------------------------------------------------------------- /imagefile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "imagefile.h" 4 | #include "utils.h" 5 | 6 | ImageFile::ImageFile() 7 | {} 8 | 9 | ImageFile::ImageFile(const QFileInfo &fileInfo) 10 | : m_fileInfo(fileInfo) 11 | , m_moved(false) 12 | { 13 | // extract "/data/car" from "/data/car.jpg" 14 | m_plateNameTemplate = m_fileInfo.canonicalPath() + QDir::separator() + m_fileInfo.completeBaseName(); 15 | m_plates = PlateFile::fromImageFile(m_plateNameTemplate); 16 | } 17 | 18 | void ImageFile::addPlate(const PlateFile &plateFile) 19 | { 20 | m_plates.append(plateFile); 21 | } 22 | 23 | void ImageFile::setPlates(const PlateFileList &newPlateFileList) 24 | { 25 | // determine plates to be removed and added 26 | PlateFileList platesToRemove = m_plates; 27 | 28 | foreach(const PlateFile &newPlateFile, newPlateFileList) 29 | { 30 | QMutableListIterator itOldPlates(platesToRemove); 31 | 32 | while(itOldPlates.hasNext()) 33 | { 34 | const PlateFile &oldPlateFile = itOldPlates.next(); 35 | 36 | if(oldPlateFile.plateFile() == newPlateFile.plateFile()) 37 | itOldPlates.remove(); 38 | } 39 | } 40 | 41 | foreach(const PlateFile &plateFile, platesToRemove) 42 | { 43 | // standalone YAML 44 | if(plateFile.plateFileTemplate().isEmpty()) 45 | { 46 | qDebug() << "Removing HEAP YAML" << plateFile.plateFile(); 47 | 48 | if(QFile::exists(plateFile.plateFile()) && !QFile::remove(plateFile.plateFile())) 49 | Utils::error(QObject::tr("Cannot remove YAML file %1").arg(plateFile.plateFile())); 50 | } 51 | } 52 | 53 | m_plates = newPlateFileList; 54 | 55 | int numberedIndex = 0; 56 | 57 | // sync to disk 58 | for(int i = 0;i < m_plates.size();i++) 59 | { 60 | QString error; 61 | PlateFile plateFile = m_plates.at(i); 62 | 63 | // new plates don't have an image file set 64 | if(plateFile.imageFile().isEmpty()) 65 | plateFile.setImageFile(m_fileInfo.fileName()); 66 | 67 | bool written = plateFile.plateFileTemplate().isEmpty() 68 | ? plateFile.writeToStandaloneFile(&error) 69 | : plateFile.writeToNumberedFile(numberedIndex++, &error); 70 | 71 | if(!written) 72 | { 73 | Utils::error(QObject::tr("Cannot save YAML file. %1") 74 | .arg(error.isEmpty() 75 | ? QObject::tr("Unknown error") 76 | : QObject::tr("Error: %1").arg(error))); 77 | } 78 | } 79 | 80 | int index = numberedIndex; 81 | 82 | while(true) 83 | { 84 | const QString &file = m_plateNameTemplate + QString("-%1.yaml").arg(index); 85 | 86 | if(!QFile::exists(file)) 87 | break; 88 | 89 | qDebug() << "Removing INDEXED YAML" << file; 90 | 91 | QFile::remove(file); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /imagefile.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGEFILE_H 2 | #define IMAGEFILE_H 3 | 4 | #include 5 | #include 6 | 7 | #include "platefile.h" 8 | 9 | /* 10 | * Represents a single image with associated YAML files 11 | * 12 | * If an image file is "car.jpg", associated YAML files will be named 13 | * 14 | * car-0.yaml 15 | * car-1.yaml 16 | * etc. 17 | */ 18 | class ImageFile 19 | { 20 | public: 21 | ImageFile(); 22 | ImageFile(const QFileInfo &fileInfo); 23 | 24 | /* 25 | * Image file info 26 | */ 27 | const QFileInfo &fileInfo() const; 28 | 29 | /* 30 | * Plate name template 31 | */ 32 | 33 | QString plateNameTemplate() const; 34 | 35 | /* 36 | * Associated plates 37 | */ 38 | PlateFileList plates() const; 39 | 40 | /* 41 | * Add new non-autonumbered plate 42 | */ 43 | void addPlate(const PlateFile &plateFile); 44 | 45 | /* 46 | * Update plates 47 | */ 48 | void setPlates(const PlateFileList &newPlateFileList); 49 | 50 | /* 51 | * Image has been moved and its methods and properties 52 | * should not be used anymore 53 | */ 54 | bool moved() const; 55 | void setMoved(bool moved); 56 | 57 | private: 58 | QFileInfo m_fileInfo; 59 | QString m_plateNameTemplate; 60 | PlateFileList m_plates; 61 | bool m_moved; 62 | }; 63 | 64 | inline 65 | const QFileInfo &ImageFile::fileInfo() const 66 | { 67 | return m_fileInfo; 68 | } 69 | 70 | inline 71 | QString ImageFile::plateNameTemplate() const 72 | { 73 | return m_plateNameTemplate; 74 | } 75 | 76 | inline 77 | PlateFileList ImageFile::plates() const 78 | { 79 | return m_plates; 80 | } 81 | 82 | inline 83 | bool ImageFile::moved() const 84 | { 85 | return m_moved; 86 | } 87 | 88 | inline 89 | void ImageFile::setMoved(bool moved) 90 | { 91 | m_moved = moved; 92 | } 93 | 94 | using ImageFileList = QList; 95 | 96 | #endif // IMAGEFILE_H 97 | -------------------------------------------------------------------------------- /images/plates.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openalpr/plate_tagger/9ffb4ee3e8ca365a006d0a9af37332da0c26f646/images/plates.icns -------------------------------------------------------------------------------- /images/plates.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openalpr/plate_tagger/9ffb4ee3e8ca365a006d0a9af37332da0c26f646/images/plates.ico -------------------------------------------------------------------------------- /imageview.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "threadedimageloader.h" 6 | #include "QProgressIndicator.h" 7 | #include "imagefile.h" 8 | #include "imageview.h" 9 | #include "utils.h" 10 | #include "ui_imageview.h" 11 | 12 | ImageView::ImageView(QWidget *parent) 13 | : QStackedWidget(parent) 14 | , ui(new Ui::ImageView) 15 | , m_imageFile(nullptr) 16 | , m_threadedImageLoader(new ThreadedImageLoader(this)) 17 | { 18 | ui->setupUi(this); 19 | 20 | // the image has been loaded 21 | connect(m_threadedImageLoader, SIGNAL(loaded(QImage)), this, SLOT(slotImageFileLoaded(QImage))); 22 | 23 | // proxying signals 24 | connect(ui->imageViewer, SIGNAL(zoomChanged(double)), this, SIGNAL(zoomChanged(double))); 25 | connect(ui->imageViewer, SIGNAL(platesChanged()), this, SIGNAL(platesChanged())); 26 | } 27 | 28 | ImageView::~ImageView() 29 | { 30 | delete ui; 31 | } 32 | 33 | void ImageView::setImageFile(ImageFile *imageFile) 34 | { 35 | qDebug("Loading image '%s'", qPrintable(imageFile->fileInfo().canonicalFilePath())); 36 | 37 | if(busy()) 38 | return; 39 | 40 | m_imageFile = imageFile; 41 | 42 | setCurrentIndex(0); 43 | ui->progress->startAnimation(); 44 | 45 | m_threadedImageLoader->loadImageFromFile(imageFile->fileInfo().canonicalFilePath()); 46 | } 47 | 48 | bool ImageView::busy() const 49 | { 50 | return m_threadedImageLoader->isRunning(); 51 | } 52 | 53 | void ImageView::reset() 54 | { 55 | if(busy()) 56 | return; 57 | 58 | setCurrentIndex(0); 59 | 60 | m_imageFile = nullptr; 61 | ui->imageViewer->reset(); 62 | } 63 | 64 | void ImageView::setImage(const QImage &image) 65 | { 66 | if(!m_imageFile) 67 | return; 68 | 69 | setCurrentIndex(1); 70 | ui->progress->stopAnimation(); 71 | 72 | ui->imageViewer->setImageFile(m_imageFile); 73 | ui->imageViewer->setImage(image); 74 | } 75 | 76 | void ImageView::slotImageFileLoaded(const QImage &image) 77 | { 78 | if(image.isNull()) 79 | { 80 | setCurrentIndex(1); 81 | Utils::error(tr("Cannot load the specified image. Possibly it's corrupted"), this); 82 | return; 83 | } 84 | 85 | setImage(image); 86 | } 87 | -------------------------------------------------------------------------------- /imageview.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGEVIEW_H 2 | #define IMAGEVIEW_H 3 | 4 | #include 5 | #include 6 | 7 | class QImage; 8 | 9 | class ImageFile; 10 | 11 | namespace Ui 12 | { 13 | class ImageView; 14 | } 15 | 16 | class ThreadedImageLoader; 17 | 18 | /* 19 | * Image viewer preserving aspect ratio and supporting scaling. 20 | * 21 | * Displays a spinning progress when loading a file. Utilizes ImageViewer class 22 | * to display an actual image 23 | */ 24 | class ImageView : public QStackedWidget 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | explicit ImageView(QWidget *parent = 0); 30 | ~ImageView(); 31 | 32 | /* 33 | * Load the specified image 34 | */ 35 | void setImageFile(ImageFile *imageFile); 36 | 37 | /* 38 | * Is loading the specified image 39 | */ 40 | bool busy() const; 41 | 42 | void reset(); 43 | 44 | private: 45 | void setImage(const QImage &image); 46 | 47 | signals: 48 | void zoomChanged(double); 49 | void platesChanged(); 50 | 51 | private slots: 52 | void slotImageFileLoaded(const QImage &image); 53 | 54 | private: 55 | Ui::ImageView *ui; 56 | ImageFile *m_imageFile; 57 | ThreadedImageLoader *m_threadedImageLoader; 58 | }; 59 | 60 | #endif // IMAGEVIEW_H 61 | -------------------------------------------------------------------------------- /imageview.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | ImageView 4 | 5 | 6 | 7 | 0 8 | 0 9 | 389 10 | 300 11 | 12 | 13 | 14 | QFrame::StyledPanel 15 | 16 | 17 | 0 18 | 19 | 20 | 21 | 22 | 23 | 24 | Qt::Vertical 25 | 26 | 27 | 28 | 20 29 | 120 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | Qt::Horizontal 38 | 39 | 40 | 41 | 165 42 | 20 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 24 52 | 24 53 | 54 | 55 | 56 | 57 | 24 58 | 24 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Qt::Horizontal 67 | 68 | 69 | 70 | 164 71 | 20 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Qt::Vertical 80 | 81 | 82 | 83 | 20 84 | 120 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | ImageViewerObserver 96 | QWidget 97 |

imageviewerobserver.h
98 | 1 99 | 100 | 101 | QProgressIndicator 102 | QWidget 103 |
QProgressIndicator.h
104 | 1 105 |
106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /imageviewerbase.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "imageviewerbase.h" 6 | 7 | ImageViewerBase::ImageViewerBase(QWidget *parent) 8 | : QWidget(parent) 9 | , m_zoom(1) 10 | { 11 | m_timerDelayedUpdate = new QTimer(this); 12 | m_timerDelayedUpdate->setSingleShot(true); 13 | m_timerDelayedUpdate->setInterval(10); 14 | connect(m_timerDelayedUpdate, SIGNAL(timeout()), this, SLOT(updatePixmap())); 15 | 16 | setMinimumSize(200, 120); 17 | } 18 | 19 | void ImageViewerBase::setImage(const QImage &image) 20 | { 21 | m_timerDelayedUpdate->stop(); 22 | m_image = image; 23 | 24 | updatePixmap(); 25 | } 26 | 27 | void ImageViewerBase::reset() 28 | { 29 | m_image = QImage(); 30 | m_pixmap = QPixmap(); 31 | m_pixmapBoundingRect = QRect(); 32 | m_zoom = 1; 33 | 34 | update(); 35 | } 36 | 37 | void ImageViewerBase::resizeEvent(QResizeEvent *event) 38 | { 39 | Q_UNUSED(event) 40 | 41 | if(!m_timerDelayedUpdate->isActive()) 42 | m_timerDelayedUpdate->start(); 43 | } 44 | 45 | void ImageViewerBase::paintEvent(QPaintEvent *event) 46 | { 47 | if(m_pixmap.isNull()) 48 | return; 49 | 50 | QPainter painter(this); 51 | 52 | painter.setClipRegion(event->region()); 53 | painter.setRenderHint(QPainter::Antialiasing); 54 | 55 | // car image 56 | painter.drawPixmap(m_pixmapBoundingRect.x(), m_pixmapBoundingRect.y(), m_pixmap); 57 | 58 | // custom paint in subclasses 59 | draw(&painter); 60 | } 61 | 62 | void ImageViewerBase::updatePixmap() 63 | { 64 | pixmapAboutToBeChanged(); 65 | 66 | m_pixmap = QPixmap(); 67 | 68 | if(m_image.isNull()) 69 | return; 70 | 71 | // scale with a higher quality 72 | m_pixmap = QPixmap::fromImage(m_image.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); 73 | 74 | // calculate scaling 75 | m_zoom = static_cast(m_pixmap.width()) / m_image.width(); 76 | 77 | // pixmap bounding rectangle 78 | m_pixmapBoundingRect = QRect((width() - m_pixmap.width()) / 2, 79 | (height() - m_pixmap.height()) / 2, 80 | m_pixmap.width(), 81 | m_pixmap.height()); 82 | 83 | pixmapChanged(); 84 | 85 | emit zoomChanged(m_zoom); 86 | 87 | update(); 88 | } 89 | -------------------------------------------------------------------------------- /imageviewerbase.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGEVIEWERBASE_H 2 | #define IMAGEVIEWERBASE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class QPainter; 10 | class QTimer; 11 | 12 | /* 13 | * Base image viewer widget with auto scaling 14 | */ 15 | class ImageViewerBase : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit ImageViewerBase(QWidget *parent = 0); 21 | virtual ~ImageViewerBase() = default; 22 | 23 | /* 24 | * Display an image in the view 25 | */ 26 | void setImage(const QImage &image); 27 | 28 | /* 29 | * Current zoom 30 | */ 31 | double zoom() const; 32 | 33 | /* 34 | * Clear and reset view to initial state with no actual image set 35 | */ 36 | virtual void reset(); 37 | 38 | protected: 39 | virtual void resizeEvent(QResizeEvent *event) override; 40 | virtual void paintEvent(QPaintEvent *event) override; 41 | 42 | /* 43 | * Getters for derived classes 44 | */ 45 | QPixmap pixmap() const; 46 | QImage image() const; 47 | QRect pixmapBoundingRect() const; 48 | 49 | /* 50 | * Pixmap will be scaled right now! 51 | */ 52 | virtual void pixmapAboutToBeChanged() = 0; 53 | 54 | /* 55 | * Pixmap has been scaled and all the internal data has been updated 56 | */ 57 | virtual void pixmapChanged() = 0; 58 | 59 | /* 60 | * Draw viewer-specific stuff 61 | */ 62 | virtual void draw(QPainter *painter) = 0; 63 | 64 | signals: 65 | void zoomChanged(double); 66 | 67 | private slots: 68 | void updatePixmap(); 69 | 70 | private: 71 | QTimer *m_timerDelayedUpdate; 72 | QImage m_image; 73 | QPixmap m_pixmap; 74 | double m_zoom; 75 | QRect m_pixmapBoundingRect; 76 | }; 77 | 78 | inline 79 | double ImageViewerBase::zoom() const 80 | { 81 | return m_zoom; 82 | } 83 | 84 | inline 85 | QPixmap ImageViewerBase::pixmap() const 86 | { 87 | return m_pixmap; 88 | } 89 | 90 | inline 91 | QImage ImageViewerBase::image() const 92 | { 93 | return m_image; 94 | } 95 | 96 | inline 97 | QRect ImageViewerBase::pixmapBoundingRect() const 98 | { 99 | return m_pixmapBoundingRect; 100 | } 101 | 102 | #endif // IMAGEVIEWERBASE_H 103 | -------------------------------------------------------------------------------- /imageviewerobserver.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGEVIEWEROBSERVER_H 2 | #define IMAGEVIEWEROBSERVER_H 3 | 4 | #include "imageviewerbase.h" 5 | #include "selection.h" 6 | #include "polygons.h" 7 | 8 | class ImageFile; 9 | 10 | /* 11 | * Image viewer to display a car with static license plates 12 | */ 13 | class ImageViewerObserver : public ImageViewerBase 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit ImageViewerObserver(QWidget *parent = nullptr); 19 | 20 | /* 21 | * Add information with static license plates 22 | */ 23 | void setImageFile(ImageFile *imageFile); 24 | 25 | /* 26 | * Reset override 27 | */ 28 | virtual void reset() override; 29 | 30 | protected: 31 | /* 32 | * For handling selection 33 | */ 34 | virtual void mousePressEvent(QMouseEvent *e) override; 35 | virtual void mouseMoveEvent(QMouseEvent *e) override; 36 | virtual void mouseReleaseEvent(QMouseEvent *e) override; 37 | 38 | /* 39 | * Custom tooltips 40 | */ 41 | virtual bool event(QEvent *event) override; 42 | 43 | virtual void pixmapAboutToBeChanged() override; 44 | virtual void pixmapChanged() override; 45 | 46 | virtual void draw(QPainter *painter) override; 47 | 48 | signals: 49 | void platesChanged(); 50 | 51 | private slots: 52 | void slotShowPlateSelector(); 53 | 54 | private: 55 | ImageFile *m_imageFile; 56 | Polygons m_polygons; 57 | Selection m_selection; 58 | QRect m_fixedSelection; 59 | int m_plateFileIndexForEditing; 60 | }; 61 | 62 | #endif // IMAGEVIEWEROBSERVER_H 63 | -------------------------------------------------------------------------------- /imageviewerplateselector.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGEVIEWERPLATESELECTOR_H 2 | #define IMAGEVIEWERPLATESELECTOR_H 3 | 4 | #include 5 | #include 6 | 7 | #include "imageviewerbase.h" 8 | 9 | class Dot; 10 | 11 | /* 12 | * Image viewer to display a car with static license plates 13 | */ 14 | class ImageViewerPlateSelector : public ImageViewerBase 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit ImageViewerPlateSelector(QWidget *parent = nullptr); 20 | 21 | /* 22 | * Check if the given dot geometry fits into the pixmap 23 | */ 24 | bool acceptableDotPosition(const QRect &rect) const; 25 | 26 | /* 27 | * Add a new dot at the given point 28 | */ 29 | bool addDotInViewCoordinates(const QPoint &point); 30 | bool addDotInImageCoordinates(const QPoint &point); 31 | 32 | /* 33 | * Remove all dots 34 | */ 35 | void clearDots(); 36 | 37 | /* 38 | * Selection result as a polygon with 4 points. Each point is 39 | * in image coordinates 40 | */ 41 | QPolygon selectedPolygon() const; 42 | 43 | protected: 44 | /* 45 | * For handling selection 46 | */ 47 | virtual void mousePressEvent(QMouseEvent *e) override; 48 | virtual void mouseMoveEvent(QMouseEvent *e) override; 49 | virtual void mouseReleaseEvent(QMouseEvent *e) override; 50 | 51 | virtual void pixmapAboutToBeChanged() override; 52 | virtual void pixmapChanged() override; 53 | 54 | virtual void draw(QPainter *painter) override; 55 | 56 | private: 57 | void updatePointInImage(Dot *dot) const; 58 | void emitDotsChanged(); 59 | bool reorderDots(); 60 | 61 | signals: 62 | void dotsChanged(int); 63 | 64 | private slots: 65 | void slotDotMoving(); 66 | void slotDotMoved(); 67 | 68 | private: 69 | // selection dots 70 | QList m_dots; 71 | }; 72 | 73 | #endif // IMAGEVIEWERPLATESELECTOR_H 74 | -------------------------------------------------------------------------------- /mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | 6 | #include "imagefile.h" 7 | 8 | class QImage; 9 | 10 | namespace Ui 11 | { 12 | class MainWindow; 13 | } 14 | 15 | class MainWindow : public QMainWindow 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit MainWindow(QWidget *parent = 0); 21 | ~MainWindow(); 22 | 23 | private: 24 | /* 25 | * Reset all labels 26 | */ 27 | void reset(); 28 | 29 | /* 30 | * Update labels based on the currently selected image 31 | */ 32 | void updateImageInformationFromIndex(); 33 | void updateImagePlatesInformationFromIndex(); 34 | 35 | /* 36 | * Update labels with a number of tagged images 37 | */ 38 | void updateTaggedAndPlatesInformation(); 39 | 40 | /* 41 | * Move the currently selected image file to negatives 42 | * if necessary 43 | */ 44 | void moveFileFromCurrentIndex(); 45 | 46 | private slots: 47 | // File menu 48 | void slotOpenDirectory(); 49 | void slotQuit(); 50 | 51 | // Edit menu 52 | void slotOptions(); 53 | 54 | // Help menu 55 | void slotUsage(); 56 | void slotAbout(); 57 | void slotAboutQt(); 58 | 59 | // other slots 60 | void slotPrevious(); 61 | void slotJumpTo(); 62 | void slotNext(); 63 | void slotZoomChanged(double zoom); 64 | void slotPlatesChanged(); 65 | 66 | private: 67 | Ui::MainWindow *ui; 68 | ImageFileList m_imageFiles; 69 | int m_currentIndex; 70 | bool m_firstRun; 71 | }; 72 | 73 | #endif // MAINWINDOW_H 74 | -------------------------------------------------------------------------------- /man/plates.1: -------------------------------------------------------------------------------- 1 | .TH PLATES 1 "MAY 17, 2017" 2 | .\" Please adjust this date whenever revising the manpage. 3 | .SH NAME 4 | plates \- an OpenALPR training utility to manually find and mark license plates on photos. 5 | .SH SYNOPSIS 6 | .B plates [--plates ] 7 | .br 8 | .SH DESCRIPTION 9 | OpenALPR is an open source Automatic License Plate Recognition library written 10 | in C++ with bindings in C#, Java, Node.js, Go, and Python. The library analyzes 11 | images and video streams to identify license plates. The output is the text 12 | representation of any license plate characters. 13 | 14 | The purpose of this applications is to train OpenALPR to find license plates. 15 | 16 | See https://github.com/openalpr/openalpr for more. 17 | .SH AUTHOR 18 | plates was written by Dmitry Baryshev. 19 | .PP 20 | This manual page was written by Dmitry Baryshev , 21 | for the Debian project (but may be used by others). 22 | -------------------------------------------------------------------------------- /options.cpp: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | #include "options.h" 3 | #include "ui_options.h" 4 | 5 | Options::Options(QWidget *parent) 6 | : QDialog(parent) 7 | , ui(new Ui::Options) 8 | { 9 | ui->setupUi(this); 10 | 11 | // load settings 12 | ui->checkSkipTagged->setChecked(SETTINGS_GET_BOOL(SETTING_SKIP_TAGGED)); 13 | ui->checkMove->setChecked(SETTINGS_GET_BOOL(SETTING_MOVE_UNTAGGED)); 14 | ui->checkTooltips->setChecked(SETTINGS_GET_BOOL(SETTING_TOOLTIPS)); 15 | } 16 | 17 | Options::~Options() 18 | { 19 | delete ui; 20 | } 21 | 22 | void Options::slotAccept() 23 | { 24 | SETTINGS_SET_BOOL(SETTING_SKIP_TAGGED, ui->checkSkipTagged->isChecked(), Settings::NoSync); 25 | SETTINGS_SET_BOOL(SETTING_MOVE_UNTAGGED, ui->checkMove->isChecked(), Settings::NoSync); 26 | SETTINGS_SET_BOOL(SETTING_TOOLTIPS, ui->checkTooltips->isChecked()); 27 | 28 | accept(); 29 | } 30 | -------------------------------------------------------------------------------- /options.h: -------------------------------------------------------------------------------- 1 | #ifndef OPTIONS_H 2 | #define OPTIONS_H 3 | 4 | #include 5 | 6 | namespace Ui 7 | { 8 | class Options; 9 | } 10 | 11 | class Options : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit Options(QWidget *parent = 0); 17 | ~Options(); 18 | 19 | private slots: 20 | void slotAccept(); 21 | 22 | private: 23 | Ui::Options *ui; 24 | }; 25 | 26 | #endif // OPTIONS_H 27 | -------------------------------------------------------------------------------- /options.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options 4 | 5 | 6 | 7 | 0 8 | 0 9 | 316 10 | 116 11 | 12 | 13 | 14 | Preferences 15 | 16 | 17 | 18 | 19 | 20 | Qt::Vertical 21 | 22 | 23 | 24 | 20 25 | 4 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Skip tagged images 34 | 35 | 36 | 37 | 38 | 39 | 40 | Move images without plates into "negatives" subdirectory 41 | 42 | 43 | 44 | 45 | 46 | 47 | Qt::Horizontal 48 | 49 | 50 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 51 | 52 | 53 | 54 | 55 | 56 | 57 | Show tooltips with a license plate information 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | buttonBox 67 | accepted() 68 | Options 69 | slotAccept() 70 | 71 | 72 | 248 73 | 254 74 | 75 | 76 | 157 77 | 274 78 | 79 | 80 | 81 | 82 | buttonBox 83 | rejected() 84 | Options 85 | reject() 86 | 87 | 88 | 316 89 | 260 90 | 91 | 92 | 286 93 | 274 94 | 95 | 96 | 97 | 98 | 99 | slotAccept() 100 | 101 | 102 | -------------------------------------------------------------------------------- /platefile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "platefile.h" 6 | 7 | PlateFile::PlateFile(const QString &platePath) 8 | : m_plateFile(platePath) 9 | , m_parsed(false) 10 | { 11 | if(!exists()) 12 | return; 13 | 14 | try 15 | { 16 | m_yaml = YAML::LoadFile(QDir::toNativeSeparators(m_plateFile).toStdString()); 17 | } 18 | catch(...) 19 | { 20 | qWarning("Error parsing file '%s'", qPrintable(m_plateFile)); 21 | return; 22 | } 23 | 24 | if(!m_yaml["plate_corners_gt"]) 25 | return; 26 | 27 | // cache polygon (8 x,y numbers) 28 | int x, y; 29 | QPolygon polygon; 30 | 31 | QString corners = QString::fromStdString(m_yaml["plate_corners_gt"].as()); 32 | QTextStream ts(&corners, QIODevice::ReadOnly); 33 | 34 | while(true) 35 | { 36 | ts.skipWhiteSpace(); 37 | 38 | if(ts.atEnd()) 39 | break; 40 | 41 | ts >> x >> y; 42 | polygon.append(QPoint(x, y)); 43 | } 44 | 45 | if(polygon.size() == 4) 46 | { 47 | m_plateCorners = polygon; 48 | m_parsed = true; 49 | } 50 | else 51 | qWarning("Polygon in file '%s' has only %d point(s) thus it's invalid", qPrintable(m_plateFile), polygon.size()); 52 | } 53 | 54 | PlateFile::PlateFile(const QString &platePathTemplate, int index) 55 | : PlateFile(platePathTemplate + QString("-%1.yaml").arg(index)) 56 | { 57 | m_plateFileTemplate = platePathTemplate; 58 | } 59 | 60 | bool PlateFile::writeToNumberedFile(int index, QString *error) 61 | { 62 | const QString &yamlPath = m_plateFileTemplate + QString("-%1.yaml").arg(index); 63 | qDebug("Writing INDEXED YAML %d '%s'", index, qPrintable(yamlPath)); 64 | return writeToFile(yamlPath, error); 65 | } 66 | 67 | bool PlateFile::writeToStandaloneFile(QString *error) 68 | { 69 | qDebug("Writing HEAP YAML '%s'", qPrintable(plateFile())); 70 | return writeToFile(m_plateFile, error); 71 | } 72 | 73 | bool PlateFile::exists() 74 | { 75 | return QFileInfo(m_plateFile).exists(); 76 | } 77 | 78 | void PlateFile::setPlateCorners(const QPolygon &plateCorners) 79 | { 80 | m_plateCorners = plateCorners; 81 | 82 | QStringList cornersStringList; 83 | cornersStringList.reserve(m_plateCorners.size() * 2); 84 | 85 | foreach(const QPoint &point, m_plateCorners) 86 | { 87 | cornersStringList.append(QString::number(point.x())); 88 | cornersStringList.append(QString::number(point.y())); 89 | } 90 | 91 | m_yaml["plate_corners_gt"] = cornersStringList.join(" ").toStdString(); 92 | } 93 | 94 | // static 95 | PlateFileList PlateFile::fromImageFile(const QString &fileTemplate) 96 | { 97 | PlateFileList plateList; 98 | 99 | int index = 0; 100 | 101 | // find associated car-nnn.yaml files 102 | while(true) 103 | { 104 | PlateFile plateFile(fileTemplate, index++); 105 | 106 | if(!plateFile.exists()) 107 | break; 108 | 109 | if(plateFile.isValid()) 110 | plateList.append(plateFile); 111 | } 112 | 113 | return plateList; 114 | } 115 | 116 | bool PlateFile::writeToFile(const QString &yamlPath, QString *error) 117 | { 118 | const std::string &yamlFilePath = yamlPath.toStdString(); 119 | 120 | try 121 | { 122 | std::ofstream fout(yamlFilePath); 123 | fout << m_yaml; 124 | } 125 | catch(...) 126 | { 127 | if(error) 128 | *error = QObject::tr("Cannot write into a file"); 129 | 130 | return false; 131 | } 132 | 133 | return true; 134 | } 135 | -------------------------------------------------------------------------------- /platefile.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATEFILE_H 2 | #define PLATEFILE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "plates-yaml.h" 9 | 10 | class QTextStream; 11 | class QFileInfo; 12 | 13 | class PlateFile; 14 | using PlateFileList = QList; 15 | 16 | class PlateFile 17 | { 18 | public: 19 | PlateFile(const QString &platePath); 20 | PlateFile(const QString &platePathTemplate, int index); 21 | 22 | /* 23 | * Overwrite a plate file with index 'index' 24 | */ 25 | bool writeToNumberedFile(int index, QString *error = nullptr); 26 | 27 | /* 28 | * Overwrite a standalone plate file 29 | */ 30 | bool writeToStandaloneFile(QString *error = nullptr); 31 | 32 | /* 33 | * Full path to the plate file 34 | */ 35 | QString plateFile() const; 36 | 37 | /* 38 | * Plate file template like "/data/car" from "/data/car.jpg". Empty 39 | * if the plate is loaded from the non-related YAML file (car.yaml for truck.jpg) 40 | */ 41 | QString plateFileTemplate() const; 42 | 43 | /* 44 | * Check is the corresponding plate file exists 45 | */ 46 | bool exists(); 47 | 48 | /* 49 | * PlateFile is valid when it has 50 | * - an image path set 51 | * - valid image dimensions 52 | * - valid plate corners 53 | */ 54 | bool isValid() const; 55 | 56 | /* 57 | * Some getters/setters 58 | */ 59 | QString imageFile() const; 60 | void setImageFile(const QString &imageFile); 61 | 62 | void setImageWidth(int imageWidth); 63 | void setImageHeight(int imageHeight); 64 | 65 | QString regionCode() const; 66 | void setRegionCode(const QString ®ionCode); 67 | 68 | QString plateNumber() const; 69 | void setPlateNumber(const QString &plateNumber); 70 | 71 | QPolygon plateCorners() const; 72 | void setPlateCorners(const QPolygon &plateCorners); 73 | 74 | bool plateInverted() const; 75 | void setPlateInverted(bool plateInverted); 76 | 77 | /* 78 | * Get a list of associated plates for the specified image file 79 | * 80 | * If an image file is "car.jpg", it will look for 81 | * 82 | * car-0.yaml 83 | * car-1.yaml 84 | * etc. 85 | */ 86 | static PlateFileList fromImageFile(const QString &fileTemplate); 87 | 88 | private: 89 | bool writeToFile(const QString &yamlPath, QString *error); 90 | 91 | private: 92 | QString m_plateFileTemplate; 93 | 94 | // YAML properies. We store polygon separately as it needs parsing 95 | YAML::Node m_yaml; 96 | QPolygon m_plateCorners; 97 | QString m_plateFile; 98 | bool m_parsed; 99 | }; 100 | 101 | inline 102 | QString PlateFile::plateFile() const 103 | { 104 | return m_plateFile; 105 | } 106 | 107 | inline 108 | QString PlateFile::plateFileTemplate() const 109 | { 110 | return m_plateFileTemplate; 111 | } 112 | 113 | inline 114 | bool PlateFile::isValid() const 115 | { 116 | return m_parsed 117 | && m_yaml["image_width"] 118 | && m_yaml["image_width"].as() > 0 119 | && m_yaml["image_height"] 120 | && m_yaml["image_height"].as() > 0; 121 | } 122 | 123 | inline 124 | QString PlateFile::imageFile() const 125 | { 126 | return m_yaml["image_file"] 127 | ? QString::fromUtf8(m_yaml["image_file"].as().c_str()) 128 | : QString(); 129 | } 130 | 131 | inline 132 | void PlateFile::setImageFile(const QString &imageFile) 133 | { 134 | m_yaml["image_file"] = imageFile.toStdString(); 135 | } 136 | 137 | inline 138 | void PlateFile::setImageWidth(int imageWidth) 139 | { 140 | m_yaml["image_width"] = imageWidth; 141 | } 142 | 143 | inline 144 | void PlateFile::setImageHeight(int imageHeight) 145 | { 146 | m_yaml["image_height"] = imageHeight; 147 | } 148 | 149 | inline 150 | QString PlateFile::regionCode() const 151 | { 152 | return m_yaml["region_code_gt"] 153 | ? QString::fromUtf8(m_yaml["region_code_gt"].as().c_str()) 154 | : QString(); 155 | } 156 | 157 | inline 158 | void PlateFile::setRegionCode(const QString ®ionCode) 159 | { 160 | if(regionCode.isEmpty()) 161 | { 162 | if(m_yaml["region_code_gt"]) 163 | m_yaml.remove("region_code_gt"); 164 | } 165 | else 166 | m_yaml["region_code_gt"] = regionCode.toStdString(); 167 | } 168 | 169 | inline 170 | QString PlateFile::plateNumber() const 171 | { 172 | return m_yaml["plate_number_gt"] 173 | ? QString::fromUtf8(m_yaml["plate_number_gt"].as().c_str()) 174 | : QString(); 175 | } 176 | 177 | inline 178 | void PlateFile::setPlateNumber(const QString &plateNumber) 179 | { 180 | m_yaml["plate_number_gt"] = plateNumber.toStdString(); 181 | } 182 | 183 | inline 184 | QPolygon PlateFile::plateCorners() const 185 | { 186 | return m_plateCorners; 187 | } 188 | 189 | inline 190 | bool PlateFile::plateInverted() const 191 | { 192 | return m_yaml["plate_inverted_gt"] 193 | ? m_yaml["plate_inverted_gt"].as() 194 | : false; 195 | } 196 | 197 | inline 198 | void PlateFile::setPlateInverted(bool plateInverted) 199 | { 200 | m_yaml["plate_inverted_gt"] = plateInverted; 201 | } 202 | 203 | #endif // PLATEFILE_H 204 | -------------------------------------------------------------------------------- /plates-yaml.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATESYAML_H 2 | #define PLATESYAML_H 3 | 4 | #include "yaml-cpp/yaml.h" 5 | 6 | #endif // PLATESYAML_H 7 | -------------------------------------------------------------------------------- /plates.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Type=Application 4 | Categories=Qt;Education; 5 | Exec=plates 6 | Icon=plates 7 | Terminal=false 8 | Name=OpenALPR training utility 9 | Comment=OpenALPR training utility 10 | -------------------------------------------------------------------------------- /plates.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/plates.ico 4 | 5 | 6 | -------------------------------------------------------------------------------- /plates.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define stringify(v1) #v1 6 | #define quote(v1) stringify(v1) 7 | 8 | #define NVERSION VERSION_MAJOR.VERSION_MINOR.VERSION_PATCH 9 | 10 | STRINGTABLE LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 11 | BEGIN 12 | 1 quote(TARGET_UPPER)quote(TARGET)"\0" 13 | END 14 | 15 | IDI_ICON1 ICON DISCARDABLE "images/plates.ico" 16 | 17 | 1 VERSIONINFO 18 | FILEVERSION VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, 0 19 | PRODUCTVERSION VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, 0 20 | FILEOS VOS_UNKNOWN 21 | FILETYPE VFT_APP 22 | BEGIN 23 | BLOCK "StringFileInfo" 24 | BEGIN 25 | BLOCK "040904e4" 26 | BEGIN 27 | VALUE "Comments", quote(TARGET) "" 28 | VALUE "CompanyName", "OpenALPR" 29 | VALUE "FileDescription", quote(TARGET) 30 | VALUE "FileVersion", quote(NVERSION) 31 | VALUE "InternalName", quote(TARGET) 32 | VALUE "LegalCopyright", "(C) 2017 OpenALPR" 33 | VALUE "ProductName", quote(TARGET) 34 | VALUE "ProductVersion", quote(NVERSION) 35 | VALUE "Builder", "OpenALPR" 36 | END 37 | END 38 | BLOCK "VarFileInfo" 39 | BEGIN 40 | VALUE "Translation", 0x409, 1200 41 | END 42 | END 43 | -------------------------------------------------------------------------------- /plateselector.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATESELECTOR_H 2 | #define PLATESELECTOR_H 3 | 4 | #include 5 | #include 6 | 7 | class QAbstractButton; 8 | class QShortcut; 9 | 10 | class PlateFile; 11 | 12 | namespace Ui 13 | { 14 | class PlateSelector; 15 | } 16 | 17 | /* 18 | * Dialog to select or edit a license plate with four points 19 | */ 20 | class PlateSelector : public QDialog 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | enum DeleteButtonExistense { WithDeleteButton, WithoutDeleteButton }; 26 | 27 | explicit PlateSelector(const QImage &image, DeleteButtonExistense deleteButtonExistense, QWidget *parent = 0); 28 | ~PlateSelector(); 29 | 30 | /* 31 | * Set an existing plate to edit 32 | */ 33 | void setPlateFile(const PlateFile &plateFile); 34 | 35 | /* 36 | * Selection rectangle in the original (full) image. This rectangle is used to re-calculate 37 | * correct relative dot coordinates and pass them into addDotInImageCoordinates() method 38 | */ 39 | void setSelectionRect(const QRect &rect); 40 | 41 | /* 42 | * Getters 43 | */ 44 | QString plateNumber() const; 45 | QString plateRegion() const; 46 | bool lightOnDark() const; 47 | 48 | QPolygon selectedPolygon() const; 49 | 50 | private slots: 51 | void slotCheckData(); 52 | void slotSave(); 53 | void slotHelp(); 54 | void slotClicked(QAbstractButton *button); 55 | 56 | private: 57 | Ui::PlateSelector *ui; 58 | QRect m_selection; 59 | QPolygon m_selectedPolygon; 60 | QShortcut *m_shortCutPlateNumber; 61 | QShortcut *m_shortCutPlateRegion; 62 | QShortcut *m_shortCutLightOnDark; 63 | }; 64 | 65 | inline 66 | void PlateSelector::setSelectionRect(const QRect &rect) 67 | { 68 | m_selection = rect; 69 | } 70 | 71 | inline 72 | QPolygon PlateSelector::selectedPolygon() const 73 | { 74 | return m_selectedPolygon; 75 | } 76 | 77 | #endif // PLATESELECTOR_H 78 | -------------------------------------------------------------------------------- /polygons.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "polygons.h" 4 | #include "utils.h" 5 | 6 | Polygons::Polygons() 7 | {} 8 | 9 | void Polygons::setZoom(double zoom) 10 | { 11 | m_scaledPolygons.clear(); 12 | m_scaledPolygons.reserve(m_polygons.size()); 13 | 14 | foreach(QPolygon polygon, m_polygons) 15 | { 16 | for(int i = 0;i < polygon.size();i++) 17 | { 18 | polygon.setPoint(i, polygon.point(i) * zoom); 19 | } 20 | 21 | m_scaledPolygons.append(polygon); 22 | } 23 | } 24 | 25 | void Polygons::draw(QPainter *painter) 26 | { 27 | if(!painter) 28 | return; 29 | 30 | painter->setPen(Utils::polygonPaintingPen()); 31 | 32 | foreach(const QPolygon &polygon, m_scaledPolygons) 33 | { 34 | painter->drawPolygon(polygon); 35 | } 36 | } 37 | 38 | Polygons Polygons::fromPlates(const PlateFileList &plateFileList) 39 | { 40 | Polygons polygons; 41 | 42 | foreach(const PlateFile &plateFile, plateFileList) 43 | { 44 | polygons.append(plateFile.plateCorners()); 45 | } 46 | 47 | return polygons; 48 | } 49 | -------------------------------------------------------------------------------- /polygons.h: -------------------------------------------------------------------------------- 1 | #ifndef POLYGONS_H 2 | #define POLYGONS_H 3 | 4 | #include 5 | #include 6 | 7 | #include "platefile.h" 8 | 9 | class QPainter; 10 | 11 | /* 12 | * Class to hold static license plates polygons and draw them 13 | */ 14 | class Polygons 15 | { 16 | public: 17 | Polygons(); 18 | 19 | /* 20 | * QList proxy methods 21 | */ 22 | void append(const QPolygon &polygon); 23 | void clear(); 24 | 25 | /* 26 | * Scale the currently saved polygons 27 | */ 28 | void setZoom(double zoom); 29 | 30 | /* 31 | * Draw currently saved polygons with the given painter 32 | */ 33 | void draw(QPainter *painter); 34 | 35 | /* 36 | * Constructs a 'Polygons' object from saved license plates 37 | */ 38 | static Polygons fromPlates(const PlateFileList &plateFileList); 39 | 40 | private: 41 | QList m_polygons; 42 | QList m_scaledPolygons; 43 | }; 44 | 45 | inline 46 | void Polygons::append(const QPolygon &polygon) 47 | { 48 | m_polygons.append(polygon); 49 | } 50 | 51 | inline 52 | void Polygons::clear() 53 | { 54 | m_polygons.clear(); 55 | } 56 | 57 | #endif // POLYGONS_H 58 | -------------------------------------------------------------------------------- /qprogressindicator/QProgressIndicator.cpp: -------------------------------------------------------------------------------- 1 | #include "QProgressIndicator.h" 2 | 3 | #include 4 | 5 | QProgressIndicator::QProgressIndicator(QWidget* parent) 6 | : QWidget(parent), 7 | m_angle(0), 8 | m_timerId(-1), 9 | m_delay(40), 10 | m_displayedWhenStopped(false), 11 | m_color(Qt::black) 12 | { 13 | setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 14 | setFocusPolicy(Qt::NoFocus); 15 | } 16 | 17 | bool QProgressIndicator::isAnimated () const 18 | { 19 | return (m_timerId != -1); 20 | } 21 | 22 | void QProgressIndicator::setDisplayedWhenStopped(bool state) 23 | { 24 | m_displayedWhenStopped = state; 25 | 26 | update(); 27 | } 28 | 29 | bool QProgressIndicator::isDisplayedWhenStopped() const 30 | { 31 | return m_displayedWhenStopped; 32 | } 33 | 34 | void QProgressIndicator::startAnimation() 35 | { 36 | m_angle = 0; 37 | 38 | if (m_timerId == -1) 39 | m_timerId = startTimer(m_delay); 40 | } 41 | 42 | void QProgressIndicator::stopAnimation() 43 | { 44 | if (m_timerId != -1) 45 | killTimer(m_timerId); 46 | 47 | m_timerId = -1; 48 | 49 | update(); 50 | } 51 | 52 | void QProgressIndicator::setAnimationDelay(int delay) 53 | { 54 | if (m_timerId != -1) 55 | killTimer(m_timerId); 56 | 57 | m_delay = delay; 58 | 59 | if (m_timerId != -1) 60 | m_timerId = startTimer(m_delay); 61 | } 62 | 63 | void QProgressIndicator::setColor(const QColor & color) 64 | { 65 | m_color = color; 66 | 67 | update(); 68 | } 69 | 70 | QSize QProgressIndicator::sizeHint() const 71 | { 72 | return QSize(20,20); 73 | } 74 | 75 | int QProgressIndicator::heightForWidth(int w) const 76 | { 77 | return w; 78 | } 79 | 80 | void QProgressIndicator::timerEvent(QTimerEvent * /*event*/) 81 | { 82 | m_angle = (m_angle+30)%360; 83 | 84 | update(); 85 | } 86 | 87 | void QProgressIndicator::paintEvent(QPaintEvent * /*event*/) 88 | { 89 | if (!m_displayedWhenStopped && !isAnimated()) 90 | return; 91 | 92 | int width = qMin(this->width(), this->height()); 93 | 94 | QPainter p(this); 95 | p.setRenderHint(QPainter::Antialiasing); 96 | 97 | int outerRadius = (width-1)*0.5; 98 | int innerRadius = (width-1)*0.5*0.38; 99 | 100 | int capsuleHeight = outerRadius - innerRadius; 101 | int capsuleWidth = (width > 32 ) ? capsuleHeight *.23 : capsuleHeight *.35; 102 | int capsuleRadius = capsuleWidth/2; 103 | 104 | /* CO-> */ 105 | if (isAnimated()) 106 | { 107 | for (int i = 0; i < 12; ++i) 108 | { 109 | QColor color = m_color; 110 | color.setAlphaF(1.0f - (i/12.0f)); 111 | p.setPen(Qt::NoPen); 112 | p.setBrush(color); 113 | p.save(); 114 | p.translate(rect().center()); 115 | p.rotate(m_angle - i * 30.0f); 116 | p.drawRoundedRect(-capsuleWidth * 0.5, -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius); 117 | p.restore(); 118 | } 119 | } 120 | else 121 | for (int i = 0; i < 12; ++i) 122 | { 123 | QColor color = m_color; 124 | color.setAlphaF(0.2F); 125 | p.setPen(Qt::NoPen); 126 | p.setBrush(color); 127 | p.save(); 128 | p.translate(rect().center()); 129 | p.rotate(m_angle - i * 30.0f); 130 | p.drawRoundedRect(-capsuleWidth * 0.5, -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius); 131 | p.restore(); 132 | } 133 | /* <-CO */ 134 | } 135 | -------------------------------------------------------------------------------- /qprogressindicator/QProgressIndicator.h: -------------------------------------------------------------------------------- 1 | #ifndef QPROGRESSINDICATOR_H 2 | #define QPROGRESSINDICATOR_H 3 | 4 | #include 5 | #include 6 | 7 | /*! 8 | \class QProgressIndicator 9 | \brief The QProgressIndicator class lets an application display a progress indicator to show that a lengthy task is under way. 10 | 11 | Progress indicators are indeterminate and do nothing more than spin to show that the application is busy. 12 | \sa QProgressBar 13 | */ 14 | class QProgressIndicator : public QWidget 15 | { 16 | Q_OBJECT 17 | Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay) 18 | Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped) 19 | Q_PROPERTY(QColor color READ color WRITE setColor) 20 | public: 21 | QProgressIndicator(QWidget* parent = 0); 22 | 23 | /*! Returns the delay between animation steps. 24 | \return The number of milliseconds between animation steps. By default, the animation delay is set to 40 milliseconds. 25 | \sa setAnimationDelay 26 | */ 27 | int animationDelay() const { return m_delay; } 28 | 29 | /*! Returns a Boolean value indicating whether the component is currently animated. 30 | \return Animation state. 31 | \sa startAnimation stopAnimation 32 | */ 33 | bool isAnimated () const; 34 | 35 | /*! Returns a Boolean value indicating whether the receiver shows itself even when it is not animating. 36 | \return Return true if the progress indicator shows itself even when it is not animating. By default, it returns false. 37 | \sa setDisplayedWhenStopped 38 | */ 39 | bool isDisplayedWhenStopped() const; 40 | 41 | /*! Returns the color of the component. 42 | \sa setColor 43 | */ 44 | const QColor & color() const { return m_color; } 45 | 46 | virtual QSize sizeHint() const; 47 | int heightForWidth(int w) const; 48 | public slots: 49 | /*! Starts the spin animation. 50 | \sa stopAnimation isAnimated 51 | */ 52 | void startAnimation(); 53 | 54 | /*! Stops the spin animation. 55 | \sa startAnimation isAnimated 56 | */ 57 | void stopAnimation(); 58 | 59 | /*! Sets the delay between animation steps. 60 | Setting the \a delay to a value larger than 40 slows the animation, while setting the \a delay to a smaller value speeds it up. 61 | \param delay The delay, in milliseconds. 62 | \sa animationDelay 63 | */ 64 | void setAnimationDelay(int delay); 65 | 66 | /*! Sets whether the component hides itself when it is not animating. 67 | \param state The animation state. Set false to hide the progress indicator when it is not animating; otherwise true. 68 | \sa isDisplayedWhenStopped 69 | */ 70 | void setDisplayedWhenStopped(bool state); 71 | 72 | /*! Sets the color of the components to the given color. 73 | \sa color 74 | */ 75 | void setColor(const QColor & color); 76 | 77 | protected: 78 | virtual void timerEvent(QTimerEvent * event); 79 | virtual void paintEvent(QPaintEvent * event); 80 | private: 81 | int m_angle; 82 | int m_timerId; 83 | int m_delay; 84 | bool m_displayedWhenStopped; 85 | QColor m_color; 86 | }; 87 | 88 | #endif // QPROGRESSINDICATOR_H 89 | -------------------------------------------------------------------------------- /selection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "selection.h" 5 | #include "utils.h" 6 | 7 | constexpr int SELECTION_MIN_WIDTH = 6; 8 | constexpr int SELECTION_MIN_HEIGHT = 6; 9 | 10 | Selection::Selection() 11 | : m_hasSelection(false) 12 | {} 13 | 14 | bool Selection::selectionIsFine() const 15 | { 16 | const QRect &selection = m_selection.normalized(); 17 | return m_hasSelection && selection.width() > SELECTION_MIN_WIDTH && selection.height() > SELECTION_MIN_HEIGHT; 18 | } 19 | 20 | void Selection::reset() 21 | { 22 | m_hasSelection = false; 23 | m_selection = QRect(); 24 | } 25 | 26 | void Selection::start(const QPoint &pos) 27 | { 28 | if(!m_referenceRect.contains(pos)) 29 | return; 30 | 31 | m_hasSelection = true; 32 | m_selection = QRect(pos, pos); 33 | 34 | qDebug() << "Starting selection" << m_selection; 35 | } 36 | 37 | void Selection::move(const QPoint &pos) 38 | { 39 | m_selection.setBottomRight(Utils::fitPoint(m_referenceRect, pos)); 40 | } 41 | 42 | void Selection::draw(QPainter *painter) 43 | { 44 | if(!painter) 45 | return; 46 | 47 | // selection must be normalized and checked against a minimal size 48 | const QRect &selection = m_selection.normalized(); 49 | 50 | if(selectionIsFine()) 51 | { 52 | painter->setCompositionMode(QPainter::RasterOp_SourceXorDestination); 53 | painter->setPen(Qt::white); 54 | painter->drawRect(selection); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /selection.h: -------------------------------------------------------------------------------- 1 | #ifndef SELECTION_H 2 | #define SELECTION_H 3 | 4 | #include 5 | 6 | class QPainter; 7 | 8 | /* 9 | * Rectangular selection painter 10 | */ 11 | class Selection 12 | { 13 | public: 14 | Selection(); 15 | 16 | /* 17 | * Actual selection rectangle 18 | */ 19 | QRect selection() const; 20 | 21 | /* 22 | * In selection mode 23 | */ 24 | bool hasSelection() const; 25 | 26 | /* 27 | * Has selection and it's enought large 28 | */ 29 | bool selectionIsFine() const; 30 | 31 | /* 32 | * Reset to inital state 33 | */ 34 | void reset(); 35 | 36 | /* 37 | * Relative rectangle 38 | */ 39 | void setReferenceRect(const QRect &rect); 40 | 41 | /* 42 | * Start painting a selection rectangle from the given position 43 | */ 44 | void start(const QPoint &pos); 45 | 46 | /* 47 | * Move the selection rectangle 48 | */ 49 | void move(const QPoint &pos); 50 | 51 | /* 52 | * Stop painting selection 53 | */ 54 | void stop(); 55 | 56 | /* 57 | * Paint selection using the specified painter 58 | */ 59 | void draw(QPainter *painter); 60 | 61 | private: 62 | QRect m_referenceRect; 63 | QRect m_selection; 64 | bool m_hasSelection; 65 | }; 66 | 67 | inline 68 | QRect Selection::selection() const 69 | { 70 | return m_selection; 71 | } 72 | 73 | inline 74 | bool Selection::hasSelection() const 75 | { 76 | return m_hasSelection; 77 | } 78 | 79 | inline 80 | void Selection::setReferenceRect(const QRect &rect) 81 | { 82 | m_referenceRect = rect; 83 | } 84 | 85 | inline 86 | void Selection::stop() 87 | { 88 | m_hasSelection = false; 89 | m_selection = m_selection.normalized(); 90 | } 91 | 92 | #endif // SELECTION_H 93 | -------------------------------------------------------------------------------- /settings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "settings.h" 4 | 5 | class SettingsPrivate 6 | { 7 | public: 8 | QSettings *settings; 9 | QMap translations; 10 | QHash defaultValues; 11 | }; 12 | 13 | /*******************************************************/ 14 | 15 | Settings::Settings() 16 | { 17 | d = new SettingsPrivate; 18 | 19 | addDefaultValues(); 20 | 21 | d->settings = new QSettings(QSettings::IniFormat, 22 | QSettings::UserScope, 23 | QCoreApplication::organizationName(), 24 | QCoreApplication::applicationName()); 25 | 26 | qDebug("Configuration file: %s", qPrintable(d->settings->fileName())); 27 | 28 | d->settings->setFallbacksEnabled(false); 29 | } 30 | 31 | void Settings::addDefaultValues() 32 | { 33 | QHash defaultValues; 34 | 35 | defaultValues.insert(SETTING_SKIP_TAGGED, false); 36 | defaultValues.insert(SETTING_MOVE_UNTAGGED, false); 37 | defaultValues.insert(SETTING_TOOLTIPS, true); 38 | 39 | addDefaultValues(defaultValues); 40 | } 41 | 42 | void Settings::addDefaultValues(const QHash &defaultValues) 43 | { 44 | QHash::const_iterator itEnd = defaultValues.end(); 45 | 46 | for(QHash::const_iterator it = defaultValues.begin();it != itEnd;++it) 47 | { 48 | d->defaultValues.insert(it.key(), it.value()); 49 | } 50 | } 51 | 52 | void Settings::fillTranslations() 53 | { 54 | d->translations.insert("en", "English"); 55 | 56 | // http://www.loc.gov/standards/iso639-2/php/code_list.php 57 | // currently nothing to add 58 | } 59 | 60 | Settings::~Settings() 61 | { 62 | delete d->settings; 63 | delete d; 64 | } 65 | 66 | QVariant Settings::defaultValue(const QString &key) const 67 | { 68 | return d->defaultValues.value(key); 69 | } 70 | 71 | void Settings::remove(const QString &key, Settings::SyncType sync) 72 | { 73 | QSettings *s = settings(); 74 | 75 | s->beginGroup("settings"); 76 | s->remove(key); 77 | s->endGroup(); 78 | 79 | if(sync == Sync) 80 | s->sync(); 81 | } 82 | 83 | void Settings::sync() 84 | { 85 | d->settings->sync(); 86 | } 87 | 88 | QMap Settings::translations() 89 | { 90 | if(d->translations.isEmpty()) 91 | fillTranslations(); 92 | 93 | return d->translations; 94 | } 95 | 96 | Settings* Settings::instance() 97 | { 98 | static Settings *inst = new Settings; 99 | 100 | return inst; 101 | } 102 | 103 | QHash& Settings::defaultValues() 104 | { 105 | return d->defaultValues; 106 | } 107 | 108 | QSettings *Settings::settings() const 109 | { 110 | return d->settings; 111 | } 112 | -------------------------------------------------------------------------------- /settings.h: -------------------------------------------------------------------------------- 1 | #ifndef SETTINGS_H 2 | #define SETTINGS_H 3 | 4 | #include 5 | 6 | #define SETTINGS_CONTAINS Settings::instance()->contains 7 | 8 | #define SETTINGS_GET_BOOL Settings::instance()->value 9 | #define SETTINGS_SET_BOOL Settings::instance()->setValue 10 | 11 | #define SETTINGS_GET_INT Settings::instance()->value 12 | #define SETTINGS_SET_INT Settings::instance()->setValue 13 | 14 | #define SETTINGS_GET_STRING Settings::instance()->value 15 | #define SETTINGS_SET_STRING Settings::instance()->setValue 16 | 17 | #define SETTINGS_REMOVE Settings::instance()->remove 18 | 19 | #define SETTING_LAST_DIRECTORY "last-directory" 20 | #define SETTING_SKIP_TAGGED "skip-tagged" 21 | #define SETTING_MOVE_UNTAGGED "move-untagged" 22 | #define SETTING_TOOLTIPS "tooltips" 23 | 24 | class SettingsPrivate; 25 | 26 | /* 27 | * System settings 28 | */ 29 | class Settings 30 | { 31 | public: 32 | static Settings* instance(); 33 | 34 | ~Settings(); 35 | 36 | enum SyncType { NoSync, Sync }; 37 | 38 | template 39 | T value(const QString &key); 40 | 41 | template 42 | T value(const QString &key, const T &def); 43 | 44 | template 45 | void setValue(const QString &key, const T &value, SyncType sync = Sync); 46 | 47 | QVariant defaultValue(const QString &key) const; 48 | 49 | /* 50 | * Remove the specified key from the section "settings" 51 | */ 52 | void remove(const QString &key, SyncType sync = Sync); 53 | 54 | void sync(); 55 | 56 | /* 57 | * Available translations, hardcoded 58 | */ 59 | QMap translations(); 60 | 61 | private: 62 | Settings(); 63 | 64 | /* 65 | * Install some default values 66 | */ 67 | void addDefaultValues(); 68 | void addDefaultValues(const QHash &defaultValues); 69 | 70 | void fillTranslations(); 71 | 72 | QHash &defaultValues(); 73 | 74 | QSettings *settings() const; 75 | 76 | private: 77 | SettingsPrivate *d; 78 | }; 79 | 80 | /**********************************/ 81 | 82 | template 83 | T Settings::value(const QString &key) 84 | { 85 | T def = T(); 86 | QHash::iterator it = defaultValues().find(key); 87 | 88 | if(it != defaultValues().end()) 89 | def = it.value().value(); 90 | 91 | return value(key, def); 92 | } 93 | 94 | template 95 | T Settings::value(const QString &key, const T &def) 96 | { 97 | QSettings *s = settings(); 98 | 99 | s->beginGroup("settings"); 100 | QVariant value = s->value(key, QVariant::fromValue(def)); 101 | s->endGroup(); 102 | 103 | return value.value(); 104 | } 105 | 106 | template 107 | void Settings::setValue(const QString &key, const T &value, Settings::SyncType sync) 108 | { 109 | QSettings *s = settings(); 110 | 111 | s->beginGroup("settings"); 112 | s->setValue(key, QVariant::fromValue(value)); 113 | s->endGroup(); 114 | 115 | if(sync == Sync) 116 | s->sync(); 117 | } 118 | 119 | #endif // SETTINGS_H 120 | -------------------------------------------------------------------------------- /squeezedlabel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "squeezedlabel.h" 5 | 6 | SqueezedLabel::SqueezedLabel(QWidget *parent) 7 | : QLabel(parent) 8 | , m_metrics(nullptr) 9 | { 10 | setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); 11 | setTextFormat(Qt::PlainText); 12 | 13 | ensurePolished(); 14 | } 15 | 16 | SqueezedLabel::~SqueezedLabel() 17 | { 18 | delete m_metrics; 19 | } 20 | 21 | void SqueezedLabel::setText(const QString &text) 22 | { 23 | m_text = text; 24 | updateText(); 25 | } 26 | 27 | void SqueezedLabel::updateText() 28 | { 29 | if(!m_metrics) 30 | m_metrics = new QFontMetrics(font()); 31 | 32 | QLabel::setText(m_metrics->elidedText(m_text, Qt::ElideMiddle, width())); 33 | } 34 | 35 | void SqueezedLabel::resizeEvent(QResizeEvent *event) 36 | { 37 | Q_UNUSED(event) 38 | 39 | updateText(); 40 | } 41 | -------------------------------------------------------------------------------- /squeezedlabel.h: -------------------------------------------------------------------------------- 1 | #ifndef SQUEEZEDLABEL_H 2 | #define SQUEEZEDLABEL_H 3 | 4 | #include 5 | 6 | class QFontMetrics; 7 | 8 | /* 9 | * Label displaying dots if not enough space for all characters like 10 | * long_image_...file.jpg 11 | */ 12 | class SqueezedLabel : public QLabel 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit SqueezedLabel(QWidget *parent = 0); 18 | ~SqueezedLabel(); 19 | 20 | void setText(const QString &text); 21 | 22 | private slots: 23 | void updateText(); 24 | 25 | protected: 26 | virtual void resizeEvent(QResizeEvent *event) override; 27 | 28 | private: 29 | QFontMetrics *m_metrics; 30 | QString m_text; 31 | }; 32 | 33 | #endif // SQUEEZEDLABEL_H 34 | -------------------------------------------------------------------------------- /threadedimageloader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "threadedimageloader.h" 5 | 6 | ThreadedImageLoader::ThreadedImageLoader(QObject *parent) 7 | : QThread(parent) 8 | {} 9 | 10 | void ThreadedImageLoader::loadImageFromFile(const QString &imagePath) 11 | { 12 | m_imagePath = imagePath; 13 | 14 | start(); 15 | } 16 | 17 | void ThreadedImageLoader::run() 18 | { 19 | emit loaded(QImage(m_imagePath)); 20 | } 21 | -------------------------------------------------------------------------------- /threadedimageloader.h: -------------------------------------------------------------------------------- 1 | #ifndef THREADEDIMAGELOADER_H 2 | #define THREADEDIMAGELOADER_H 3 | 4 | #include 5 | #include 6 | 7 | class QImage; 8 | 9 | /* 10 | * Thread to asynchronously load images. Allocates an image on a heap. Signal receiver 11 | * MUST delete it 12 | */ 13 | class ThreadedImageLoader : public QThread 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | ThreadedImageLoader(QObject *parent = nullptr); 19 | 20 | void loadImageFromFile(const QString &imagePath); 21 | 22 | protected: 23 | virtual void run() override; 24 | 25 | signals: 26 | void loaded(const QImage &); 27 | 28 | private: 29 | QString m_imagePath; 30 | }; 31 | 32 | #endif // THREADEDIMAGELOADER_H 33 | -------------------------------------------------------------------------------- /utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include "platefile.h" 8 | #include "utils.h" 9 | 10 | constexpr double BOUNDING_ENLARGE_WIDTH_FACTOR = 0.15; 11 | constexpr double BOUNDING_ENLARGE_HEIGHT_FACTOR = 0.25; 12 | 13 | QString Utils::helpString() 14 | { 15 | return QObject::tr("Help"); 16 | } 17 | 18 | QString Utils::informationString() 19 | { 20 | return QObject::tr("Information"); 21 | } 22 | 23 | QString Utils::warningString() 24 | { 25 | return QObject::tr("Warning"); 26 | } 27 | 28 | QString Utils::errorString() 29 | { 30 | return QObject::tr("Error"); 31 | } 32 | 33 | QString Utils::fatalErrorString() 34 | { 35 | return QObject::tr("Fatal error"); 36 | } 37 | 38 | QPoint Utils::centroid(const QPolygon &polygon) 39 | { 40 | QPoint centroid{0,0}; 41 | 42 | foreach(const auto &point, polygon) 43 | { 44 | centroid.rx() += point.x(); 45 | centroid.ry() += point.y(); 46 | } 47 | 48 | return centroid / polygon.size(); 49 | } 50 | 51 | void Utils::setShortcutTooltips(const QList &buttons) 52 | { 53 | // set tooltips 54 | foreach(auto *button, buttons) 55 | { 56 | button->setToolTip(QObject::tr("Shortcut: %1").arg(button->shortcut().toString())); 57 | } 58 | } 59 | 60 | QStringList Utils::imageMatchingWildcard() 61 | { 62 | return QStringList() 63 | << "*.jpg" 64 | << "*.JPG" 65 | << "*.jpeg" 66 | << "*.JPEG" 67 | << "*.png" 68 | << "*.PNG" 69 | ; 70 | } 71 | 72 | QPoint Utils::fitPoint(const QRect &m_referenceRect, const QPoint &_pos) 73 | { 74 | QPoint pos = _pos; 75 | 76 | if(pos.x() > m_referenceRect.topRight().x()) 77 | pos.setX(m_referenceRect.topRight().x()); 78 | else if(pos.x() < m_referenceRect.topLeft().x()) 79 | pos.setX(m_referenceRect.topLeft().x()); 80 | 81 | if(pos.y() > m_referenceRect.bottomLeft().y()) 82 | pos.setY(m_referenceRect.bottomLeft().y()); 83 | else if(pos.y() < m_referenceRect.topLeft().y()) 84 | pos.setY(m_referenceRect.topLeft().y()); 85 | 86 | return pos; 87 | } 88 | 89 | QRect Utils::selectionForPlate(const PlateFile &plateFile, const QImage &inImage) 90 | { 91 | const QRect &boundingRect = plateFile.plateCorners().boundingRect(); 92 | 93 | // enlarge 94 | QRect selection = boundingRect.adjusted(-BOUNDING_ENLARGE_WIDTH_FACTOR * boundingRect.width(), 95 | -BOUNDING_ENLARGE_HEIGHT_FACTOR * boundingRect.height(), 96 | BOUNDING_ENLARGE_WIDTH_FACTOR * boundingRect.width(), 97 | BOUNDING_ENLARGE_HEIGHT_FACTOR * boundingRect.height()); 98 | 99 | selection &= inImage.rect(); 100 | 101 | return selection; 102 | } 103 | 104 | void Utils::help(const QString &message, QWidget *parent) 105 | { 106 | QMessageBox::information(parent, Utils::helpString(), message); 107 | } 108 | 109 | void Utils::message(const QString &message, QWidget *parent) 110 | { 111 | QMessageBox::information(parent, Utils::informationString(), message); 112 | } 113 | 114 | void Utils::warning(const QString &message, QWidget *parent) 115 | { 116 | QMessageBox::warning(parent, Utils::warningString(), message); 117 | } 118 | 119 | void Utils::error(const QString &message, QWidget *parent) 120 | { 121 | QMessageBox::critical(parent, Utils::errorString(), message); 122 | } 123 | 124 | void Utils::fatalError(const QString &message, QWidget *parent) 125 | { 126 | QMessageBox::critical(parent, Utils::fatalErrorString(), message); 127 | ::exit(1); 128 | } 129 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H 2 | #define UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class QPushButton; 11 | class QPolygon; 12 | class QWidget; 13 | class QImage; 14 | class QRect; 15 | 16 | class PlateFile; 17 | 18 | class Utils 19 | { 20 | public: 21 | static QString helpString(); 22 | static QString informationString(); 23 | static QString warningString(); 24 | static QString errorString(); 25 | static QString fatalErrorString(); 26 | 27 | /* 28 | * Pen to pain a polygon 29 | */ 30 | static QPen polygonPaintingPen(); 31 | 32 | /* 33 | * Calculate a polygon centroid 34 | */ 35 | static QPoint centroid(const QPolygon &polygon); 36 | 37 | /* 38 | * Set tooltips for buttons with their shortcuts 39 | */ 40 | static void setShortcutTooltips(const QList &buttons); 41 | 42 | /* 43 | * Supported image formats as a UNIX wildcard 44 | */ 45 | static QStringList imageMatchingWildcard(); 46 | 47 | static QPoint fitPoint(const QRect &m_referenceRect, const QPoint &_pos); 48 | 49 | /* 50 | * Return a selection rectangle to edit the specified plate 51 | */ 52 | static QRect selectionForPlate(const PlateFile &plateFile, const QImage &inImage); 53 | 54 | static void help(const QString &message, QWidget *parent = nullptr); 55 | static void message(const QString &message, QWidget *parent = nullptr); 56 | static void warning(const QString &message, QWidget *parent = nullptr); 57 | static void error(const QString &message, QWidget *parent = nullptr); 58 | static void fatalError(const QString &message, QWidget *parent = nullptr); 59 | }; 60 | 61 | inline 62 | QPen Utils::polygonPaintingPen() 63 | { 64 | return QPen(Qt::magenta, 2); 65 | } 66 | 67 | #endif // UTILS_H 68 | --------------------------------------------------------------------------------