Commit a232dceb21a97cc3077f83c58aae0e5274b60969
Merge pull request #164 from biometrics/string_management
Updates to the c API to handle returning strings more safely
Showing
11 changed files
with
148 additions
and
83 deletions
app/br/br.cpp
| ... | ... | @@ -171,7 +171,11 @@ public: |
| 171 | 171 | // Do nothing because we checked for this flag prior to initialization |
| 172 | 172 | } else if (!strcmp(fun, "objects")) { |
| 173 | 173 | check(parc <= 2, "Incorrect parameter count for 'objects'."); |
| 174 | - printf("%s\n", br_objects(parc >= 1 ? parv[0] : ".*", parc >= 2 ? parv[1] : ".*")); | |
| 174 | + int size = br_objects(NULL, 0, parc >= 1 ? parv[0] : ".*", parc >= 2 ? parv[1] : ".*"); | |
| 175 | + char * temp = new char[size]; | |
| 176 | + br_objects(temp, size, parc >= 1 ? parv[0] : ".*", parc >= 2 ? parv[1] : ".*"); | |
| 177 | + printf("%s\n", temp); | |
| 178 | + delete [] temp; | |
| 175 | 179 | } else if (!strcmp(fun, "about")) { |
| 176 | 180 | check(parc == 0, "No parameters expected for 'about'."); |
| 177 | 181 | printf("%s\n", br_about()); | ... | ... |
openbr/gui/algorithm.cpp
| 1 | 1 | #include <QStringList> |
| 2 | 2 | #include <openbr/openbr.h> |
| 3 | +#include <openbr/openbr_plugin.h> | |
| 3 | 4 | |
| 4 | 5 | #include "algorithm.h" |
| 5 | 6 | |
| ... | ... | @@ -18,7 +19,7 @@ bool br::Algorithm::addAlgorithm(const QString &algorithm, const QString &displa |
| 18 | 19 | { |
| 19 | 20 | static QStringList availableAlgorithms; |
| 20 | 21 | if (availableAlgorithms.isEmpty()) |
| 21 | - availableAlgorithms = QString(br_objects("Abbreviation", ".*", false)).split("\n"); | |
| 22 | + availableAlgorithms = br::Context::objects("Abbreviation", ".*", false); | |
| 22 | 23 | |
| 23 | 24 | if (!availableAlgorithms.contains(algorithm)) |
| 24 | 25 | return false; | ... | ... |
openbr/gui/gallerytoolbar.cpp
| ... | ... | @@ -84,7 +84,7 @@ void br::GalleryToolBar::_enroll(const br::File &input) |
| 84 | 84 | galleryLock.lock(); |
| 85 | 85 | this->input = input; |
| 86 | 86 | if (input.suffix() == "gal") gallery = input.name + ".mem"; |
| 87 | - else gallery = QString("%1/galleries/%2.gal[cache]").arg(br_scratch_path(), qPrintable(input.baseName()+input.hash())); | |
| 87 | + else gallery = QString("%1/galleries/%2.gal[cache]").arg(br::Globals->scratchPath(), qPrintable(input.baseName()+input.hash())); | |
| 88 | 88 | files = br::Enroll(input.flat(), gallery.flat()); |
| 89 | 89 | galleryLock.unlock(); |
| 90 | 90 | } |
| ... | ... | @@ -148,7 +148,7 @@ void br::GalleryToolBar::home() |
| 148 | 148 | |
| 149 | 149 | void br::GalleryToolBar::mean() |
| 150 | 150 | { |
| 151 | - const QString file = QString("%1/mean/%2.png").arg(br_scratch_path(), input.baseName()+input.hash()); | |
| 151 | + const QString file = QString("%1/mean/%2.png").arg(br::Globals->scratchPath(), input.baseName()+input.hash()); | |
| 152 | 152 | br_set_property("CENTER_TRAIN_B", qPrintable(file)); |
| 153 | 153 | br::File trainingFile = input; |
| 154 | 154 | br_train(qPrintable(trainingFile.flat()), "[algorithm=MedianFace]"); | ... | ... |
openbr/gui/progress.cpp
| 1 | 1 | #include <openbr/openbr.h> |
| 2 | +#include <openbr/openbr_plugin.h> | |
| 2 | 3 | |
| 3 | 4 | #include "progress.h" |
| 4 | 5 | |
| ... | ... | @@ -29,7 +30,7 @@ void br::Progress::checkProgress() |
| 29 | 30 | const bool visible = progress >= 0 && progress < 100; |
| 30 | 31 | |
| 31 | 32 | if (visible) { |
| 32 | - showMessage(br_most_recent_message()); | |
| 33 | + showMessage(Globals->mostRecentMessage); | |
| 33 | 34 | pbProgress.setValue(progress); |
| 34 | 35 | if (progress > 100) pbProgress.setMaximum(0); |
| 35 | 36 | else pbProgress.setMaximum(100); | ... | ... |
openbr/gui/templateviewer.cpp
| ... | ... | @@ -72,7 +72,7 @@ void TemplateViewer::refreshImage() |
| 72 | 72 | if (file.isNull() || (format == "Photo")) { |
| 73 | 73 | setImage(file, true); |
| 74 | 74 | } else { |
| 75 | - const QString path = QString(br_scratch_path()) + "/thumbnails"; | |
| 75 | + const QString path = QString(br::Globals->scratchPath()) + "/thumbnails"; | |
| 76 | 76 | const QString hash = file.hash()+format; |
| 77 | 77 | const QString processedFile = path+"/"+file.baseName()+hash+".png"; |
| 78 | 78 | if (!QFileInfo(processedFile).exists()) { | ... | ... |
openbr/gui/transformeditor.cpp
| ... | ... | @@ -24,7 +24,7 @@ using namespace br; |
| 24 | 24 | br::TransformEditor::TransformEditor(Transform *transform, QWidget *parent) |
| 25 | 25 | : QWidget(parent) |
| 26 | 26 | { |
| 27 | - name.addItems(QString(br_objects("Transform", ".*", false)).split('\n')); | |
| 27 | + name.addItems(br::Context::objects("Transform", ".*", false)); | |
| 28 | 28 | layout.addWidget(&name); |
| 29 | 29 | setLayout(&layout); |
| 30 | 30 | ... | ... |
openbr/openbr.cpp
| ... | ... | @@ -28,9 +28,27 @@ |
| 28 | 28 | |
| 29 | 29 | using namespace br; |
| 30 | 30 | |
| 31 | +static int partialCopy(const QString & string, char * buffer, int buffer_length) | |
| 32 | +{ | |
| 33 | + | |
| 34 | + QByteArray byteArray = string.toLocal8Bit(); | |
| 35 | + | |
| 36 | + int copyLength = std::min(buffer_length-1, byteArray.size()); | |
| 37 | + if (copyLength < 0) | |
| 38 | + return byteArray.size() + 1; | |
| 39 | + | |
| 40 | + memcpy(buffer, byteArray.data(), copyLength); | |
| 41 | + buffer[copyLength] = '\0'; | |
| 42 | + | |
| 43 | + return byteArray.size() + 1; | |
| 44 | +} | |
| 45 | + | |
| 31 | 46 | const char *br_about() |
| 32 | 47 | { |
| 48 | + static QMutex aboutLock; | |
| 49 | + QMutexLocker lock(&aboutLock); | |
| 33 | 50 | static QByteArray about = Context::about().toLocal8Bit(); |
| 51 | + | |
| 34 | 52 | return about.data(); |
| 35 | 53 | } |
| 36 | 54 | |
| ... | ... | @@ -150,53 +168,14 @@ void br_make_pairwise_mask(const char *target_input, const char *query_input, co |
| 150 | 168 | BEE::makePairwiseMask(target_input, query_input, mask); |
| 151 | 169 | } |
| 152 | 170 | |
| 153 | -const char *br_most_recent_message() | |
| 171 | +int br_most_recent_message(char * buffer, int buffer_length) | |
| 154 | 172 | { |
| 155 | - static QByteArray byteArray; | |
| 156 | - byteArray = Globals->mostRecentMessage.toLocal8Bit(); | |
| 157 | - return byteArray.data(); | |
| 173 | + return partialCopy(Globals->mostRecentMessage, buffer, buffer_length); | |
| 158 | 174 | } |
| 159 | 175 | |
| 160 | -const char *br_objects(const char *abstractions, const char *implementations, bool parameters) | |
| 176 | +int br_objects(char * buffer, int buffer_length, const char *abstractions, const char *implementations, bool parameters) | |
| 161 | 177 | { |
| 162 | - static QByteArray objects; | |
| 163 | - | |
| 164 | - QStringList objectList; | |
| 165 | - QRegExp abstractionsRegExp(abstractions); | |
| 166 | - QRegExp implementationsRegExp(implementations); | |
| 167 | - | |
| 168 | - if (abstractionsRegExp.exactMatch("Abbreviation")) | |
| 169 | - foreach (const QString &name, Globals->abbreviations.keys()) | |
| 170 | - if (implementationsRegExp.exactMatch(name)) | |
| 171 | - objectList.append(name + (parameters ? "\t" + Globals->abbreviations[name] : "")); | |
| 172 | - | |
| 173 | - if (abstractionsRegExp.exactMatch("Distance")) | |
| 174 | - foreach (const QString &name, Factory<Distance>::names()) | |
| 175 | - if (implementationsRegExp.exactMatch(name)) | |
| 176 | - objectList.append(name + (parameters ? "\t" + Factory<Distance>::parameters(name) : "")); | |
| 177 | - | |
| 178 | - if (abstractionsRegExp.exactMatch("Format")) | |
| 179 | - foreach (const QString &name, Factory<Format>::names()) | |
| 180 | - if (implementationsRegExp.exactMatch(name)) | |
| 181 | - objectList.append(name + (parameters ? "\t" + Factory<Format>::parameters(name) : "")); | |
| 182 | - | |
| 183 | - if (abstractionsRegExp.exactMatch("Initializer")) | |
| 184 | - foreach (const QString &name, Factory<Initializer>::names()) | |
| 185 | - if (implementationsRegExp.exactMatch(name)) | |
| 186 | - objectList.append(name + (parameters ? "\t" + Factory<Initializer>::parameters(name) : "")); | |
| 187 | - | |
| 188 | - if (abstractionsRegExp.exactMatch("Output")) | |
| 189 | - foreach (const QString &name, Factory<Output>::names()) | |
| 190 | - if (implementationsRegExp.exactMatch(name)) | |
| 191 | - objectList.append(name + (parameters ? "\t" + Factory<Output>::parameters(name) : "")); | |
| 192 | - | |
| 193 | - if (abstractionsRegExp.exactMatch("Transform")) | |
| 194 | - foreach (const QString &name, Factory<Transform>::names()) | |
| 195 | - if (implementationsRegExp.exactMatch(name)) | |
| 196 | - objectList.append(name + (parameters ? "\t" + Factory<Transform>::parameters(name) : "")); | |
| 197 | - | |
| 198 | - objects = objectList.join("\n").toLocal8Bit(); | |
| 199 | - return objects.data(); | |
| 178 | + return partialCopy(br::Context::objects(abstractions, implementations, parameters).join('\n'), buffer, buffer_length); | |
| 200 | 179 | } |
| 201 | 180 | |
| 202 | 181 | bool br_plot(int num_files, const char *files[], const char *destination, bool show) |
| ... | ... | @@ -251,15 +230,15 @@ void br_read_pipe(const char *pipe, int *argc, char ***argv) |
| 251 | 230 | *argv = rawCharArrayList.data(); |
| 252 | 231 | } |
| 253 | 232 | |
| 254 | -const char *br_scratch_path() | |
| 233 | +int br_scratch_path(char * buffer, int buffer_length) | |
| 255 | 234 | { |
| 256 | - static QByteArray byteArray; | |
| 257 | - byteArray = Context::scratchPath().toLocal8Bit(); | |
| 258 | - return byteArray.data(); | |
| 235 | + return partialCopy(Context::scratchPath(), buffer, buffer_length); | |
| 259 | 236 | } |
| 260 | 237 | |
| 261 | 238 | const char *br_sdk_path() |
| 262 | 239 | { |
| 240 | + static QMutex sdkLock; | |
| 241 | + QMutexLocker lock(&sdkLock); | |
| 263 | 242 | static QByteArray sdkPath = QDir(Globals->sdkPath).absolutePath().toLocal8Bit(); |
| 264 | 243 | return sdkPath.data(); |
| 265 | 244 | } |
| ... | ... | @@ -303,6 +282,8 @@ void br_train_n(int num_inputs, const char *inputs[], const char *model) |
| 303 | 282 | |
| 304 | 283 | const char *br_version() |
| 305 | 284 | { |
| 285 | + static QMutex versionLock; | |
| 286 | + QMutexLocker lock(&versionLock); | |
| 306 | 287 | static QByteArray version = Context::version().toLocal8Bit(); |
| 307 | 288 | return version.data(); |
| 308 | 289 | } |
| ... | ... | @@ -380,11 +361,9 @@ bool br_img_is_empty(br_template tmpl) |
| 380 | 361 | return t->m().empty(); |
| 381 | 362 | } |
| 382 | 363 | |
| 383 | -const char* br_get_filename(br_template tmpl) | |
| 364 | +int br_get_filename(char * buffer, int buffer_length, br_template tmpl) | |
| 384 | 365 | { |
| 385 | - static QByteArray buffer; | |
| 386 | - buffer = reinterpret_cast<Template*>(tmpl)->file.name.toLocal8Bit(); | |
| 387 | - return buffer.data(); | |
| 366 | + return partialCopy(reinterpret_cast<Template*>(tmpl)->file.name, buffer, buffer_length); | |
| 388 | 367 | } |
| 389 | 368 | |
| 390 | 369 | void br_set_filename(br_template tmpl, const char *filename) |
| ... | ... | @@ -393,15 +372,11 @@ void br_set_filename(br_template tmpl, const char *filename) |
| 393 | 372 | t->file.name = filename; |
| 394 | 373 | } |
| 395 | 374 | |
| 396 | -const char* br_get_metadata_string(br_template tmpl, const char *key) | |
| 375 | +int br_get_metadata_string(char * buffer, int buffer_length, br_template tmpl, const char *key) | |
| 397 | 376 | { |
| 398 | 377 | Template *t = reinterpret_cast<Template*>(tmpl); |
| 399 | - // need an object outside of this scope | |
| 400 | - // so the char pointer is valid | |
| 401 | - static QByteArray result; | |
| 402 | 378 | QVariant qvar = t->file.value(key); |
| 403 | - result = QtUtils::toString(qvar).toUtf8(); | |
| 404 | - return result.data(); | |
| 379 | + return partialCopy(QtUtils::toString(qvar), buffer, buffer_length); | |
| 405 | 380 | } |
| 406 | 381 | |
| 407 | 382 | br_template_list br_enroll_template(br_template tmpl) | ... | ... |
openbr/openbr.h
| ... | ... | @@ -41,6 +41,10 @@ extern "C" { |
| 41 | 41 | * \section managed_return_value Managed Return Value |
| 42 | 42 | * Memory for <tt>const char*</tt> return values is managed internally and guaranteed until the next call to the function. |
| 43 | 43 | * |
| 44 | + * \section input_string_buffer Input String Buffer | |
| 45 | + * Users should input a char * buffer and the size of that buffer. String data will be copied into the buffer, if the buffer is too | |
| 46 | + * small, only part of the string will be copied. Returns the buffer size required to contain the complete string. | |
| 47 | + * | |
| 44 | 48 | * \section examples Examples |
| 45 | 49 | * - \ref c_face_recognition_evaluation |
| 46 | 50 | * |
| ... | ... | @@ -56,7 +60,6 @@ extern "C" { |
| 56 | 60 | |
| 57 | 61 | /*! |
| 58 | 62 | * \brief Wraps br::Context::about() |
| 59 | - * \note \ref managed_return_value | |
| 60 | 63 | * \see br_version |
| 61 | 64 | */ |
| 62 | 65 | BR_EXPORT const char *br_about(); |
| ... | ... | @@ -256,10 +259,10 @@ BR_EXPORT void br_make_pairwise_mask(const char *target_input, const char *query |
| 256 | 259 | |
| 257 | 260 | /*! |
| 258 | 261 | * \brief Returns the most recent line sent to stderr. |
| 259 | - * \note \ref managed_return_value | |
| 262 | + * \note \ref input_string_buffer | |
| 260 | 263 | * \see br_progress br_time_remaining |
| 261 | 264 | */ |
| 262 | -BR_EXPORT const char *br_most_recent_message(); | |
| 265 | +BR_EXPORT int br_most_recent_message(char * buffer, int buffer_length); | |
| 263 | 266 | |
| 264 | 267 | /*! |
| 265 | 268 | * \brief Returns names and parameters for the requested objects. |
| ... | ... | @@ -268,10 +271,10 @@ BR_EXPORT const char *br_most_recent_message(); |
| 268 | 271 | * \param abstractions Regular expression of the abstractions to search. |
| 269 | 272 | * \param implementations Regular expression of the implementations to search. |
| 270 | 273 | * \param parameters Include parameters after object name. |
| 271 | - * \note \ref managed_return_value | |
| 274 | + * \note \ref input_string_buffer | |
| 272 | 275 | * \note This function uses Qt's <a href="http://doc.qt.digia.com/stable/qregexp.html">QRegExp</a> syntax. |
| 273 | 276 | */ |
| 274 | -BR_EXPORT const char *br_objects(const char *abstractions = ".*", const char *implementations = ".*", bool parameters = true); | |
| 277 | +BR_EXPORT int br_objects(char * buffer, int buffer_length, const char *abstractions = ".*", const char *implementations = ".*", bool parameters = true); | |
| 275 | 278 | |
| 276 | 279 | /*! |
| 277 | 280 | * \brief Renders recognition performance figures for a set of <tt>.csv</tt> files created by \ref br_eval. |
| ... | ... | @@ -376,14 +379,14 @@ BR_EXPORT void br_read_pipe(const char *pipe, int *argc, char ***argv); |
| 376 | 379 | |
| 377 | 380 | /*! |
| 378 | 381 | * \brief Wraps br::Context::scratchPath() |
| 379 | - * \note \ref managed_return_value | |
| 382 | + * \note \ref input_string_buffer | |
| 380 | 383 | * \see br_version |
| 381 | 384 | */ |
| 382 | -BR_EXPORT const char *br_scratch_path(); | |
| 385 | +BR_EXPORT int br_scratch_path(char * buffer, int buffer_length); | |
| 386 | + | |
| 383 | 387 | |
| 384 | 388 | /*! |
| 385 | 389 | * \brief Returns the full path to the root of the SDK. |
| 386 | - * \note \ref managed_return_value | |
| 387 | 390 | * \see br_initialize |
| 388 | 391 | */ |
| 389 | 392 | BR_EXPORT const char *br_sdk_path(); |
| ... | ... | @@ -436,7 +439,6 @@ BR_EXPORT void br_train_n(int num_inputs, const char *inputs[], const char *mode |
| 436 | 439 | |
| 437 | 440 | /*! |
| 438 | 441 | * \brief Wraps br::Context::version() |
| 439 | - * \note \ref managed_return_value | |
| 440 | 442 | * \see br_about br_scratch_path |
| 441 | 443 | */ |
| 442 | 444 | BR_EXPORT const char *br_version(); |
| ... | ... | @@ -508,16 +510,18 @@ BR_EXPORT int br_img_channels(br_template tmpl); |
| 508 | 510 | BR_EXPORT bool br_img_is_empty(br_template tmpl); |
| 509 | 511 | /*! |
| 510 | 512 | * \brief Get the filename for a br::Template |
| 513 | + * \note \ref input_string_buffer | |
| 511 | 514 | */ |
| 512 | -BR_EXPORT const char* br_get_filename(br_template tmpl); | |
| 515 | +BR_EXPORT int br_get_filename(char * buffer, int buffer_length, br_template tmpl); | |
| 513 | 516 | /*! |
| 514 | 517 | * \brief Set the filename for a br::Template. |
| 515 | 518 | */ |
| 516 | 519 | BR_EXPORT void br_set_filename(br_template tmpl, const char *filename); |
| 517 | 520 | /*! |
| 518 | 521 | * \brief Get metadata as a string for the given key in the given template. |
| 522 | + * \note \ref input_string_buffer | |
| 519 | 523 | */ |
| 520 | -BR_EXPORT const char* br_get_metadata_string(br_template, const char *key); | |
| 524 | +BR_EXPORT int br_get_metadata_string(char * buffer, int buffer_length, br_template tmpl, const char *key); | |
| 521 | 525 | /*! |
| 522 | 526 | * \brief Enroll a br::Template from the C API! Returns a pointer to a br::TemplateList |
| 523 | 527 | * \param tmpl Pointer to a br::Template. | ... | ... |
openbr/openbr_plugin.cpp
| ... | ... | @@ -203,6 +203,13 @@ QList<QRectF> File::namedRects() const |
| 203 | 203 | const QVariant &variant = m_metadata[key]; |
| 204 | 204 | if (variant.canConvert<QRectF>()) |
| 205 | 205 | rects.append(variant.value<QRectF>()); |
| 206 | + else if(variant.canConvert<QList<QRectF> >()) { | |
| 207 | + QList<QRectF> list = variant.value<QList<QRectF> >(); | |
| 208 | + for (int i=0;i < list.size();i++) | |
| 209 | + { | |
| 210 | + rects.append(list[i]); | |
| 211 | + } | |
| 212 | + } | |
| 206 | 213 | } |
| 207 | 214 | return rects; |
| 208 | 215 | } |
| ... | ... | @@ -1009,6 +1016,47 @@ QString br::Context::scratchPath() |
| 1009 | 1016 | return QString("%1/%2-%3.%4").arg(QDir::homePath(), PRODUCT_NAME, QString::number(PRODUCT_VERSION_MAJOR), QString::number(PRODUCT_VERSION_MINOR)); |
| 1010 | 1017 | } |
| 1011 | 1018 | |
| 1019 | + | |
| 1020 | +QStringList br::Context::objects(const char *abstractions, const char *implementations, bool parameters) | |
| 1021 | +{ | |
| 1022 | + QStringList objectList; | |
| 1023 | + QRegExp abstractionsRegExp(abstractions); | |
| 1024 | + QRegExp implementationsRegExp(implementations); | |
| 1025 | + | |
| 1026 | + if (abstractionsRegExp.exactMatch("Abbreviation")) | |
| 1027 | + foreach (const QString &name, Globals->abbreviations.keys()) | |
| 1028 | + if (implementationsRegExp.exactMatch(name)) | |
| 1029 | + objectList.append(name + (parameters ? "\t" + Globals->abbreviations[name] : "")); | |
| 1030 | + | |
| 1031 | + if (abstractionsRegExp.exactMatch("Distance")) | |
| 1032 | + foreach (const QString &name, Factory<Distance>::names()) | |
| 1033 | + if (implementationsRegExp.exactMatch(name)) | |
| 1034 | + objectList.append(name + (parameters ? "\t" + Factory<Distance>::parameters(name) : "")); | |
| 1035 | + | |
| 1036 | + if (abstractionsRegExp.exactMatch("Format")) | |
| 1037 | + foreach (const QString &name, Factory<Format>::names()) | |
| 1038 | + if (implementationsRegExp.exactMatch(name)) | |
| 1039 | + objectList.append(name + (parameters ? "\t" + Factory<Format>::parameters(name) : "")); | |
| 1040 | + | |
| 1041 | + if (abstractionsRegExp.exactMatch("Initializer")) | |
| 1042 | + foreach (const QString &name, Factory<Initializer>::names()) | |
| 1043 | + if (implementationsRegExp.exactMatch(name)) | |
| 1044 | + objectList.append(name + (parameters ? "\t" + Factory<Initializer>::parameters(name) : "")); | |
| 1045 | + | |
| 1046 | + if (abstractionsRegExp.exactMatch("Output")) | |
| 1047 | + foreach (const QString &name, Factory<Output>::names()) | |
| 1048 | + if (implementationsRegExp.exactMatch(name)) | |
| 1049 | + objectList.append(name + (parameters ? "\t" + Factory<Output>::parameters(name) : "")); | |
| 1050 | + | |
| 1051 | + if (abstractionsRegExp.exactMatch("Transform")) | |
| 1052 | + foreach (const QString &name, Factory<Transform>::names()) | |
| 1053 | + if (implementationsRegExp.exactMatch(name)) | |
| 1054 | + objectList.append(name + (parameters ? "\t" + Factory<Transform>::parameters(name) : "")); | |
| 1055 | + | |
| 1056 | + | |
| 1057 | + return objectList; | |
| 1058 | +} | |
| 1059 | + | |
| 1012 | 1060 | void br::Context::messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) |
| 1013 | 1061 | { |
| 1014 | 1062 | // Something about this method is not thread safe, and will lead to crashes if qDebug | ... | ... |
openbr/openbr_plugin.h
| ... | ... | @@ -830,6 +830,18 @@ public: |
| 830 | 830 | */ |
| 831 | 831 | static QString scratchPath(); |
| 832 | 832 | |
| 833 | + /*! | |
| 834 | + * \brief Returns names and parameters for the requested objects. | |
| 835 | + * | |
| 836 | + * Each object is \c \\n seperated. Arguments are seperated from the object name with a \c \\t. | |
| 837 | + * \param abstractions Regular expression of the abstractions to search. | |
| 838 | + * \param implementations Regular expression of the implementations to search. | |
| 839 | + * \param parameters Include parameters after object name. | |
| 840 | + * \note \ref managed_return_value | |
| 841 | + * \note This function uses Qt's <a href="http://doc.qt.digia.com/stable/qregexp.html">QRegExp</a> syntax. | |
| 842 | + */ | |
| 843 | + static QStringList objects(const char *abstractions = ".*", const char *implementations = ".*", bool parameters = true); | |
| 844 | + | |
| 833 | 845 | private: |
| 834 | 846 | static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); |
| 835 | 847 | }; | ... | ... |
scripts/brpy/__init__.py
| ... | ... | @@ -12,6 +12,14 @@ def _var_string_args(n): |
| 12 | 12 | s.extend(_string_args(n)) |
| 13 | 13 | return s |
| 14 | 14 | |
| 15 | +def _handle_string_func(func): | |
| 16 | + def call_func(*args): | |
| 17 | + howlong = func('', 0, *args) | |
| 18 | + msg = 'x'*(howlong-1) | |
| 19 | + func(msg, howlong, *args) | |
| 20 | + return msg | |
| 21 | + return call_func | |
| 22 | + | |
| 15 | 23 | def init_brpy(br_loc='/usr/local/lib'): |
| 16 | 24 | """Takes the ctypes lib object for br and initializes all function inputs and outputs""" |
| 17 | 25 | br_loc += '/libopenbr.%s' |
| ... | ... | @@ -48,9 +56,14 @@ def init_brpy(br_loc='/usr/local/lib'): |
| 48 | 56 | br.br_is_classifier.restype = c_bool |
| 49 | 57 | br.br_make_mask.argtypes = _string_args(3) |
| 50 | 58 | br.br_make_pairwise_mask.argtypes = _string_args(3) |
| 51 | - br.br_most_recent_message.restype = c_char_p | |
| 52 | - br.br_objects.argtypes = _string_args(2) + [c_bool] | |
| 53 | - br.br_objects.restype = c_char_p | |
| 59 | + br.br_most_recent_message.argtypes = [c_char_p, c_int] | |
| 60 | + br.br_most_recent_message.restype = c_int | |
| 61 | + func = br.br_most_recent_message.__call__ | |
| 62 | + br.br_most_recent_message = _handle_string_func(func) | |
| 63 | + br.br_objects.argtypes = [c_char_p, c_int] + _string_args(2) + [c_bool] | |
| 64 | + br.br_objects.restype = c_int | |
| 65 | + func2 = br.br_objects.__call__ | |
| 66 | + br.br_objects = _handle_string_func(func2) | |
| 54 | 67 | br.br_plot.argtypes = plot_args |
| 55 | 68 | br.br_plot.restype = c_bool |
| 56 | 69 | br.br_plot_detection.argtypes = plot_args |
| ... | ... | @@ -61,7 +74,10 @@ def init_brpy(br_loc='/usr/local/lib'): |
| 61 | 74 | br.br_plot_metadata.restype = c_bool |
| 62 | 75 | br.br_progress.restype = c_float |
| 63 | 76 | br.br_read_pipe.argtypes = [c_char_p, POINTER(c_int), POINTER(POINTER(c_char_p))] |
| 64 | - br.br_scratch_path.restype = c_char_p | |
| 77 | + br.br_scratch_path.argtypes = [c_char_p, c_int] | |
| 78 | + br.br_scratch_path.restype = c_int | |
| 79 | + func3 = br.br_scratch_path.__call__ | |
| 80 | + br.br_scratch_path = _handle_string_func(func3) | |
| 65 | 81 | br.br_sdk_path.restype = c_char_p |
| 66 | 82 | br.br_get_header.argtypes = [c_char_p, POINTER(c_char_p), POINTER(c_char_p)] |
| 67 | 83 | br.br_set_header.argtypes = _string_args(3) |
| ... | ... | @@ -88,11 +104,15 @@ def init_brpy(br_loc='/usr/local/lib'): |
| 88 | 104 | br.br_img_channels.restype = c_int |
| 89 | 105 | br.br_img_is_empty.argtypes = [c_void_p] |
| 90 | 106 | br.br_img_is_empty.restype = c_bool |
| 91 | - br.br_get_filename.argtypes = [c_void_p] | |
| 92 | - br.br_get_filename.restype = c_char_p | |
| 107 | + br.br_get_filename.argtypes = [c_char_p, c_int, c_void_p] | |
| 108 | + br.br_get_filename.restype = c_int | |
| 109 | + func4 = br.br_get_filename.__call__ | |
| 110 | + br.br_get_filename = _handle_string_func(func4) | |
| 93 | 111 | br.br_set_filename.argtypes = [c_void_p, c_char_p] |
| 94 | - br.br_get_metadata_string.argtypes = [c_void_p, c_char_p] | |
| 95 | - br.br_get_metadata_string.restype = c_char_p | |
| 112 | + br.br_get_metadata_string.argtypes = [c_char_p, c_int, c_void_p, c_char_p] | |
| 113 | + br.br_get_metadata_string.restype = c_int | |
| 114 | + func5 = br.br_get_metadata_string.__call__ | |
| 115 | + br.br_get_metadata_string = _handle_string_func(func5) | |
| 96 | 116 | br.br_enroll_template.argtypes = [c_void_p] |
| 97 | 117 | br.br_enroll_template.restype = c_void_p |
| 98 | 118 | br.br_enroll_template_list.argtypes = [c_void_p] | ... | ... |