summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <me@robin-krahl.de>2018-05-25 12:00:21 +0200
committerRobin Krahl <me@robin-krahl.de>2018-05-25 12:04:11 +0200
commitf6e09cc2fb4541a15a57415439b575d7bf44b07f (patch)
tree1f5087f54e054797ac2ae3bdb9a072854347d188
parentaee920b21d3951d2166ff73a533461e1bdd16e7f (diff)
downloadlibnitrokey-f6e09cc2fb4541a15a57415439b575d7bf44b07f.tar.gz
libnitrokey-f6e09cc2fb4541a15a57415439b575d7bf44b07f.tar.bz2
Refactor result retrieval in C API
The result retrieval functions get_with_array_result, get_with_string_result, get_with_result and get_without_result currently contain much duplicated code: the error handling. This patch tries to simplify this code by introducing a new function, get_with_status, that executes a function, catches errors and returns the error code together with the result of the function or a fallback value passed by the user if the function failed. get_with_array_result, get_with_string_result and get_with_result are adapted to use this function. get_without_result is not changed as it has a different error handling logic than the other functions: It ignores any InvalidCRCReceived exceptions.
-rw-r--r--NK_C_API.cc46
1 files changed, 15 insertions, 31 deletions
diff --git a/NK_C_API.cc b/NK_C_API.cc
index 8e005b8..41c38aa 100644
--- a/NK_C_API.cc
+++ b/NK_C_API.cc
@@ -21,6 +21,7 @@
#include "NK_C_API.h"
#include <iostream>
+#include <tuple>
#include "libnitrokey/NitrokeyManager.h"
#include <cstring>
#include "libnitrokey/LibraryException.h"
@@ -52,11 +53,11 @@ T* duplicate_vector_and_clear(std::vector<T> &v){
return d;
}
-template <typename T>
-uint8_t * get_with_array_result(T func){
+template <typename R, typename T>
+std::tuple<int, R> get_with_status(T func, R fallback) {
NK_last_command_status = 0;
try {
- return func();
+ return std::make_tuple(0, func());
}
catch (CommandFailedException & commandFailedException){
NK_last_command_status = commandFailedException.last_command_status;
@@ -67,43 +68,26 @@ uint8_t * get_with_array_result(T func){
catch (const DeviceCommunicationException &deviceException){
NK_last_command_status = 256-deviceException.getType();
}
- return nullptr;
+ return std::make_tuple(NK_last_command_status, fallback);
+}
+
+template <typename T>
+uint8_t * get_with_array_result(T func){
+ return std::get<1>(get_with_status<uint8_t*>(func, nullptr));
}
template <typename T>
char* get_with_string_result(T func){
- NK_last_command_status = 0;
- try {
- return func();
+ auto result = std::get<1>(get_with_status<char*>(func, nullptr));
+ if (result == nullptr) {
+ return strndup("", MAXIMUM_STR_REPLY_LENGTH);
}
- catch (CommandFailedException & commandFailedException){
- NK_last_command_status = commandFailedException.last_command_status;
- }
- catch (LibraryException & libraryException){
- NK_last_command_status = libraryException.exception_id();
- }
- catch (const DeviceCommunicationException &deviceException){
- NK_last_command_status = 256-deviceException.getType();
- }
- return strndup("", MAXIMUM_STR_REPLY_LENGTH);
+ return result;
}
template <typename T>
auto get_with_result(T func){
- NK_last_command_status = 0;
- try {
- return func();
- }
- catch (CommandFailedException & commandFailedException){
- NK_last_command_status = commandFailedException.last_command_status;
- }
- catch (LibraryException & libraryException){
- NK_last_command_status = libraryException.exception_id();
- }
- catch (const DeviceCommunicationException &deviceException){
- NK_last_command_status = 256-deviceException.getType();
- }
- return static_cast<decltype(func())>(0);
+ return std::get<1>(get_with_status(func, static_cast<decltype(func())>(0)));
}
template <typename T>