mksqlite  2.5
A MATLAB interface to SQLite
typed_blobs.hpp
Go to the documentation of this file.
1 
17 #pragma once
18 
19 //#include "config.h"
20 //#include "global.hpp"
21 #include "utils.hpp"
22 
23 #ifdef _WIN32
24  #define GCC_PACKED_STRUCT
25  #pragma pack(1)
26 #else
27  #define GCC_PACKED_STRUCT __attribute__((packed))
28 #endif
29 
49 #if !defined( MATLAB_MEX_FILE )
50  typedef enum
52  {
53  mxUNKNOWN_CLASS = 0,
54  mxCELL_CLASS,
55  mxSTRUCT_CLASS,
56  mxLOGICAL_CLASS,
57  mxCHAR_CLASS,
58  mxVOID_CLASS,
59  mxDOUBLE_CLASS,
60  mxSINGLE_CLASS,
61  mxINT8_CLASS,
62  mxUINT8_CLASS,
63  mxINT16_CLASS,
64  mxUINT16_CLASS,
65  mxINT32_CLASS,
66  mxUINT32_CLASS,
67  mxINT64_CLASS,
68  mxUINT64_CLASS,
69  mxFUNCTION_CLASS,
70  mxOPAQUE_CLASS,
71  mxOBJECT_CLASS
72  } mxClassID;
73 
74  typedef size_t mwSize;
75 
77  #define mxGetClassID(x) mxUINT8_CLASS
78 #endif
79 
80 
88 #define TBH_MAGIC_MAXLEN 14
89 #define TBH_PLATFORM_MAXLEN 11
90 #define TBH_COMPRID_MAXLEN 12
91 #define TBH_ENDIAN_MAXLEN 2
92 
100 extern const char TBH_MAGIC[];
101 extern char TBH_platform[];
102 extern char TBH_endian[];
103 
106 #ifdef MAIN_MODULE
107 
108 /* Implementations */
109 
110 static int typed_blobs_mode = 0;
111 
112 namespace old_version { int check_compatibility(void); };
113 
122 {
123  mxArray *plhs[3] = {0};
124 
126 
127 #if defined( MATLAB_MEX_FILE)
128  if( 0 == mexCallMATLAB( 3, plhs, 0, NULL, "computer" ) )
129  {
130  mxGetString( plhs[0], TBH_platform, TBH_PLATFORM_MAXLEN );
131  mxGetString( plhs[2], TBH_endian, TBH_ENDIAN_MAXLEN );
132 
133  ::utils_destroy_array( plhs[0] );
134  ::utils_destroy_array( plhs[1] );
135  ::utils_destroy_array( plhs[2] );
136  }
137 #else
138 #endif
140 }
141 
143 void typed_blobs_mode_set( int mode )
144 {
145  typed_blobs_mode = (mode != 0);
146 }
147 
150 {
151  return typed_blobs_mode;
152 }
153 
154 /*static*/ const char TBH_MAGIC[TBH_MAGIC_MAXLEN] = "mkSQLite.tbh\0";
155 /*static*/ char TBH_platform[TBH_PLATFORM_MAXLEN] = {0};
156 /*static*/ char TBH_endian[TBH_ENDIAN_MAXLEN] = {0};
157 
158 #endif
159 
165 struct GCC_PACKED_STRUCT TypedBLOBHeaderBase
166 {
167  char m_magic[TBH_MAGIC_MAXLEN];
168  int16_t m_ver;
169  int32_t m_clsid;
170  char m_platform[TBH_PLATFORM_MAXLEN];
171  char m_endian;
172 
175  void init( mxClassID clsid )
176  {
177  strcpy( m_magic, TBH_MAGIC );
178  strcpy( m_platform, TBH_platform );
179 
180  m_ver = (int16_t)sizeof( *this ); // Header size used as version number
181  m_clsid = (int32_t)clsid; // MATLABs class ID
182  m_endian = TBH_endian[0]; // First letter only ('L'ittle or 'B'ig)
183  }
184 
186  bool validMagic()
187  {
188  return 0 == _strnicmp( m_magic, TBH_MAGIC, TBH_MAGIC_MAXLEN );
189  }
190 
192  static
193  bool validClsid( mxClassID clsid )
194  {
195  switch( clsid )
196  {
197  // standard types can be stored in any typed blob
198  case mxLOGICAL_CLASS:
199  case mxCHAR_CLASS:
200  case mxDOUBLE_CLASS:
201  case mxSINGLE_CLASS:
202  case mxINT8_CLASS:
203  case mxUINT8_CLASS:
204  case mxINT16_CLASS:
205  case mxUINT16_CLASS:
206  case mxINT32_CLASS:
207  case mxUINT32_CLASS:
208  case mxINT64_CLASS:
209  case mxUINT64_CLASS:
210  return true;
211  default:
212  // no other types supported so far
213  return false;
214  }
215  }
216 
217 
219  static
220  bool validClsid( const mxArray* pItem )
221  {
222  return pItem && validClsid( mxGetClassID( pItem ) );
223  }
224 
225 
227  bool validClsid()
228  {
229  return validClsid( (mxClassID)m_clsid );
230  }
231 
232 
235  {
236  return TBH_endian[0] == m_endian && 0 == _strnicmp( TBH_platform, m_platform, TBH_PLATFORM_MAXLEN );
237  }
238 
239 
240 #if defined( MATLAB_MEX_FILE )
241  static
243  size_t getDataSize( const mxArray* pItem )
244  {
245  size_t data_size = 0;
246 
247  if( pItem )
248  {
249  size_t szElement = mxGetElementSize( pItem );
250  size_t cntElements = mxGetNumberOfElements( pItem );
251 
252  data_size = szElement * cntElements;
253  }
254 
255  return data_size;
256  }
257 #endif
258 };
259 
260 
269 struct GCC_PACKED_STRUCT TypedBLOBHeaderCompressed : public TypedBLOBHeaderBase
270 {
272  char m_compression[12];
273 
275  void init( mxClassID clsid )
276  {
277  TypedBLOBHeaderBase::init( clsid );
278  setCompressor( "" );
279  }
280 
282  void setCompressor( const char* strCompressorType )
283  {
284  strncpy( m_compression, strCompressorType, sizeof( m_compression ) );
285  }
286 
288  const char* getCompressor()
289  {
290  return m_compression;
291  }
292 
298  {
299  return 1;
300  }
301 };
302 
303 
313 template< typename HeaderBaseType >
314 struct GCC_PACKED_STRUCT TBHData : public HeaderBaseType
315 {
317  int32_t m_nDims[1];
318 
326  void init( mxClassID clsid, mwSize nDims, const mwSize* pSize )
327  {
328  HeaderBaseType::init( clsid );
329  HeaderBaseType::m_ver = sizeof( *this );
330 
331  assert( nDims >= 0 );
332  assert( !nDims || pSize );
333 
334  m_nDims[0] = nDims;
335  for( int i = 0; i < (int)nDims; i++ )
336  {
337  m_nDims[i+1] = (int32_t)pSize[i];
338  }
339  }
340 
341 
343  void init( const mxArray* pItem )
344  {
345  assert( pItem );
346  mxClassID clsid = mxGetClassID( pItem );
347  mwSize nDims = mxGetNumberOfDimensions( pItem );
348  const mwSize* dimensions = mxGetDimensions( pItem );
349 
350  init( clsid, nDims, dimensions );
351  }
352 
353 
360  bool validVer()
361  {
362  return sizeof(*this) == (size_t)HeaderBaseType::m_ver;
363  }
364 
365 
372  void* getData( mwSize nDims )
373  {
374  return (void*)&m_nDims[ nDims + 1 ];
375  }
376 
377 
379  void* getData()
380  {
381  return getData( m_nDims[0] );
382  }
383 
384 
391  static
392  size_t dataOffset( mwSize nDims )
393  {
394  //return offsetof( TBHData, m_nDims[nDims+1] ); /* doesn't work on linux gcc 4.1.2 */
395  TBHData* p = (TBHData*)1024; // p must be something other than 0, due to compiler checking
396  return (char*)&p->m_nDims[nDims+1] - (char*)p;
397  }
398 
399 
401  size_t dataOffset()
402  {
403  return dataOffset( m_nDims[0] );
404  }
405 
406 
408  size_t getDataSize()
409  {
410  return utils_elbytes( (mxClassID)HeaderBaseType::m_clsid );
411  }
412 
413 
421  mxArray* createNumericArray( bool doCopyData )
422  {
423  mwSize nDims = m_nDims[0];
424  mwSize* dimensions = new mwSize[nDims];
425  mxArray* pItem = NULL;
426  mxClassID clsid = (mxClassID)HeaderBaseType::m_clsid;
427 
428  for( int i = 0; i < (int)nDims; i++ )
429  {
430  dimensions[i] = (mwSize)m_nDims[i+1];
431  }
432 
433  pItem = mxCreateNumericArray( nDims, dimensions, clsid, mxREAL );
434  delete[] dimensions;
435 
436  // copy hosted item data into numeric array
437  if( pItem && doCopyData )
438  {
439  memcpy( mxGetData( pItem ), getData(), TypedBLOBHeaderBase::getDataSize( pItem ) );
440  }
441 
442  return pItem;
443  }
444 
445 private:
455  TBHData();
456  TBHData( const TBHData& );
457  TBHData& operator=( const TBHData& );
460 };
461 
464 
465 
469 namespace old_version {
470  /* Store type and dimensions of MATLAB vectors/arrays in BLOBs */
471  static const char TBH_MAGIC[] = "mkSQLite.tbh";
472  static char TBH_platform[11] = {0};
473  static char TBH_endian[2] = {0};
474 
475  // typed BLOB header agreement
476  // native and free of matlab types, to provide data sharing with other applications
477 
478 #ifdef _WIN32
479 #pragma pack( push )
480 #pragma pack()
481 #endif
482 
484  typedef struct
485  {
486  char magic[sizeof(TBH_MAGIC)];
487  int16_t ver;
488  int32_t clsid;
489  char platform[11];
490  char endian;
491  int32_t sizeDims[1];
492  } TypedBLOBHeader;
494 
495 #ifdef _WIN32
496 #pragma pack( pop )
497 #endif
498 
500 #define TBH_DATA(tbh) ((void*)&tbh->sizeDims[tbh->sizeDims[0]+1])
501 #define TBH_DATA_OFFSET(nDims) ((ptrdiff_t)&((TypedBLOBHeader*) 0)->sizeDims[nDims+1])
503 
506  {
507  TypedBLOBHeaderV1* tbh1 = (TypedBLOBHeaderV1*)1024;
508  TypedBLOBHeader* old_struct = (TypedBLOBHeader*)1024;
509 
510  if( (void*)&tbh1->m_ver == (void*)&old_struct->ver
511  && (void*)&tbh1->m_clsid == (void*)&old_struct->clsid
512  && (void*)&tbh1->m_platform[0] == (void*)&old_struct->platform[0]
513  && (void*)&tbh1->m_endian == (void*)&old_struct->endian
514  && (void*)&tbh1->m_nDims == (void*)&old_struct->sizeDims
516  {
517  return 1;
518  }
519  else
520  {
521  return 0;
522  }
523  }
524 
525 #undef TBH_DATA
526 #undef TBH_DATA_OFFSET
527 };
const char TBH_MAGIC[]
identify string
static size_t getDataSize(const mxArray *pItem)
Get data size of an array in bytes.
typed BLOB header (deprecated)
void init(mxClassID clsid)
Initialize structure with class ID and platform information.
int check_compatibility(void)
Checks for valid header size, platform name, endian type and magic (deprecated)
mxArray * createNumericArray(bool doCopyData)
#define TBH_DATA_OFFSET(nDims)
Get offset from header start to hosted data (deprecated)
2nd version of typed blobs with additional compression feature.
static char TBH_platform[11]
platform name (i.e. "PCWIN") (deprecated)
int32_t m_nDims[1]
Number of dimensions, followed by sizes of each dimension (BLOB data follows after last dimension siz...
int32_t clsid
Matlab ClassID of variable (see mxClassID)
static const char TBH_MAGIC[]
identifying string (magic) (deprecated)
size_t getDataSize()
Get data size in bytes, returns 0 on error.
bool validPlatform()
Check if originate platform equals to running one.
TBHData< TypedBLOBHeaderCompressed > TypedBLOBHeaderV2
typed blob header for MATLAB arrays with compression feature
Utilities used in all files.
size_t utils_elbytes(mxClassID classID)
Get the size of one element in bytes.
Definition: utils.hpp:75
void setCompressor(const char *strCompressorType)
Compressor selection.
bool validVer()
Header version checking.
static char TBH_endian[2]
endian used (&#39;L&#39;ittle or &#39;B&#39;ig) (deprecated)
bool validCompression()
Check for valid compressor.
void init(mxClassID clsid, mwSize nDims, const mwSize *pSize)
Initialization (hides base class init() function)
void typed_blobs_mode_set(int mode)
Set mode of typed blob usage.
char TBH_endian[]
endian (little or big)
bool validClsid()
Check for valid self class ID.
size_t dataOffset()
Get header offset to begin of array data (initialized)
char platform[11]
Computer architecture: PCWIN, PCWIN64, GLNX86, GLNXA64, MACI, MACI64, SOL64.
static bool validClsid(mxClassID clsid)
Check if class id is valid for typed blob (TYBLOB_ARRAYS)
void utils_destroy_array(mxArray *&pmxarr)
Freeing memory allocated by mxCreateNumericMatrix() or mxCreateNumericArray().
Definition: utils.hpp:302
char TBH_platform[]
platform name
Template class extending base class uniquely.
int typed_blobs_mode_on()
Get mode of typed blob usage.
bool validMagic()
Check identifying string (magic)
void * getData()
get a pointer to array data (initialized)
void init(const mxArray *pItem)
Set class ID and dimension information of an array item.
int16_t ver
Struct size as kind of header version number for later backwards compatibility (may increase only!) ...
char endian
Byte order: &#39;L&#39;ittle endian or &#39;B&#39;ig endian.
const char * getCompressor()
Get compressor name.
TBHData< TypedBLOBHeaderBase > TypedBLOBHeaderV1
typed blob header for MATLAB arrays
static bool validClsid(const mxArray *pItem)
Check if class id is valid for typed blob (TYBLOB_ARRAYS)
void * getData(mwSize nDims)
Get pointer to array data (while initializing)
static int typed_blobs_mode
typed blobs are off by default
1st (base) version of typed BLOB header with ability of storing multidimensional MATLAB arrays...
void init(mxClassID clsid)
Initialization.
static size_t dataOffset(mwSize nDims)
Get header offset to begin of array data (while initializing)
void typed_blobs_init()
Initialization.