Developer Application Interface (ARC API) v3.6.2
ARC, Inc. GenII/III Application Interface
CArcBase.h
1// +------------------------------------------------------------------------------------------------------------------+
2// | FILE: ArcBase.h ( Gen3 ) |
3// +------------------------------------------------------------------------------------------------------------------+
4// | PURPOSE: This file defines the ARC base class. |
5// | |
6// | AUTHOR: Scott Streit DATE: March 25, 2020 |
7// | |
8// | Copyright 2013 Astronomical Research Cameras, Inc. All rights reserved. |
9// +------------------------------------------------------------------------------------------------------------------+
10
11#ifndef _CARCBASE_H_
12#define _CARCBASE_H_
13
14#ifdef _WINDOWS
15 #include <windows.h>
16#else
17 #include <cstring>
18#endif
19
20#include <type_traits>
21#include <stdexcept>
22#include <string>
23#include <sstream>
24#include <cstdint>
25#include <cstdarg>
26
27#include <CArcBaseDllMain.h>
28#include <CArcStringList.h>
29
30
31
32namespace arc
33{
34 namespace gen3
35 {
36
37 // +----------------------------------------------------------------------------------------------------------+
38 // | Macro - throwArcGen3Error |
39 // +----------------------------------------------------------------------------------------------------------+
40 // | Convenience to auto fill class::method name |
41 // +----------------------------------------------------------------------------------------------------------+
42
46 #define throwArcGen3Error( ... ) arc::gen3::CArcBase::throwException<std::runtime_error>( __FUNCTION__, __LINE__, __VA_ARGS__ )
47
48 #define throwArcGen3InvalidArgument( ... ) arc::gen3::CArcBase::throwException<std::invalid_argument>( __FUNCTION__, __LINE__, __VA_ARGS__ )
49
50 #define throwArcGen3OutOfRange( ... ) arc::gen3::CArcBase::throwOutOfRange( __FUNCTION__, __LINE__, __VA_ARGS__ )
51
52 #define throwArcGen3LengthError( ... ) arc::gen3::CArcBase::throwException<std::length_error>( __FUNCTION__, __LINE__, __VA_ARGS__ )
53
54 #define throwArcGen3NoDeviceError() arc::gen3::CArcBase::throwNoDeviceError( __FUNCTION__, __LINE__ )
55
56
57 // +----------------------------------------------------------------------------------------------------------+
58 // | CArcBase Class |
59 // +----------------------------------------------------------------------------------------------------------+
60
66 class GEN3_CARCBASE_API CArcBase
67 {
68 public:
69
73 static const std::string version( void );
74
75
81 static void zeroMemory( void* pDest, const std::size_t uiSize );
82
83
90 static void copyMemory( void* pDest, void* pSrc, const std::size_t uiSize );
91
92
100 static void throwOutOfRange( const std::string& sMethodName, const std::int32_t iLine, const std::uint32_t uiElement, std::pair<std::uint32_t, std::uint32_t> range );
101
102
110 static void throwOutOfRange( const std::string& sMethodName, const std::int32_t iLine, const std::string& sElement, const std::size_t uiSize );
111
112
119 static void throwNoDeviceError( const std::string& sMethodName, const std::int32_t iLine, const std::string& sMsg = "" );
120
121
128 template <typename T = std::runtime_error>
129 static void throwException( const std::string& sMethodName, const std::int32_t iLine, const std::string& sMsg )
130 {
131 std::ostringstream oss;
132
133 oss << sMsg << "\nTrace: ( " << sMethodName << "() line: " << iLine << " )" << std::ends;
134
135 throw T( oss.str() );
136 }
137
138
159 template <typename T = std::runtime_error>
160 static void throwException( const std::string& sMethodName, const std::int32_t iLine, const char* pszFmt, ... )
161 {
162 std::ostringstream oss;
163 char* pzChar;
164 char* pszVal;
165
166 va_list ap;
167
168 va_start( ap, pszFmt );
169
170 for ( pzChar = (char* )pszFmt; *pzChar; pzChar++ )
171 {
172 if ( *pzChar != '%' )
173 {
174 oss << *pzChar;
175 continue;
176 }
177
178 switch ( *++pzChar )
179 {
180 case 'd':
181 {
182 oss << va_arg( ap, int );
183 }
184 break;
185
186 case 'u':
187 {
188 oss << va_arg( ap, unsigned int );
189 }
190 break;
191
192 case 'l':
193 {
194 oss << va_arg( ap, long );
195 }
196 break;
197
198 case 'j':
199 {
200 oss << va_arg( ap, unsigned long );
201 }
202 break;
203
204 case 'J':
205 {
206 oss << va_arg( ap, unsigned long long );
207 }
208 break;
209
210 case 'f':
211 {
212 oss << va_arg( ap, double );
213 }
214 break;
215
216 case 's':
217 {
218 for ( pszVal = va_arg( ap, char* ); *pszVal; pszVal++ )
219 {
220 oss << *pszVal;
221 }
222 }
223 break;
224
225 case 'e':
226 {
227 #ifdef _WINDOWS
228 oss << CArcBase::getSystemMessage( va_arg( ap, std::uint32_t ) );
229 #else
230 oss << CArcBase::getSystemMessage( va_arg( ap, std::int32_t ) );
231 #endif
232 }
233 break;
234
235 case 'X':
236 case 'x':
237 {
238 oss << std::uppercase << std::hex << va_arg( ap, unsigned int ) << std::dec;
239 }
240 break;
241
242 case 'b':
243 {
244 oss << std::boolalpha << ( va_arg( ap, int ) > 0 ? true : false );
245 }
246 break;
247
248 case 'p':
249 {
250 oss << std::uppercase << std::showbase << std::hex << va_arg( ap, std::uint64_t ) << std::dec;
251 }
252 break;
253
254 default:
255 {
256 oss << *pzChar;
257 }
258 break;
259 }
260 }
261 va_end( ap );
262
263 throwException<T>( sMethodName, iLine, oss.str() );
264 }
265
266
271 template<typename ErrCode>
272 static const std::string getSystemMessage( ErrCode iCode ) requires std::is_integral_v<ErrCode>
273 {
274 #ifdef _WINDOWS
275 std::ostringstream oss;
276 std::string sMsg;
277
278 LPTSTR lpBuffer;
279
280 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
281 NULL,
282 ( DWORD )iCode,
283 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
284 ( LPTSTR )&lpBuffer,
285 0,
286 NULL );
287
288 char szBuffer[ 1024 ] = { '\0' };
289
290 std::int32_t iBytes = WideCharToMultiByte( CP_ACP,
291 0,
292 reinterpret_cast< LPWSTR >( lpBuffer ),
293 -1,
294 szBuffer,
295 sizeof( szBuffer ),
296 NULL,
297 NULL );
298
299 if (iBytes > 0)
300 {
301 oss << szBuffer;
302 }
303
304 LocalFree( lpBuffer );
305
306 #else
307
308 std::ostringstream oss;
309 std::string sMsg;
310
311 if ( iCode != -1 )
312 {
313 oss << "( errno: " << iCode << " ) - " << strerror( iCode );
314 }
315
316 //
317 // Remove and return characters '\r' or '\n' at the end of the string.
318 //
319 sMsg = oss.str();
320
321 if (sMsg.back() == '\n' || sMsg.back() == '\r')
322 {
323 sMsg.erase( sMsg.end() - 1, sMsg.end() );
324 }
325
326 #endif
327
328 //
329 // Remove and return characters '\r' or '\n' at the end of the string.
330 //
331 sMsg = oss.str();
332
333 if ( sMsg.back() == '\n' || sMsg.back() == '\r' )
334 {
335 sMsg.erase( sMsg.end() - 1, sMsg.end() );
336 }
337
338 return sMsg;
339 }
340
341
345 #ifdef _WINDOWS
346 static std::uint32_t getSystemError( void ) noexcept
347 {
348 return static_cast< std::uint32_t >( ::GetLastError() );
349 }
350 #else
351 static std::int32_t getSystemError( void ) noexcept
352 {
353 return static_cast< std::int32_t >( errno );
354 }
355 #endif
356
357
364 static std::unique_ptr<CArcStringList> splitString( const std::string& sString, const char& zDelim = ' ' );
365
366
384 static std::string formatString( const char* pszFmt, ... );
385
386
391 static std::string convertWideToAnsi( wchar_t wzString[] ) noexcept;
392
393
398 static std::string convertWideToAnsi( const std::wstring& wsString );
399
400
405 static std::wstring convertAnsiToWide( const char* pszString );
406
407
416 static std::string cmdToString( const std::uint32_t uiCmd );
417
418
428 static std::string cmdToString( const std::uint32_t uiReply, const std::initializer_list<std::uint32_t>& tCmdList );
429
430
439 static std::string setDots( std::string_view svText, const std::size_t uiMaxLength, const char szDot = '.' );
440
441
455 template <typename T> static std::string iterToString( T* pBegin, T* pEnd, char zSeperator = ' ' )
456 {
457 std::ostringstream oss;
458
459 if ( pBegin != nullptr )
460 {
461 if ( pEnd != nullptr )
462 {
463 while ( pBegin != pEnd )
464 {
465 oss << cmdToString( *pBegin++ ) << zSeperator;
466 }
467 }
468
469 else
470 {
471 throwArcGen3Error( "Invalid \"end\" parameter ( nullptr )." );
472 }
473 }
474
475 else
476 {
477 throwArcGen3Error( "Invalid \"begin\" parameter ( nullptr )." );
478 }
479
480 return oss.str();
481 }
482
483
485 virtual ~CArcBase( void );
486
487 protected:
488
490 CArcBase( void ) = default;
491
493 CArcBase( const CArcBase& ) = delete;
494
496 CArcBase( CArcBase&& ) = delete;
497
499 CArcBase& operator=( const CArcBase& ) = delete;
500
503
505 static const std::string m_sVersion;
506
507 };
508
509
510 } // pEnd gen3 namespace
511} // pEnd arc namespace
512
513
514#endif // _CARCBASE_H_
Definition: CArcBase.h:67
static std::int32_t getSystemError(void) noexcept
Definition: CArcBase.h:351
static const std::string m_sVersion
Definition: CArcBase.h:505
CArcBase & operator=(CArcBase &&)=delete
static std::string iterToString(T *pBegin, T *pEnd, char zSeperator=' ')
Definition: CArcBase.h:455
CArcBase(const CArcBase &)=delete
CArcBase & operator=(const CArcBase &)=delete
static const std::string getSystemMessage(ErrCode iCode)
Definition: CArcBase.h:272
CArcBase(void)=default
static void throwException(const std::string &sMethodName, const std::int32_t iLine, const char *pszFmt,...)
Definition: CArcBase.h:160
static void throwException(const std::string &sMethodName, const std::int32_t iLine, const std::string &sMsg)
Definition: CArcBase.h:129
CArcBase(CArcBase &&)=delete