|
35 | 35 | namespace pcsc_cpp |
36 | 36 | { |
37 | 37 |
|
38 | | -inline std::string buildErrorMessage(const char* callerFunctionName, const char* scardFunctionName, |
39 | | - const LONG result, const char* file, int line) |
| 38 | +template <auto Func, typename... Args> |
| 39 | +inline void SCardCall(const char* callerFunctionName, const char* file, int line, |
| 40 | + const char* scardFunctionName, Args&&... args) |
40 | 41 | { |
41 | | - return std::string(scardFunctionName) + " returned " + int2hexstr(result) + " in " |
42 | | - + removeAbsolutePathPrefix(file) + ':' + std::to_string(line) + ':' + callerFunctionName; |
43 | | -} |
44 | | - |
45 | | -template <typename Func, typename... Args> |
46 | | -void SCardCall(const char* callerFunctionName, const char* file, int line, |
47 | | - const char* scardFunctionName, Func scardFunction, Args... args) |
48 | | -{ |
49 | | - // TODO: Add logging - or is exception error message enough? |
50 | | - |
51 | | - const LONG result = scardFunction(args...); |
| 42 | + const LONG result = Func(std::forward<Args>(args)...); |
| 43 | + auto buildErrorMessage = [&] { |
| 44 | + return std::string(scardFunctionName) + " returned " + int2hexstr(result) + " in " |
| 45 | + + removeAbsolutePathPrefix(file) + ':' + std::to_string(line) + ':' |
| 46 | + + callerFunctionName; |
| 47 | + }; |
52 | 48 |
|
53 | | - // TODO: Add more cases when needed. |
54 | 49 | switch (result) { |
55 | 50 | case SCARD_S_SUCCESS: |
56 | 51 | return; |
57 | 52 | case LONG(SCARD_E_NO_SERVICE): |
58 | 53 | case LONG(SCARD_E_SERVICE_STOPPED): |
59 | | - throw ScardServiceNotRunningError( |
60 | | - buildErrorMessage(callerFunctionName, scardFunctionName, result, file, line)); |
| 54 | + throw ScardServiceNotRunningError(buildErrorMessage()); |
61 | 55 | case LONG(SCARD_E_NO_READERS_AVAILABLE): |
62 | 56 | case LONG(SCARD_E_READER_UNAVAILABLE): |
63 | | - throw ScardNoReadersError( |
64 | | - buildErrorMessage(callerFunctionName, scardFunctionName, result, file, line)); |
| 57 | + throw ScardNoReadersError(buildErrorMessage()); |
65 | 58 | case LONG(SCARD_E_NO_SMARTCARD): |
66 | 59 | #ifdef _WIN32 |
67 | 60 | case ERROR_NO_MEDIA_IN_DRIVE: |
68 | 61 | #endif // _WIN32 |
69 | | - throw ScardNoCardError( |
70 | | - buildErrorMessage(callerFunctionName, scardFunctionName, result, file, line)); |
| 62 | + throw ScardNoCardError(buildErrorMessage()); |
71 | 63 | case LONG(SCARD_E_NOT_READY): |
72 | 64 | case LONG(SCARD_E_INVALID_VALUE): |
73 | 65 | case LONG(SCARD_E_COMM_DATA_LOST): |
74 | 66 | case LONG(SCARD_W_RESET_CARD): |
75 | 67 | #ifdef _WIN32 |
76 | 68 | case ERROR_IO_DEVICE: |
77 | 69 | #endif // _WIN32 |
78 | | - throw ScardCardCommunicationFailedError( |
79 | | - buildErrorMessage(callerFunctionName, scardFunctionName, result, file, line)); |
| 70 | + throw ScardCardCommunicationFailedError(buildErrorMessage()); |
80 | 71 | case LONG(SCARD_W_REMOVED_CARD): |
81 | | - throw ScardCardRemovedError( |
82 | | - buildErrorMessage(callerFunctionName, scardFunctionName, result, file, line)); |
| 72 | + throw ScardCardRemovedError(buildErrorMessage()); |
83 | 73 | case LONG(SCARD_E_NOT_TRANSACTED): |
84 | | - throw ScardTransactionFailedError( |
85 | | - buildErrorMessage(callerFunctionName, scardFunctionName, result, file, line)); |
| 74 | + throw ScardTransactionFailedError(buildErrorMessage()); |
86 | 75 | default: |
87 | | - throw ScardError( |
88 | | - buildErrorMessage(callerFunctionName, scardFunctionName, result, file, line)); |
| 76 | + throw ScardError(buildErrorMessage()); |
89 | 77 | } |
90 | 78 | } |
91 | 79 |
|
92 | 80 | } // namespace pcsc_cpp |
93 | 81 |
|
94 | 82 | #define SCard(APIFunctionName, ...) \ |
95 | | - SCardCall(__FUNCTION__, __FILE__, __LINE__, "SCard" #APIFunctionName, SCard##APIFunctionName, \ |
96 | | - __VA_ARGS__) |
| 83 | + SCardCall<SCard##APIFunctionName>(__FUNCTION__, __FILE__, __LINE__, "SCard" #APIFunctionName, \ |
| 84 | + __VA_ARGS__) |
0 commit comments