aboutsummaryrefslogtreecommitdiff
path: root/NK_C_API_helpers.h
blob: c5241be7e44d6f8bdb61fbee8d1ab9886c1088a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef LIBNITROKEY_NK_C_API_HELPERS_H
#define LIBNITROKEY_NK_C_API_HELPERS_H


#include "NK_C_API.h"
#include <iostream>
#include <tuple>
#include "libnitrokey/NitrokeyManager.h"
#include <cstring>
#include "libnitrokey/LibraryException.h"
#include "libnitrokey/cxx_semantics.h"
#include "libnitrokey/stick20_commands.h"
#include "libnitrokey/device_proto.h"
#include "libnitrokey/version.h"

void clear_string(std::string &s);

extern uint8_t NK_last_command_status;


template <typename T>
T* duplicate_vector_and_clear(std::vector<T> &v){
  auto d = new T[v.size()];
  std::copy(v.begin(), v.end(), d);
  std::fill(v.begin(), v.end(), 0);
  return d;
}

template <typename R, typename T>
std::tuple<int, R> get_with_status(T func, R fallback) {
  NK_last_command_status = 0;
  try {
    return std::make_tuple(0, 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 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){
  auto result = std::get<1>(get_with_status<char*>(func, nullptr));
  if (result == nullptr) {
    return strndup("", MAXIMUM_STR_REPLY_LENGTH);
  }
  return result;
}

template <typename T>
auto get_with_result(T func){
  return std::get<1>(get_with_status(func, static_cast<decltype(func())>(0)));
}

template <typename T>
uint8_t get_without_result(T func){
  NK_last_command_status = 0;
  try {
    func();
    return 0;
  }
  catch (CommandFailedException & commandFailedException){
    NK_last_command_status = commandFailedException.last_command_status;
  }
  catch (LibraryException & libraryException){
    NK_last_command_status = libraryException.exception_id();
  }
  catch (const InvalidCRCReceived &invalidCRCException){
    ;
  }
  catch (const DeviceCommunicationException &deviceException){
    NK_last_command_status = 256-deviceException.getType();
  }
  return NK_last_command_status;
}


#endif // LIBNITROKEY_NK_C_API_HELPERS_H