mksqlite  2.5
A MATLAB interface to SQLite
value.hpp
Go to the documentation of this file.
1 
21 #pragma once
22 
23 //#include "config.h"
24 #include "global.hpp"
25 #include "sqlite/sqlite3.h"
26 #include <string>
27 #include <vector>
28 #include <utility>
29 #include <string>
30 #include <algorithm>
31 #include <memory>
32 
33 using namespace std;
34 
35 #ifdef _MSC_VER
36 #pragma warning( disable: 4521 4522 ) // multiple copy constructors and assignment operators specified
37 #endif
38 
39 class ValueBase;
40 class ValueMex;
41 class ValueSQL;
42 class ValueSQLCol;
43 struct tagNativeArray;
44 
45 
46 #define SQLITE_BLOBX 20
47 
48 HC_ASSERT( sizeof( sqlite3_int64 ) <= sizeof( long long ) );
50 
58 class ValueBase
59 {
60 public:
61  bool m_isConst;
62  union
63  {
64  double m_float;
65  sqlite3_int64 m_integer;
66  char* m_text;
67  mxArray* m_blob;
68  mxArray* m_pcItem;
69  tagNativeArray* m_array;
70 
71  long long m_largest_field;
72  };
73 
76  {
77  // Class ValueBase manages no memory, so when object runs out of scope memory must have been freed
78  // already or be const either.
79  assert( m_isConst || !m_largest_field );
80  }
81 
82 // Only derived classes may create class instances
83 protected:
84 
87  : m_isConst(true),
88  m_largest_field(0)
89  {
90  }
91 
93  ValueBase( const ValueBase& other )
94  {
95  m_isConst = true;
96  *this = other;
97  }
98 
101  {
102  m_isConst = true;
103  *this = other;
104  other.m_isConst = true; // taking ownership
105  }
106 
108  ValueBase( ValueBase&& other )
109  {
110  m_isConst = true;
111  *this = other;
112  other.m_isConst = true; // taking ownership
113  }
114 
116  ValueBase& operator=( const ValueBase& other )
117  {
118  // checking self assignment
119  if( this != &other )
120  {
121  assert( m_isConst || !m_largest_field );
122  m_isConst = true;
123  m_largest_field = other.m_largest_field;
124  }
125 
126  return *this;
127  }
128 
131  {
132  // checking self assignment
133  if( this != &other )
134  {
135  assert( m_isConst || !m_largest_field );
136  m_isConst = other.m_isConst;
137  m_largest_field = other.m_largest_field;
138 
139  other.m_isConst = true; // taking ownership
140  }
141 
142  return *this;
143  }
144 
147  {
148  // checking self assignment
149  if( this != &other )
150  {
151  assert( m_isConst || !m_largest_field );
152  m_isConst = other.m_isConst;
153  m_largest_field = other.m_largest_field;
154 
155  other.m_isConst = true; // taking ownership
156  }
157 
158  return *this;
159  }
160 };
161 
162 
178 class ValueMex : public ValueBase
179 {
180 public:
185  typedef enum {
186  TC_EMPTY = 0,
191  TC_UNSUPP = -1
193 
194  enum {
195  LOGICAL_CLASS = mxLOGICAL_CLASS,
196  INT8_CLASS = mxINT8_CLASS,
197  UINT8_CLASS = mxUINT8_CLASS,
198  INT16_CLASS = mxINT16_CLASS,
199  INT32_CLASS = mxINT32_CLASS,
200  UINT16_CLASS = mxUINT16_CLASS,
201  UINT32_CLASS = mxUINT32_CLASS,
202  INT64_CLASS = mxINT64_CLASS,
203  DOUBLE_CLASS = mxDOUBLE_CLASS,
204  SINGLE_CLASS = mxSINGLE_CLASS,
205  CHAR_CLASS = mxCHAR_CLASS,
206  };
207 
208 
211  {
212  }
213 
215  ValueMex( const ValueMex& other ) : ValueBase( other )
216  {
217  }
218 
220  ValueMex( ValueMex& other ) : ValueBase( other )
221  {
222  }
223 
225  ValueMex( ValueMex&& other ) : ValueBase( other )
226  {
227  }
228 
230  ValueMex& operator=( const ValueMex& other )
231  {
232  ValueBase::operator=( other );
233  return *this;
234  }
235 
238  {
239  ValueBase::operator=( other );
240  return *this;
241  }
242 
245  {
246  ValueBase::operator=( other );
247  return *this;
248  }
249 
255  explicit
256  ValueMex( const mxArray* pcItem )
257  {
258  m_isConst = true;
259  m_pcItem = const_cast<mxArray*>(pcItem);
260  }
261 
262 
270  ValueMex( mwIndex m, mwIndex n, int clsid = mxDOUBLE_CLASS )
271  {
272  m_pcItem = mxCreateNumericMatrix( m, n, (mxClassID)clsid, mxREAL );
273  m_isConst = false;
274  }
275 
276 
282  ValueMex& Adopt( bool doAdopt = true )
283  {
284  m_isConst = !doAdopt;
285  return *this;
286  }
287 
288 
297  static
298  ValueMex CreateCellMatrix( int m, int n )
299  {
300  return ValueMex( mxCreateCellMatrix( m, n ) ).Adopt();
301  }
302 
303 
310  static
311  ValueMex CreateDoubleScalar( double value )
312  {
313  return ValueMex( mxCreateDoubleScalar( value ) ).Adopt();
314  }
315 
316 
323  static
324  ValueMex CreateString( const char* str )
325  {
326  return ValueMex( mxCreateString( str ) ).Adopt();
327  }
328 
329 
335  void Destroy()
336  {
337  if( !m_isConst && m_pcItem )
338  {
339  // Workaround to avoid MATLAB crash with persistent arrays ("Case 02098404", Lucas Lebert, MathWorks Technical Support Department
340  mxArray* tmp = m_pcItem;
341  m_pcItem = NULL;
342  mxDestroyArray( m_pcItem );
343  }
344  }
345 
346 
350  inline
351  const mxArray* Item() const
352  {
353  return const_cast<const mxArray*>( m_pcItem );
354  }
355 
356 
360  inline
361  mxArray* Item()
362  {
363  return m_pcItem;
364  }
365 
366 
370  inline
372  {
373  return ValueMex( m_pcItem ? mxDuplicateArray( m_pcItem ) : NULL ).Adopt();
374  }
375 
376 
380  inline
381  mxArray* Detach()
382  {
383  assert( !m_isConst );
384  mxArray* pcItem = m_pcItem;
385  m_largest_field = 0;
386  return pcItem;
387  }
388 
389 
393  inline
394  size_t GetM() const
395  {
396  return mxGetM(m_pcItem);
397  }
398 
402  inline
403  size_t GetN() const
404  {
405  return mxGetN(m_pcItem);
406  }
407 
411  inline
412  bool IsEmpty() const
413  {
414  return !m_pcItem || mxIsEmpty( m_pcItem );
415  }
416 
420  inline
421  bool IsCell() const
422  {
423  return m_pcItem ? mxIsCell( m_pcItem ) : false;
424  }
425 
429  inline
430  bool IsComplex() const
431  {
432  return m_pcItem ? mxIsComplex( m_pcItem ) : false;
433  }
434 
438  inline
439  bool IsScalar() const
440  {
441  return NumElements() == 1;
442  }
443 
447  inline
448  bool IsStruct() const
449  {
450  return mxIsStruct( m_pcItem );
451  }
452 
456  inline
457  bool IsVector() const
458  {
459  return NumDims() == 2 && min( GetM(), GetN() ) == 1;
460  }
461 
465  inline
466  bool IsDoubleClass() const
467  {
468  return mxDOUBLE_CLASS == ClassID();
469  }
470 
474  inline
475  bool IsFunctionHandle() const
476  {
477  return mxFUNCTION_CLASS == ClassID();
478  }
479 
483  inline
484  size_t NumElements() const
485  {
486  return m_pcItem ? mxGetNumberOfElements( m_pcItem ) : 0;
487  }
488 
492  inline
493  size_t ByElement() const
494  {
495  return m_pcItem ? mxGetElementSize( m_pcItem ) : 0;
496  }
497 
501  inline
502  int NumDims() const
503  {
504  return m_pcItem ? mxGetNumberOfDimensions( m_pcItem ) : 0;
505  }
506 
510  inline
511  size_t ByData() const
512  {
513  return NumElements() * ByElement();
514  }
515 
519  inline
520  mxClassID ClassID() const
521  {
522  return m_pcItem ? mxGetClassID( m_pcItem ) : mxUNKNOWN_CLASS;
523  }
524 
531  type_complexity_e Complexity( bool bCanSerialize = false ) const
532  {
533  if( IsEmpty() ) return TC_EMPTY;
534 
535  switch( ClassID() )
536  {
537  case mxDOUBLE_CLASS:
538  case mxSINGLE_CLASS:
539  if( mxIsComplex( m_pcItem ) )
540  {
541  return TC_COMPLEX;
542  }
543  /* fallthrough */
544  case mxLOGICAL_CLASS:
545  case mxINT8_CLASS:
546  case mxUINT8_CLASS:
547  case mxINT16_CLASS:
548  case mxUINT16_CLASS:
549  case mxINT32_CLASS:
550  case mxUINT32_CLASS:
551  case mxINT64_CLASS:
552  case mxUINT64_CLASS:
553  if( IsScalar() ) return TC_SIMPLE;
554  return IsVector() ? TC_SIMPLE_VECTOR : TC_SIMPLE_ARRAY;
555  case mxCHAR_CLASS:
556  return ( IsScalar() || IsVector() ) ? TC_SIMPLE : TC_SIMPLE_ARRAY;
557  case mxUNKNOWN_CLASS:
558  // serialized data is marked as "unknown" type by mksqlite
559  return bCanSerialize ? TC_COMPLEX : TC_UNSUPP;
560  case mxSTRUCT_CLASS:
561  case mxCELL_CLASS:
562  return TC_COMPLEX;
563  default:
564  return TC_UNSUPP;
565  }
566  }
567 
571  inline
572  void* Data() const
573  {
574  return !IsEmpty() ? mxGetData( m_pcItem ) : NULL;
575  }
576 
584  char *GetString( bool flagUTF = false, const char* format = NULL ) const
585  {
586  size_t count;
587  char* result = NULL;
588  mxArray* new_string = NULL;
589  const mxArray* org_string = m_pcItem;
590 
591  // reformat original string with MATLAB function "sprintf" into new string
592  if( format )
593  {
594  mxArray* args[2] = { mxCreateString( format ), const_cast<mxArray*>(org_string) };
595 
596  mexCallMATLAB( 1, &new_string, 2, args, "sprintf" );
597  mxDestroyArray( args[0] ); // destroy format string
598 
599  org_string = new_string; // Override (but don't free!) org_string
600  }
601 
602  // get character stream from original string (MATLAB array)
603  if( org_string )
604  {
605  char* temp = mxArrayToString( org_string ); // Handles multibyte strings, too
606 
607  // Copy string with own memory management
608  if( temp )
609  {
610  count = strlen( temp ) + 1;
611  result = (char*) MEM_ALLOC( count, sizeof(char) );
612 
613  if( result )
614  {
615  memcpy( result, temp, count );
616  }
617 
618  mxFree( temp );
619  }
620  }
621 
622  // reformatted string is no longer needed
623  ::utils_destroy_array( new_string );
624 
625  // try to retrieve the character stream
626  if( !result )
627  {
628  // free memory and return with error
629  mexErrMsgTxt( getLocaleMsg( MSG_CANTCOPYSTRING ) );
630  }
631 
632  // convert to UFT
633  if( flagUTF )
634  {
635  char *buffer = NULL;
636  int buflen;
637 
638  /* get only the buffer size needed */
639  buflen = utils_latin2utf( (unsigned char*)result, (unsigned char*)buffer );
640  buffer = (char*) MEM_ALLOC( buflen, sizeof(char) );
641 
642  if( !buffer )
643  {
644  ::utils_free_ptr( result ); // Needless due to mexErrMsgTxt(), but clean
645  mexErrMsgTxt( getLocaleMsg( MSG_CANTCOPYSTRING ) );
646  }
647 
648  /* encode string to utf now */
649  ::utils_latin2utf( (unsigned char*)result, (unsigned char*)buffer );
650 
651  ::utils_free_ptr( result );
652 
653  result = buffer;
654  }
655 
656  return result;
657  }
658 
659 
665  char* GetEncString() const
666  {
667  return GetString( g_convertUTF8 ? true : false );
668  }
669 
670 
677  int GetInt( int errval = 0 ) const
678  {
679  if( !IsEmpty() )
680  {
681  switch( ClassID() )
682  {
683  case mxINT8_CLASS : return (int) *( (int8_t*) Data() );
684  case mxUINT8_CLASS : return (int) *( (uint8_t*) Data() );
685  case mxINT16_CLASS : return (int) *( (int16_t*) Data() );
686  case mxUINT16_CLASS: return (int) *( (uint16_t*) Data() );
687  case mxINT32_CLASS : return (int) *( (int32_t*) Data() );
688  case mxUINT32_CLASS: return (int) *( (uint32_t*) Data() );
689  case mxSINGLE_CLASS: return (int) *( (float*) Data() );
690  case mxDOUBLE_CLASS: return (int) *( (double*) Data() );
691  case mxLOGICAL_CLASS: return (int) mxIsLogicalScalarTrue( m_pcItem );
692 
693  default:
694  assert( false );
695  return errval;
696  }
697  }
698 
699  return errval;
700  }
701 
708  sqlite3_int64 GetInt64( int errval = 0 ) const
709  {
710  if( !IsEmpty() )
711  {
712  switch( ClassID() )
713  {
714  case mxINT64_CLASS : return *( (sqlite3_int64*) Data() );
715 
716  default:
717  assert( false );
718  return (sqlite3_int64) errval;
719  }
720  }
721 
722  return errval;
723  }
724 
726  double GetScalar() const
727  {
728  return IsScalar() ? mxGetScalar( m_pcItem ) : DBL_NAN;
729  }
730 
738  const mxArray* GetField( int n, const char* name ) const
739  {
740  mxArray* result = NULL;
741 
742  if( m_pcItem )
743  {
744  result = mxGetField( m_pcItem, n, name );
745 
746  if( !result )
747  {
748  // MATLAB bug? For implicit non-initialized structure members mxGetField()
749  // returns NULL.
750  // ( Thx Knut Voigtlaender for pointing that out )
751  // Workaround: Check if struct has requested field
752  if( mxGetFieldNumber( m_pcItem, name ) >= 0 )
753  {
754  // Create and return an empty array in this case
755  // (MATLAB destroys it automatically when exitting MEX function)
756  result = mxCreateNumericMatrix( 0, 1, mxDOUBLE_CLASS, mxREAL );
757  }
758  }
759  }
760  return result;
761  }
762 
763 
770  void SetCell( int i, const mxArray* cell )
771  {
772  if( m_pcItem )
773  {
774  mxSetCell( m_pcItem, i, const_cast<mxArray*>(cell) );
775  }
776  }
777 
778 
783  {
784  if( m_pcItem )
785  {
786  mexMakeArrayPersistent( m_pcItem );
787  m_isConst = false;
788  }
789  }
790 
791 
795  void Throw()
796  {
797  if( !IsEmpty() && mxIsClass( m_pcItem, "MException" ) )
798  {
799  mxArray* exception = Detach();
800  mexCallMATLAB( 0, NULL, 1, &exception, "throw" );
801  }
802 
803  }
804 
805 
812  void Call( ValueMex* lhs, ValueMex* exception )
813  {
814  assert( IsCell() && !IsEmpty() );
815 
816  mxArray* _lhs = NULL; // Function return value
817  mxArray** prhs = (mxArray**)Data(); // Function handle and arguments
818  mxArray* _exception = mexCallMATLABWithTrap( 1, &_lhs, (int)NumElements(), prhs, "feval" );
819 
820  // Function returned results?
821  if( _lhs )
822  {
823  *lhs = ValueMex( _lhs ).Adopt();
824  _lhs = NULL;
825  }
826 
827  // An exception occured?
828  if( _exception )
829  {
830  *exception = ValueMex( _exception ).Adopt();
831  _exception = NULL;
832  }
833 
834  // Cleanup
835 
836  if( _lhs )
837  {
838  mxDestroyArray( _lhs );
839  }
840 
841  if( _exception )
842  {
843  mxDestroyArray( _exception );
844  }
845  }
846 };
847 
848 
862 class ValueSQL : public ValueBase
863 {
864 public:
865  int m_typeID;
866  size_t m_blobsize;
867 
870  {
871  Destroy();
872  }
873 
876  {
877  m_blobsize = 0;
878  m_typeID = SQLITE_NULL;
879  }
880 
882  ValueSQL( const ValueSQL& other ) : ValueBase( other )
883  {
884  m_typeID = other.m_typeID;
885  m_blobsize = other.m_blobsize;
886  }
887 
889  ValueSQL( ValueSQL& other ) : ValueBase( other )
890  {
891  m_typeID = other.m_typeID;
892  m_blobsize = other.m_blobsize;
893  }
894 
896  ValueSQL( ValueSQL&& other ) : ValueBase( other )
897  {
898  m_typeID = other.m_typeID;
899  m_blobsize = other.m_blobsize;
900  }
901 
903  ValueSQL& operator=( const ValueSQL& other )
904  {
905  ValueBase::operator=(other);
906  m_typeID = other.m_typeID;
907  m_blobsize = other.m_blobsize;
908  return *this;
909  }
910 
913  {
914  ValueBase::operator=(other);
915  m_typeID = other.m_typeID;
916  m_blobsize = other.m_blobsize;
917  return *this;
918  }
919 
922  {
923  ValueBase::operator=(other);
924  m_typeID = other.m_typeID;
925  m_blobsize = other.m_blobsize;
926  return *this;
927  }
928 
930  explicit
931  ValueSQL( double dValue )
932  {
933  m_float = dValue;
934  m_typeID = SQLITE_FLOAT;
935  }
936 
938  explicit
939  ValueSQL( sqlite3_int64 iValue )
940  {
941  m_integer = iValue;
942  m_typeID = SQLITE_INTEGER;
943  }
944 
946  explicit
947  ValueSQL( const char* txtValue )
948  {
949  m_text = const_cast<char*>(txtValue);
950  m_typeID = SQLITE_TEXT;
951  }
952 
954  explicit
955  ValueSQL( char* txtValue )
956  {
957  m_text = txtValue;
958  m_typeID = SQLITE_TEXT;
959  }
960 
962  explicit
963  ValueSQL( char* blobValue, size_t size )
964  {
965  m_isConst = false;
966  m_text = blobValue;
967  m_blobsize = size;
968  m_typeID = SQLITE_BLOBX;
969  }
970 
972  explicit
973  ValueSQL( const mxArray* blobValue )
974  {
975  m_blob = const_cast<mxArray*>(blobValue);
976  m_typeID = SQLITE_BLOB;
977  }
978 
980  explicit
981  ValueSQL( mxArray* blobValue )
982  {
983  m_isConst = false;
984  m_blob = blobValue;
985  m_typeID = SQLITE_BLOB;
986  }
987 
988 
990  void* Detach()
991  {
992  assert( m_text && ( m_typeID == SQLITE_TEXT || m_typeID == SQLITE_BLOB || m_typeID == SQLITE_BLOBX ) );
993  m_isConst = true;
994  return (void*)m_text;
995  }
996 
1002  void Destroy()
1003  {
1004  extern void blob_free( void** pBlob ); /* sql_builtin_functions.hpp */
1005 
1006  if( !m_isConst )
1007  {
1008  if( m_typeID == SQLITE_TEXT && m_text )
1009  {
1010  ::utils_free_ptr( m_text );
1011  m_text = NULL;
1012  }
1013 
1014  if( m_typeID == SQLITE_BLOBX && m_text )
1015  {
1016  blob_free( (void**)&m_text );
1017  }
1018 
1019  if( m_typeID == SQLITE_BLOB && m_blob )
1020  {
1021  mxDestroyArray( m_blob );
1022  m_blob = NULL;
1023  }
1024  }
1025 
1026  m_typeID = SQLITE_NULL;
1027  }
1028 };
1029 
1030 
1040 {
1041 private:
1043  ValueSQLCol();
1044 
1045 public:
1046  string m_col_name;
1047  string m_name;
1049 
1051  typedef pair<string,string> StringPair;
1052  typedef vector<StringPair> StringPairList;
1053 
1054  vector<ValueSQL> m_any;
1055  vector<double> m_float;
1056 
1058  ValueSQLCol( StringPair name )
1059  : m_col_name(name.first)/*SQL*/, m_name(name.second)/*MATLAB*/, m_isAnyType(false)
1060  {
1061  }
1062 
1069  {
1070  for( int i = 0; i < (int)m_any.size(); i++ )
1071  {
1072  m_any[i].Destroy();
1073  }
1074  }
1075 
1081  void Destroy( int row )
1082  {
1083  if( m_isAnyType && row < (int)m_any.size() )
1084  {
1085  m_any[row].Destroy();
1086  }
1087  }
1088 
1090  size_t size()
1091  {
1092  return m_isAnyType ? m_any.size() : m_float.size();
1093  }
1094 
1101  const ValueSQL operator[]( int index )
1102  {
1103  return m_isAnyType ? const_cast<const ValueSQL&>(m_any[index]) : ValueSQL( m_float[index] );
1104  }
1105 
1113  {
1114  if( !m_isAnyType )
1115  {
1116  assert( !m_any.size() );
1117 
1118  // convert each element to ValueSQL type
1119  for( int i = 0; i < (int)m_float.size(); i++ )
1120  {
1121  m_any.push_back( ValueSQL(m_float[i]) );
1122  }
1123 
1124  // clear old value vector (double types) and flag new column type
1125  m_float.clear();
1126  m_isAnyType = true;
1127  }
1128  }
1129 
1131  void append( double value )
1132  {
1133  if( m_isAnyType )
1134  {
1135  m_any.push_back( ValueSQL(value) );
1136  }
1137  else
1138  {
1139  m_float.push_back( value );
1140  }
1141  }
1142 
1144  void append( sqlite3_int64 value )
1145  {
1146  /* Test if integer value can be represented as double type */
1147  double dVal = (double)(value);
1148  long long llVal = (sqlite3_int64) dVal;
1149 
1150  if( llVal == value )
1151  {
1152  // double type is equivalent, and thus preferred
1153  append( dVal );
1154  }
1155  else
1156  {
1157  swapToAnyType();
1158  m_any.push_back( ValueSQL(value) );
1159  }
1160  }
1161 
1163  void append( const char* value )
1164  {
1165  swapToAnyType();
1166  m_any.push_back( ValueSQL(value) );
1167  }
1168 
1170  void append( char* value )
1171  {
1172  swapToAnyType();
1173  m_any.push_back( ValueSQL(value) );
1174  }
1175 
1177  void append( const mxArray* value )
1178  {
1179  swapToAnyType();
1180  m_any.push_back( ValueSQL(value) );
1181  }
1182 
1184  void append( mxArray* value )
1185  {
1186  swapToAnyType();
1187  m_any.push_back( ValueSQL(value) );
1188  }
1189 
1191  void append( const ValueSQL& item )
1192  {
1193  switch( item.m_typeID )
1194  {
1195  case SQLITE_FLOAT:
1196  append( item.m_float );
1197  return;
1198 
1199  case SQLITE_INTEGER:
1200  append( item.m_integer );
1201  return;
1202 
1203  case SQLITE_NULL:
1204  if( g_NULLasNaN )
1205  {
1206  append( DBL_NAN );
1207  }
1208  else
1209  {
1210  swapToAnyType();
1211  m_any.push_back( ValueSQL() );
1212  }
1213  return;
1214 
1215  case SQLITE_TEXT:
1216  case SQLITE_BLOB:
1217  swapToAnyType();
1218  m_any.push_back( item );
1219  break;
1220 
1221  default:
1222  assert( false );
1223  break;
1224  }
1225  }
1226 
1228  void append( ValueSQL& item )
1229  {
1230  switch( item.m_typeID )
1231  {
1232  case SQLITE_FLOAT:
1233  case SQLITE_INTEGER:
1234  case SQLITE_NULL:
1235  append( (const ValueSQL&)item );
1236  break;
1237  case SQLITE_TEXT:
1238  case SQLITE_BLOB:
1239  swapToAnyType();
1240  m_any.push_back( ValueSQL(item) );
1241  break;
1242 
1243  default:
1244  assert( false );
1245  break;
1246  }
1247  }
1248 };
1249 
1259 {
1260  size_t m_elBytes;
1261  size_t m_dims[1];
1262 
1265  : m_elBytes(0)
1266  {
1267  m_dims[0] = 0;
1268  }
1269 
1274  static
1275  tagNativeArray* CreateArray( size_t nDims, size_t dims[], int typeID )
1276  {
1277  tagNativeArray* pThis = NULL;
1278  size_t elBytes = utils_elbytes( (mxClassID)typeID );
1279  size_t memBytes;
1280 
1281  size_t nElements = 0;
1282 
1283  if( nDims )
1284  {
1285  nElements = dims[0];
1286  for( int i = 1; i < (int)nDims; i++ )
1287  {
1288  nElements *= dims[i];
1289  }
1290  }
1291 
1292  memBytes = sizeof(tagNativeArray) +
1293  sizeof(dims[0]) * nDims +
1294  nElements * elBytes;
1295 
1296  pThis = (tagNativeArray*)MEM_ALLOC( memBytes, 1 );
1297 
1298  if( pThis )
1299  {
1300  pThis->m_elBytes = elBytes;
1301  pThis->m_dims[0] = nDims;
1302 
1303  for( int i = 0; i < (int)nDims; i++ )
1304  {
1305  pThis->m_dims[i+1] = dims[i];
1306  }
1307  }
1308 
1309  return pThis;
1310  }
1311 
1315  static
1316  tagNativeArray* CreateMatrix( size_t m, size_t n, int typeID )
1317  {
1318  size_t dims[] = {m, n};
1319  return CreateArray( 2, dims, typeID );
1320  }
1321 
1326  static
1327  void FreeArray( tagNativeArray* pNativeArray )
1328  {
1329  MEM_FREE( pNativeArray );
1330  }
1331 };
void append(char *value)
Appends a new row element (non-const text)
Definition: value.hpp:1170
Encapsulating a MATLAB mxArray.
Definition: value.hpp:178
size_t m_blobsize
Size of BLOB in bytes (only type SQLITE_BLOBX)
Definition: value.hpp:866
const mxArray * GetField(int n, const char *name) const
Get field from a struct array.
Definition: value.hpp:738
ValueMex & operator=(const ValueMex &other)
Assignment operator for const objects.
Definition: value.hpp:230
void append(double value)
Appends a new row element (floating point)
Definition: value.hpp:1131
ValueBase & operator=(ValueBase &other)
Move assignment operator for lvalues.
Definition: value.hpp:130
ValueSQL & operator=(const ValueSQL &other)
Assignment operator for constant objects.
Definition: value.hpp:903
mxArray * Item()
Returns hosted MATLAB array.
Definition: value.hpp:361
ValueBase & operator=(const ValueBase &other)
Assignment operator.
Definition: value.hpp:116
mxClassID ClassID() const
Returns item class ID or mxUNKNOWN_CLASS if item is NULL.
Definition: value.hpp:520
type_complexity_e Complexity(bool bCanSerialize=false) const
Get complexity information. Which storage level is necessary (scalar, vector, matrix, text, blob)
Definition: value.hpp:531
single non-complex value, char or simple string (SQLite simple types)
Definition: value.hpp:187
~ValueBase()
Dtor.
Definition: value.hpp:75
static ValueMex CreateCellMatrix(int m, int n)
Create a cell array.
Definition: value.hpp:298
ValueMex Duplicate() const
Returns a duplictae of the hosted MATLAB array.
Definition: value.hpp:371
ValueMex(ValueMex &&other)
Move ctor for rvalues (temporary objects)
Definition: value.hpp:225
vector< double > m_float
row elements as pure double type
Definition: value.hpp:1055
char * GetString(bool flagUTF=false, const char *format=NULL) const
Convert a string to char, due flagUTF converted to utf8.
Definition: value.hpp:584
void swapToAnyType()
Transform storage type.
Definition: value.hpp:1112
int GetInt(int errval=0) const
Get integer value from item.
Definition: value.hpp:677
int m_typeID
Type of SQL value as integer ID.
Definition: value.hpp:865
string m_name
Table column name (MATLAB)
Definition: value.hpp:1047
void append(ValueSQL &item)
Appends a new row element (non-const SQL value)
Definition: value.hpp:1228
const char * getLocaleMsg(int iMsgNr)
Returns the translation for a defined message.
Definition: locale.hpp:480
void MakePersistent()
Make the MATLAB array persistent.
Definition: value.hpp:782
void Destroy()
Freeing memory space if having ownership.
Definition: value.hpp:1002
size_t utils_elbytes(mxClassID classID)
Get the size of one element in bytes.
Definition: utils.hpp:75
size_t ByElement() const
Returns size in bytes of one element.
Definition: value.hpp:493
mxArray * Detach()
Detach hosted MATLAB array.
Definition: value.hpp:381
ValueBase()
Standard ctor.
Definition: value.hpp:86
ValueBase(ValueBase &&other)
Move ctor for rvalues (temporary objects)
Definition: value.hpp:108
Base class for ValueMex and ValueSQL.
Definition: value.hpp:58
mxArray replacement for speed improvement
Definition: value.hpp:1258
bool m_isConst
if flagged as non-const, class may swap memory ownership (custody)
Definition: value.hpp:61
ValueSQL & operator=(ValueSQL &&other)
Move assignment operator for rvalues (temporary objects)
Definition: value.hpp:921
ValueMex()
Standard ctor.
Definition: value.hpp:210
size_t ByData() const
Returns data size in bytes.
Definition: value.hpp:511
type_complexity_e
Definition: value.hpp:185
void append(const mxArray *value)
Appends a new row element (const MATLAB array)
Definition: value.hpp:1177
sqlite3_int64 GetInt64(int errval=0) const
Get 64 bit integer value from item.
Definition: value.hpp:708
size_t m_dims[1]
count of dimensions
Definition: value.hpp:1261
Class encapsulating a SQL field value.
Definition: value.hpp:862
ValueSQL(const mxArray *blobValue)
Ctor for MATLAB const mxArray* type initializer.
Definition: value.hpp:973
ValueMex & operator=(ValueMex &&other)
Move assignment operator for rvalues (temporary objects)
Definition: value.hpp:244
ValueSQL(mxArray *blobValue)
Ctor for MATLAB mxArray* type initializer.
Definition: value.hpp:981
ValueSQL(char *txtValue)
Ctor for char* type initializer.
Definition: value.hpp:955
bool IsVector() const
Returns true if m_pcItem is of size 1xN or Mx1.
Definition: value.hpp:457
static tagNativeArray * CreateArray(size_t nDims, size_t dims[], int typeID)
Array allocator.
Definition: value.hpp:1275
void blob_free(void **pBlob)
Free memory allocated for a BLOB.
ValueBase(ValueBase &other)
Move ctor for lvalues.
Definition: value.hpp:100
const ValueSQL operator[](int index)
Indexing operator.
Definition: value.hpp:1101
void append(sqlite3_int64 value)
Appends a new row element (integer)
Definition: value.hpp:1144
static ValueMex CreateDoubleScalar(double value)
Create a double scalar.
Definition: value.hpp:311
structs, cells, complex data (SQLite typed ByteStream BLOB)
Definition: value.hpp:190
void Destroy(int row)
Deleting a single row element.
Definition: value.hpp:1081
#define MEM_FREE(ptr)
standard memory free function
Definition: global.hpp:158
void utils_destroy_array(mxArray *&pmxarr)
Freeing memory allocated by mxCreateNumericMatrix() or mxCreateNumericArray().
Definition: utils.hpp:302
int NumDims() const
Returns number of dimensions.
Definition: value.hpp:502
ValueSQL(const ValueSQL &other)
Copy ctor for constant objects.
Definition: value.hpp:882
string m_col_name
Table column name (SQL)
Definition: value.hpp:1046
size_t NumElements() const
Returns number of elements.
Definition: value.hpp:484
void append(const ValueSQL &item)
Appends a new row element (const SQL value)
Definition: value.hpp:1191
bool IsComplex() const
Returns true if item is not NULL and complex.
Definition: value.hpp:430
size_t GetM() const
Returns row count (1st dimension)
Definition: value.hpp:394
ValueSQL & operator=(ValueSQL &other)
Move assignment operator for lvalues.
Definition: value.hpp:912
ValueSQL()
Standard ctor.
Definition: value.hpp:875
ValueMex & operator=(ValueMex &other)
Move assignment operator for lvalues.
Definition: value.hpp:237
size_t m_elBytes
size of one single element in bytes
Definition: value.hpp:1260
bool IsEmpty() const
Returns true if item is NULL or empty ([])
Definition: value.hpp:412
int g_convertUTF8
Flag: String representation (utf8 or ansi)
Definition: global.hpp:253
ValueSQL(const char *txtValue)
Ctor for const char* type initializer.
Definition: value.hpp:947
ValueMex(const ValueMex &other)
Copy ctor for const objects.
Definition: value.hpp:215
void utils_free_ptr(T *&pmxarr)
Freeing memory allocated by mxAlloc() or mxRealloc()
Definition: utils.hpp:322
void Call(ValueMex *lhs, ValueMex *exception)
Calling a MATLAB function (handle) with arguemnts.
Definition: value.hpp:812
void * Data() const
Returns pointer to raw data.
Definition: value.hpp:572
pair< string, string > StringPair
Holds one table column name (first=SQL name, second=MATLAB name)
Definition: value.hpp:1051
bool IsFunctionHandle() const
Returns true if m_pcItem is of type mxFUNCTION_CLASS.
Definition: value.hpp:475
size_t GetN() const
Returns col count (2nd dimension)
Definition: value.hpp:403
bool IsStruct() const
Returns true if item is a struct array.
Definition: value.hpp:448
ValueSQL(ValueSQL &&other)
Move ctor for rvalues (temporary objects)
Definition: value.hpp:896
ValueBase & operator=(ValueBase &&other)
Move assignment operator for rvalues (temporary objects)
Definition: value.hpp:146
static void FreeArray(tagNativeArray *pNativeArray)
Array deallocator.
Definition: value.hpp:1327
ValueBase(const ValueBase &other)
Copy ctor for constant objects.
Definition: value.hpp:93
char * GetEncString() const
Returns allocated memory with items test, due to global flag converted to UTF.
Definition: value.hpp:665
void append(const char *value)
Appends a new row element (const text)
Definition: value.hpp:1163
#define SQLITE_BLOBX
Identifier to flag another allocator as used for SQLITE_BLOB.
Definition: value.hpp:46
static ValueMex CreateString(const char *str)
Create a string.
Definition: value.hpp:324
int g_NULLasNaN
Flag: return NULL as NaN.
Definition: global.hpp:263
int utils_latin2utf(const unsigned char *s, unsigned char *buffer)
Convert char string to UTF-8 string.
Definition: utils.hpp:171
double GetScalar() const
Definition: value.hpp:726
ValueMex & Adopt(bool doAdopt=true)
Take ownership (custody) of a MEX array.
Definition: value.hpp:282
bool m_isAnyType
true, if it&#39;s pure double (integer) type
Definition: value.hpp:1048
~ValueSQLCol()
Dtor.
Definition: value.hpp:1068
ValueSQLCol(StringPair name)
Ctor with column name-pair.
Definition: value.hpp:1058
HC_ASSERT(sizeof(sqlite3_int64)<=sizeof(long long))
Asserting size of SQLite 64-bit integer type at least size of long long type.
ValueMex(ValueMex &other)
Move ctor for lvalues.
Definition: value.hpp:220
Class encapsulating a complete SQL table column with type and name.
Definition: value.hpp:1039
Global definitions.
void Throw()
Throws an exception if any occured.
Definition: value.hpp:795
void append(mxArray *value)
Appends a new row element (non-const MATLAB array)
Definition: value.hpp:1184
const mxArray * Item() const
Returns hosted MATLAB array.
Definition: value.hpp:351
ValueSQL(char *blobValue, size_t size)
Ctor for char* type initializer.
Definition: value.hpp:963
bool IsDoubleClass() const
Returns true if m_pcItem is of type mxDOUBLE_CLASS.
Definition: value.hpp:466
size_t size()
Returns the row count.
Definition: value.hpp:1090
void SetCell(int i, const mxArray *cell)
Sets a cell of a MATLAB cell array.
Definition: value.hpp:770
multidimensional non-complex numeric or char arrays (SQLite typed BLOB)
Definition: value.hpp:189
non-complex numeric vectors (SQLite BLOB)
Definition: value.hpp:188
vector< ValueSQL > m_any
row elements with type information
Definition: value.hpp:1054
tagNativeArray()
Ctor.
Definition: value.hpp:1264
static tagNativeArray * CreateMatrix(size_t m, size_t n, int typeID)
Matrix allocator.
Definition: value.hpp:1316
ValueSQL(ValueSQL &other)
Move ctor for lvalues.
Definition: value.hpp:889
ValueMex(const mxArray *pcItem)
Copy ctor for mxArrays.
Definition: value.hpp:256
bool IsScalar() const
Returns true if item consists of exact 1 element.
Definition: value.hpp:439
~ValueSQL()
Dtor.
Definition: value.hpp:869
ValueMex(mwIndex m, mwIndex n, int clsid=mxDOUBLE_CLASS)
Ctor allocating new MATLAB matrix object.
Definition: value.hpp:270
ValueSQL(sqlite3_int64 iValue)
Ctor for llong type initializer.
Definition: value.hpp:939
void * Detach()
Release custody and return pointer type.
Definition: value.hpp:990
void Destroy()
Dtor.
Definition: value.hpp:335
vector< StringPair > StringPairList
list of string pairs
Definition: value.hpp:1052
ValueSQL(double dValue)
Ctor for double type initializer.
Definition: value.hpp:931
#define MEM_ALLOC(count, bytes)
standard memory allocator
Definition: global.hpp:156
bool IsCell() const
Returns true if item is a cell array.
Definition: value.hpp:421