Commit 6a6d404e40b9efd64ee8441997c0f773a9be132c
Merge branch 'master' of https://github.com/biometrics/openbr
Showing
8 changed files
with
200 additions
and
112 deletions
CHANGELOG.md
| @@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
| 8 | * Refactored File class to improve point and rect storage (#22) | 8 | * Refactored File class to improve point and rect storage (#22) |
| 9 | * Added algorithm to show face detection results (#25) | 9 | * Added algorithm to show face detection results (#25) |
| 10 | * Reorganized GUI code and include paths (#31) | 10 | * Reorganized GUI code and include paths (#31) |
| 11 | +* 'br -daemon' to listen for commands on stdin | ||
| 11 | 12 | ||
| 12 | 0.2.0 - 2/23/13 | 13 | 0.2.0 - 2/23/13 |
| 13 | =============== | 14 | =============== |
app/br/br.cpp
| @@ -67,26 +67,23 @@ public: | @@ -67,26 +67,23 @@ public: | ||
| 67 | 67 | ||
| 68 | if (argc == 0) printf("%s\nTry running 'br -help'\n", br_about()); | 68 | if (argc == 0) printf("%s\nTry running 'br -help'\n", br_about()); |
| 69 | 69 | ||
| 70 | - bool shell = false; | ||
| 71 | - while (shell || (argc > 0)) { | 70 | + bool daemon = false; |
| 71 | + while (daemon || (argc > 0)) { | ||
| 72 | const char *fun; | 72 | const char *fun; |
| 73 | int parc; | 73 | int parc; |
| 74 | const char **parv; | 74 | const char **parv; |
| 75 | - if (shell) { | ||
| 76 | - printf("> "); | ||
| 77 | - br_read_line(&parc, &parv); | ||
| 78 | - if (parc == 0) continue; | ||
| 79 | - fun = parv[0]; | ||
| 80 | - parc--; | ||
| 81 | - parv = &parv[1]; | ||
| 82 | - } else /* argc > 0 */ { | ||
| 83 | - fun = &argv[0][1]; | ||
| 84 | - parc = 0; while ((1+parc < argc) && (argv[1+parc][0] != '-')) parc++; | ||
| 85 | - parv = (const char **)&argv[1]; | ||
| 86 | - argc = argc - (1+parc); | ||
| 87 | - argv = &argv[parc+1]; | 75 | + if (argc == 0) { // daemon |
| 76 | + br_read_stdin(&argc, &argv); | ||
| 77 | + if (argc == 0) break; | ||
| 88 | } | 78 | } |
| 89 | 79 | ||
| 80 | + fun = argv[0]; | ||
| 81 | + if (fun[0] == '-') fun++; | ||
| 82 | + parc = 0; while ((parc+1 < argc) && (argv[parc+1][0] != '-')) parc++; | ||
| 83 | + parv = (const char **)&argv[1]; | ||
| 84 | + argc = argc - (parc+1); | ||
| 85 | + argv = &argv[parc+1]; | ||
| 86 | + | ||
| 90 | // Core Tasks | 87 | // Core Tasks |
| 91 | if (!strcmp(fun, "train")) { | 88 | if (!strcmp(fun, "train")) { |
| 92 | check(parc >= 1, "Insufficient parameter count for 'train'."); | 89 | check(parc >= 1, "Insufficient parameter count for 'train'."); |
| @@ -94,7 +91,7 @@ public: | @@ -94,7 +91,7 @@ public: | ||
| 94 | } else if (!strcmp(fun, "enroll")) { | 91 | } else if (!strcmp(fun, "enroll")) { |
| 95 | check(parc >= 1, "Insufficient parameter count for 'enroll'."); | 92 | check(parc >= 1, "Insufficient parameter count for 'enroll'."); |
| 96 | if (parc == 1) br_enroll(parv[0]); | 93 | if (parc == 1) br_enroll(parv[0]); |
| 97 | - else br_enroll_n(parc-1, parv, parv[parc-1]); | 94 | + else br_enroll_n(parc-1, parv, parv[parc-1]); |
| 98 | } else if (!strcmp(fun, "compare")) { | 95 | } else if (!strcmp(fun, "compare")) { |
| 99 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'compare'."); | 96 | check((parc >= 2) && (parc <= 3), "Incorrect parameter count for 'compare'."); |
| 100 | br_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); | 97 | br_compare(parv[0], parv[1], parc == 3 ? parv[2] : ""); |
| @@ -162,12 +159,12 @@ public: | @@ -162,12 +159,12 @@ public: | ||
| 162 | } else if (!strcmp(fun, "version")) { | 159 | } else if (!strcmp(fun, "version")) { |
| 163 | check(parc == 0, "No parameters expected for 'version'."); | 160 | check(parc == 0, "No parameters expected for 'version'."); |
| 164 | printf("%s\n", br_version()); | 161 | printf("%s\n", br_version()); |
| 165 | - } else if (!strcmp(fun, "shell")) { | ||
| 166 | - check(parc == 0, "No parameters expected for 'shell'."); | ||
| 167 | - shell = true; | 162 | + } else if (!strcmp(fun, "daemon")) { |
| 163 | + check(parc == 0, "No parameters expected for 'daemon'."); | ||
| 164 | + daemon = true; | ||
| 168 | } else if (!strcmp(fun, "exit")) { | 165 | } else if (!strcmp(fun, "exit")) { |
| 169 | check(parc == 0, "No parameters expected for 'exit'."); | 166 | check(parc == 0, "No parameters expected for 'exit'."); |
| 170 | - shell = false; | 167 | + daemon = false; |
| 171 | } else if (!strcmp(fun, "br")) { | 168 | } else if (!strcmp(fun, "br")) { |
| 172 | printf("That's me!\n"); | 169 | printf("That's me!\n"); |
| 173 | } else if (parc <= 1) { | 170 | } else if (parc <= 1) { |
openbr/core/core.cpp
| @@ -111,64 +111,68 @@ struct AlgorithmCore | @@ -111,64 +111,68 @@ struct AlgorithmCore | ||
| 111 | if (gallery.isNull()) gallery = getMemoryGallery(input); | 111 | if (gallery.isNull()) gallery = getMemoryGallery(input); |
| 112 | 112 | ||
| 113 | QScopedPointer<Gallery> g(Gallery::make(gallery)); | 113 | QScopedPointer<Gallery> g(Gallery::make(gallery)); |
| 114 | - if (g.isNull()) return FileList(); | ||
| 115 | - | ||
| 116 | - if (gallery.contains("read") || gallery.contains("cache")) { | ||
| 117 | - fileList = g->files(); | ||
| 118 | - } | ||
| 119 | - if (!fileList.isEmpty() && gallery.contains("cache")) | ||
| 120 | - return fileList; | ||
| 121 | - | ||
| 122 | - const TemplateList i(TemplateList::fromGallery(input)); | ||
| 123 | - if (i.isEmpty()) return fileList; // Nothing to enroll | ||
| 124 | - | ||
| 125 | - if (transform.isNull()) qFatal("Null transform."); | ||
| 126 | - const int blocks = Globals->blocks(i.size()); | ||
| 127 | - Globals->currentStep = 0; | ||
| 128 | - Globals->totalSteps = i.size(); | ||
| 129 | - Globals->startTime.start(); | ||
| 130 | - | ||
| 131 | - const bool noDuplicates = gallery.contains("noDuplicates"); | ||
| 132 | - QStringList fileNames = noDuplicates ? fileList.names() : QStringList(); | ||
| 133 | - const int subBlockSize = 4*std::max(1, Globals->parallelism); | ||
| 134 | - const int numSubBlocks = ceil(1.0*Globals->blockSize/subBlockSize); | ||
| 135 | - int totalCount = 0, failureCount = 0; | ||
| 136 | - double totalBytes = 0; | ||
| 137 | - for (int block=0; block<blocks; block++) { | ||
| 138 | - for (int subBlock = 0; subBlock<numSubBlocks; subBlock++) { | ||
| 139 | - TemplateList data = i.mid(block*Globals->blockSize + subBlock*subBlockSize, subBlockSize); | ||
| 140 | - if (data.isEmpty()) break; | ||
| 141 | - if (noDuplicates) | ||
| 142 | - for (int i=data.size()-1; i>=0; i--) | ||
| 143 | - if (fileNames.contains(data[i].file.name)) | ||
| 144 | - data.removeAt(i); | ||
| 145 | - const int numFiles = data.size(); | ||
| 146 | - | ||
| 147 | - if (Globals->backProject) { | ||
| 148 | - TemplateList backProjectedData; | ||
| 149 | - transform->backProject(data, backProjectedData); | ||
| 150 | - data = backProjectedData; | ||
| 151 | - } else { | ||
| 152 | - data >> *transform; | 114 | + if (g.isNull()) qFatal("Null gallery!"); |
| 115 | + | ||
| 116 | + do { | ||
| 117 | + fileList.clear(); | ||
| 118 | + | ||
| 119 | + if (gallery.contains("read") || gallery.contains("cache")) | ||
| 120 | + fileList = g->files(); | ||
| 121 | + | ||
| 122 | + if (!fileList.isEmpty() && gallery.contains("cache")) | ||
| 123 | + return fileList; | ||
| 124 | + | ||
| 125 | + const TemplateList i(TemplateList::fromGallery(input)); | ||
| 126 | + if (i.isEmpty()) return fileList; // Nothing to enroll | ||
| 127 | + | ||
| 128 | + if (transform.isNull()) qFatal("Null transform."); | ||
| 129 | + const int blocks = Globals->blocks(i.size()); | ||
| 130 | + Globals->currentStep = 0; | ||
| 131 | + Globals->totalSteps = i.size(); | ||
| 132 | + Globals->startTime.start(); | ||
| 133 | + | ||
| 134 | + const bool noDuplicates = gallery.contains("noDuplicates"); | ||
| 135 | + QStringList fileNames = noDuplicates ? fileList.names() : QStringList(); | ||
| 136 | + const int subBlockSize = 4*std::max(1, Globals->parallelism); | ||
| 137 | + const int numSubBlocks = ceil(1.0*Globals->blockSize/subBlockSize); | ||
| 138 | + int totalCount = 0, failureCount = 0; | ||
| 139 | + double totalBytes = 0; | ||
| 140 | + for (int block=0; block<blocks; block++) { | ||
| 141 | + for (int subBlock = 0; subBlock<numSubBlocks; subBlock++) { | ||
| 142 | + TemplateList data = i.mid(block*Globals->blockSize + subBlock*subBlockSize, subBlockSize); | ||
| 143 | + if (data.isEmpty()) break; | ||
| 144 | + if (noDuplicates) | ||
| 145 | + for (int i=data.size()-1; i>=0; i--) | ||
| 146 | + if (fileNames.contains(data[i].file.name)) | ||
| 147 | + data.removeAt(i); | ||
| 148 | + const int numFiles = data.size(); | ||
| 149 | + | ||
| 150 | + if (Globals->backProject) { | ||
| 151 | + TemplateList backProjectedData; | ||
| 152 | + transform->backProject(data, backProjectedData); | ||
| 153 | + data = backProjectedData; | ||
| 154 | + } else { | ||
| 155 | + data >> *transform; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + g->writeBlock(data); | ||
| 159 | + const FileList newFiles = data.files(); | ||
| 160 | + fileList.append(newFiles); | ||
| 161 | + | ||
| 162 | + totalCount += newFiles.size(); | ||
| 163 | + failureCount += newFiles.failures(); | ||
| 164 | + totalBytes += data.bytes<double>(); | ||
| 165 | + Globals->currentStep += numFiles; | ||
| 166 | + Globals->printStatus(); | ||
| 153 | } | 167 | } |
| 154 | - | ||
| 155 | - g->writeBlock(data); | ||
| 156 | - const FileList newFiles = data.files(); | ||
| 157 | - fileList.append(newFiles); | ||
| 158 | - | ||
| 159 | - totalCount += newFiles.size(); | ||
| 160 | - failureCount += newFiles.failures(); | ||
| 161 | - totalBytes += data.bytes<double>(); | ||
| 162 | - Globals->currentStep += numFiles; | ||
| 163 | - Globals->printStatus(); | ||
| 164 | } | 168 | } |
| 165 | - } | ||
| 166 | 169 | ||
| 167 | - const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism)); | ||
| 168 | - if (!Globals->quiet && (Globals->totalSteps > 1)) | ||
| 169 | - fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n", | ||
| 170 | - speed, totalBytes/totalCount, failureCount, totalCount); | ||
| 171 | - Globals->totalSteps = 0; | 170 | + const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism)); |
| 171 | + if (!Globals->quiet && (Globals->totalSteps > 1)) | ||
| 172 | + fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n", | ||
| 173 | + speed, totalBytes/totalCount, failureCount, totalCount); | ||
| 174 | + Globals->totalSteps = 0; | ||
| 175 | + } while (input.getBool("infinite")); | ||
| 172 | 176 | ||
| 173 | return fileList; | 177 | return fileList; |
| 174 | } | 178 | } |
openbr/openbr.cpp
| @@ -182,10 +182,10 @@ float br_progress() | @@ -182,10 +182,10 @@ float br_progress() | ||
| 182 | return Globals->progress(); | 182 | return Globals->progress(); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | -void br_read_line(int *argc, const char ***argv) | 185 | +void br_read_stdin(int *argc, char ***argv) |
| 186 | { | 186 | { |
| 187 | static QList<QByteArray> byteArrayList; | 187 | static QList<QByteArray> byteArrayList; |
| 188 | - static QVector<const char*> rawCharArrayList; | 188 | + static QVector<char*> rawCharArrayList; |
| 189 | 189 | ||
| 190 | byteArrayList.clear(); rawCharArrayList.clear(); | 190 | byteArrayList.clear(); rawCharArrayList.clear(); |
| 191 | foreach (const QString &string, QtUtils::parse(QTextStream(stdin).readLine(), ' ')) { | 191 | foreach (const QString &string, QtUtils::parse(QTextStream(stdin).readLine(), ' ')) { |
openbr/openbr.h
| @@ -297,15 +297,15 @@ BR_EXPORT bool br_plot_metadata(int num_files, const char *files[], const char * | @@ -297,15 +297,15 @@ BR_EXPORT bool br_plot_metadata(int num_files, const char *files[], const char * | ||
| 297 | BR_EXPORT float br_progress(); | 297 | BR_EXPORT float br_progress(); |
| 298 | 298 | ||
| 299 | /*! | 299 | /*! |
| 300 | - * \brief Read and parse a line from the terminal. | 300 | + * \brief Read and parse stdin. |
| 301 | * | 301 | * |
| 302 | - * Used by the \ref cli to implement \c -shell. | 302 | + * Used by the \ref cli to implement \c -daemon. |
| 303 | * Generally not useful otherwise. | 303 | * Generally not useful otherwise. |
| 304 | * \param[out] argc argument count | 304 | * \param[out] argc argument count |
| 305 | * \param[out] argv argument list | 305 | * \param[out] argv argument list |
| 306 | * \note \ref managed_return_value | 306 | * \note \ref managed_return_value |
| 307 | */ | 307 | */ |
| 308 | -BR_EXPORT void br_read_line(int *argc, const char ***argv); | 308 | +BR_EXPORT void br_read_stdin(int *argc, char ***argv); |
| 309 | 309 | ||
| 310 | /*! | 310 | /*! |
| 311 | * \brief Converts a simmat to a new output format. | 311 | * \brief Converts a simmat to a new output format. |
openbr/openbr_plugin.cpp
| @@ -131,7 +131,7 @@ void File::set(const QString &key, const QVariant &value) | @@ -131,7 +131,7 @@ void File::set(const QString &key, const QVariant &value) | ||
| 131 | const QString valueString = value.toString(); | 131 | const QString valueString = value.toString(); |
| 132 | 132 | ||
| 133 | /* We assume that if the value starts with '0' | 133 | /* We assume that if the value starts with '0' |
| 134 | - then it was probably intended to to be a string UID | 134 | + then it was probably intended to be a string UID |
| 135 | and that it's numerical value is not relevant. */ | 135 | and that it's numerical value is not relevant. */ |
| 136 | if (value.canConvert(QVariant::Double) && | 136 | if (value.canConvert(QVariant::Double) && |
| 137 | (!valueString.startsWith('0') || (valueString == "0"))) | 137 | (!valueString.startsWith('0') || (valueString == "0"))) |
openbr/plugins/format.cpp
| @@ -492,6 +492,28 @@ BR_REGISTER(Format, matFormat) | @@ -492,6 +492,28 @@ BR_REGISTER(Format, matFormat) | ||
| 492 | 492 | ||
| 493 | /*! | 493 | /*! |
| 494 | * \ingroup formats | 494 | * \ingroup formats |
| 495 | + * \brief Returns an empty matrix. | ||
| 496 | + * \author Josh Klontz \cite jklontz | ||
| 497 | + */ | ||
| 498 | +class nullFormat : public Format | ||
| 499 | +{ | ||
| 500 | + Q_OBJECT | ||
| 501 | + | ||
| 502 | + Template read() const | ||
| 503 | + { | ||
| 504 | + return Template(file, Mat()); | ||
| 505 | + } | ||
| 506 | + | ||
| 507 | + void write(const Template &t) const | ||
| 508 | + { | ||
| 509 | + (void)t; | ||
| 510 | + } | ||
| 511 | +}; | ||
| 512 | + | ||
| 513 | +BR_REGISTER(Format, nullFormat) | ||
| 514 | + | ||
| 515 | +/*! | ||
| 516 | + * \ingroup formats | ||
| 495 | * \brief RAW format | 517 | * \brief RAW format |
| 496 | * | 518 | * |
| 497 | * http://www.nist.gov/srd/nistsd27.cfm | 519 | * http://www.nist.gov/srd/nistsd27.cfm |
openbr/plugins/qtnetwork.cpp
| @@ -50,55 +50,119 @@ class urlFormat : public Format | @@ -50,55 +50,119 @@ class urlFormat : public Format | ||
| 50 | 50 | ||
| 51 | BR_REGISTER(Format, urlFormat) | 51 | BR_REGISTER(Format, urlFormat) |
| 52 | 52 | ||
| 53 | -class WebServices : public QTcpServer | 53 | +/*! |
| 54 | + * \ingroup galleries | ||
| 55 | + * \brief Handle POST requests | ||
| 56 | + * \author Josh Klontz \cite jklontz | ||
| 57 | + */ | ||
| 58 | +class postGallery : public Gallery | ||
| 54 | { | 59 | { |
| 55 | Q_OBJECT | 60 | Q_OBJECT |
| 56 | 61 | ||
| 62 | + class TcpServer : public QTcpServer | ||
| 63 | + { | ||
| 64 | + QList<qintptr> socketDescriptors; | ||
| 65 | + QMutex socketDescriptorsLock; | ||
| 66 | + | ||
| 67 | + public: | ||
| 68 | + QList<qintptr> availableSocketDescriptors() | ||
| 69 | + { | ||
| 70 | + QMutexLocker locker(&socketDescriptorsLock); | ||
| 71 | + QList<qintptr> result(socketDescriptors); | ||
| 72 | + socketDescriptors.clear(); | ||
| 73 | + return result; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + void addPendingConnection(QTcpSocket *socket) | ||
| 77 | + { | ||
| 78 | + QTcpServer::addPendingConnection(socket); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + private: | ||
| 82 | + void incomingConnection(qintptr socketDescriptor) | ||
| 83 | + { | ||
| 84 | + QMutexLocker locker(&socketDescriptorsLock); | ||
| 85 | + socketDescriptors.append(socketDescriptor); | ||
| 86 | + } | ||
| 87 | + }; | ||
| 88 | + | ||
| 57 | public: | 89 | public: |
| 58 | - WebServices() | 90 | + static QScopedPointer<TcpServer> server; |
| 91 | + | ||
| 92 | + postGallery() | ||
| 59 | { | 93 | { |
| 60 | - connect(this, SIGNAL(newConnection()), this, SLOT(handleNewConnection())); | 94 | + if (server.isNull()) { |
| 95 | + server.reset(new TcpServer()); | ||
| 96 | + server->listen(QHostAddress::Any, 8080); | ||
| 97 | + server->moveToThread(QCoreApplication::instance()->thread()); | ||
| 98 | + qDebug("Listening on %s:%d", qPrintable(server->serverAddress().toString()), server->serverPort()); | ||
| 99 | + } | ||
| 61 | } | 100 | } |
| 62 | 101 | ||
| 63 | - void listen() | 102 | +private: |
| 103 | + TemplateList readBlock(bool *done) | ||
| 64 | { | 104 | { |
| 65 | - QTcpServer::listen(QHostAddress::Any, 8080); | 105 | + *done = true; |
| 106 | + TemplateList templates; | ||
| 107 | + foreach (qintptr socketDescriptor, server->availableSocketDescriptors()) { | ||
| 108 | + File f(".post"); | ||
| 109 | + f.set("socketDescriptor", socketDescriptor); | ||
| 110 | + templates.append(f); | ||
| 111 | + } | ||
| 112 | + if (templates.isEmpty()) | ||
| 113 | + templates.append(File(".null")); | ||
| 114 | + return templates; | ||
| 66 | } | 115 | } |
| 67 | 116 | ||
| 68 | -private slots: | ||
| 69 | - void handleNewConnection() | 117 | + void write(const Template &t) |
| 70 | { | 118 | { |
| 71 | - while (hasPendingConnections()) { | ||
| 72 | - QTcpSocket *socket = QTcpServer::nextPendingConnection(); | ||
| 73 | - connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); | ||
| 74 | - connect(socket, SIGNAL(readyRead()), this, SLOT(read())); | ||
| 75 | -// socket->write("HTTP/1.1 200 OK\r\n" | ||
| 76 | -// "Content-Type: text/html; charset=UTF-8\r\n\r\n" | ||
| 77 | -// "Hello World!\r\n"); | ||
| 78 | -// socket->disconnectFromHost(); | ||
| 79 | - } | 119 | + (void) t; |
| 120 | + qFatal("Not supported!"); | ||
| 80 | } | 121 | } |
| 122 | +}; | ||
| 123 | + | ||
| 124 | +QScopedPointer<postGallery::TcpServer> postGallery::server; | ||
| 125 | + | ||
| 126 | +BR_REGISTER(Gallery, postGallery) | ||
| 81 | 127 | ||
| 82 | - void read() | 128 | +/*! |
| 129 | + * \ingroup formats | ||
| 130 | + * \brief Handle POST requests | ||
| 131 | + * \author Josh Klontz \cite jklontz | ||
| 132 | + */ | ||
| 133 | +class postFormat : public Format | ||
| 134 | +{ | ||
| 135 | + Q_OBJECT | ||
| 136 | + | ||
| 137 | + Template read() const | ||
| 83 | { | 138 | { |
| 84 | - QTcpSocket *socket = dynamic_cast<QTcpSocket*>(QObject::sender()); | ||
| 85 | - if (socket == NULL) return; | 139 | + Template t(file); |
| 140 | + qDebug() << t.file.flat(); | ||
| 141 | + QTcpSocket *socket = new QTcpSocket(); | ||
| 142 | + socket->setSocketDescriptor(file.get<qintptr>("socketDescriptor")); | ||
| 143 | + | ||
| 144 | + socket->write("HTTP/1.1 200 OK\r\n" | ||
| 145 | + "Content-Type: text/html; charset=UTF-8\r\n\r\n" | ||
| 146 | + "Hello World!\r\n"); | ||
| 147 | + socket->waitForBytesWritten(); | ||
| 148 | + | ||
| 149 | + socket->waitForReadyRead(); | ||
| 86 | QByteArray data = socket->readAll(); | 150 | QByteArray data = socket->readAll(); |
| 87 | - qDebug() << data; | 151 | + t.append(imdecode(Mat(1, data.size(), CV_8UC1, data.data()), 1)); |
| 152 | + | ||
| 153 | + socket->close(); | ||
| 154 | + delete socket; | ||
| 155 | + return t; | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + void write(const Template &t) const | ||
| 159 | + { | ||
| 160 | + (void) t; | ||
| 161 | + qFatal("Not supported!"); | ||
| 88 | } | 162 | } |
| 89 | }; | 163 | }; |
| 90 | 164 | ||
| 91 | -//static void web() | ||
| 92 | -//{ | ||
| 93 | -// static WebServices webServices; | ||
| 94 | -// if (webServices.isListening()) | ||
| 95 | -// return; | ||
| 96 | - | ||
| 97 | -// webServices.listen(); | ||
| 98 | -// qDebug("Listening on %s:%d", qPrintable(webServices.serverAddress().toString()), webServices.serverPort()); | ||
| 99 | -// while (true) | ||
| 100 | -// QCoreApplication::processEvents(); | ||
| 101 | -//} | 165 | +BR_REGISTER(Format, postFormat) |
| 102 | 166 | ||
| 103 | } // namespace br | 167 | } // namespace br |
| 104 | 168 |