1 #ifndef BDB_TYPES__HPP
2 #define BDB_TYPES__HPP
3
4 /* $Id: bdb_types.hpp 617975 2020-10-08 18:28:17Z grichenk $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Anatoliy Kuznetsov
30 *
31 * File Description: Field types classes.
32 *
33 */
34
35 #include <db/bdb/bdb_expt.hpp>
36 #include <corelib/ncbi_limits.hpp>
37 #include <corelib/ncbi_bswap.hpp>
38 #include <corelib/ncbistr.hpp>
39 #include <util/simple_buffer.hpp>
40
41 #include <string>
42 #include <vector>
43 #include <memory>
44
45
46 extern "C" {
47 //
48 // Forward structure declarations, so we can declare pointers and
49 // applications can get type checking.
50 // Taken from <db.h>
51 struct __db_dbt; typedef struct __db_dbt DBT;
52 struct __db; typedef struct __db DB;
53 struct __dbc; typedef struct __dbc DBC;
54 struct __db_env; typedef struct __db_env DB_ENV;
55 struct __db_txn; typedef struct __db_txn DB_TXN;
56
57 typedef int (*BDB_CompareFunction)(DB*, const DBT*, const DBT*);
58 typedef unsigned int (*BDB_HashFunction)
59 (DB *, const void *bytes, unsigned length);
60 }
61
62 BEGIN_NCBI_SCOPE
63
64 /** @addtogroup BDB_Types
65 *
66 * @{
67 */
68
69
70 extern "C" {
71
72
73 /// Simple and fast comparison function for tables with
74 /// non-segmented "unsigned int" keys
75 NCBI_DEPRECATED
76 NCBI_BDB_EXPORT int BDB_UintCompare(DB*, const DBT* val1, const DBT* val2);
77 NCBI_BDB_EXPORT int BDB_Uint4Compare(DB*, const DBT* val1, const DBT* val2);
78
79 /// Simple and fast comparison function for tables with
80 /// non-segmented "int" keys
81 NCBI_DEPRECATED
82 NCBI_BDB_EXPORT int BDB_IntCompare(DB*, const DBT* val1, const DBT* val2);
83 NCBI_BDB_EXPORT int BDB_Int4Compare(DB*, const DBT* val1, const DBT* val2);
84
85 /// Simple and fast comparison function for tables with
86 /// non-segmented "Int8" keys
87 NCBI_BDB_EXPORT int BDB_Int8Compare(DB*, const DBT* val1, const DBT* val2);
88
89 /// Simple and fast comparison function for tables with
90 /// non-segmented "Uint8" keys
91 NCBI_BDB_EXPORT int BDB_Uint8Compare(DB*, const DBT* val1, const DBT* val2);
92
93 /// Simple and fast comparison function for tables with
94 /// non-segmented "short int" keys
95 NCBI_BDB_EXPORT int BDB_Int2Compare(DB*, const DBT* val1, const DBT* val2);
96
97 /// Simple and fast comparison function for tables with
98 /// non-segmented "unsigned short int" keys
99 NCBI_BDB_EXPORT int BDB_Uint2Compare(DB*, const DBT* val1, const DBT* val2);
100
101 /// Simple and fast comparison function for tables with
102 /// non-segmented "char" keys
103 NCBI_BDB_EXPORT int BDB_CharCompare(DB*, const DBT* val1, const DBT* val2);
104
105 /// Simple and fast comparison function for tables with
106 /// non-segmented "unsigned char" keys
107 NCBI_BDB_EXPORT int BDB_UCharCompare(DB*, const DBT* val1, const DBT* val2);
108
109 /// Simple and fast comparison function for tables with
110 /// non-segmented "float" keys
111 NCBI_BDB_EXPORT int BDB_FloatCompare(DB*, const DBT* val1, const DBT* val2);
112
113 /// Simple and fast comparison function for tables with
114 /// non-segmented "double" keys
115 NCBI_BDB_EXPORT int BDB_DoubleCompare(DB*, const DBT* val1, const DBT* val2);
116
117 /// Simple and fast comparison function for tables with
118 /// non-segmented "C string" keys
119 NCBI_BDB_EXPORT int BDB_StringCompare(DB*, const DBT* val1, const DBT* val2);
120
121 /// Simple and fast comparison function for tables with
122 /// non-segmented length prefixed string keys
123 NCBI_BDB_EXPORT int BDB_LStringCompare(DB*, const DBT* val1, const DBT* val2);
124
125 /// Simple and fast comparison function for tables with
126 /// non-segmented fixed length string keys
127 NCBI_BDB_EXPORT int BDB_FixedByteStringCompare
128 (DB*, const DBT* val1, const DBT* val2);
129
130
131 /// Simple and fast comparison function for tables with
132 /// non-segmented "case insensitive C string" keys
133 NCBI_BDB_EXPORT int
134 BDB_StringCaseCompare(DB*, const DBT* val1, const DBT* val2);
135
136 /// General purpose DBD comparison function
137 int NCBI_BDB_EXPORT BDB_Compare(DB* db, const DBT* val1, const DBT* val2);
138
139
140
141 /// Simple and fast comparison function for tables with
142 /// non-segmented "unsigned int" keys.
143 /// Used when the data file is in a different byte order architecture.
144 NCBI_DEPRECATED
145 NCBI_BDB_EXPORT int
146 BDB_ByteSwap_UintCompare(DB*, const DBT* val1, const DBT* val2);
147 NCBI_BDB_EXPORT int
148 BDB_ByteSwap_Uint4Compare(DB*, const DBT* val1, const DBT* val2);
149
150 /// Simple and fast comparison function for tables with
151 /// non-segmented "Int8" keys
152 /// Used when the data file is in a different byte order architecture.
153 NCBI_BDB_EXPORT int
154 BDB_ByteSwap_Int8Compare(DB*, const DBT* val1, const DBT* val2);
155
156 /// Simple and fast comparison function for tables with
157 /// non-segmented "Uint8" keys
158 /// Used when the data file is in a different byte order architecture.
159 NCBI_BDB_EXPORT int
160 BDB_ByteSwap_Uint8Compare(DB*, const DBT* val1, const DBT* val2);
161
162 /// Simple and fast comparison function for tables with
163 /// non-segmented "int" keys
164 /// Used when the data file is in a different byte order architecture.
165 NCBI_DEPRECATED
166 NCBI_BDB_EXPORT int
167 BDB_ByteSwap_IntCompare(DB*, const DBT* val1, const DBT* val2);
168 NCBI_BDB_EXPORT int
169 BDB_ByteSwap_Int4Compare(DB*, const DBT* val1, const DBT* val2);
170
171 /// Simple and fast comparison function for tables with
172 /// non-segmented "short int" keys
173 /// Used when the data file is in a different byte order architecture.
174 NCBI_BDB_EXPORT int
175 BDB_ByteSwap_Int2Compare(DB*, const DBT* val1, const DBT* val2);
176
177 /// Simple and fast comparison function for tables with
178 /// non-segmented "unsigned short int" keys
179 /// Used when the data file is in a different byte order architecture.
180 NCBI_BDB_EXPORT int
181 BDB_ByteSwap_Uint2Compare(DB*, const DBT* val1, const DBT* val2);
182
183 /// Simple and fast comparison function for tables with
184 /// non-segmented "float" keys
185 /// Used when the data file is in a different byte order architecture.
186 NCBI_BDB_EXPORT int
187 BDB_ByteSwap_FloatCompare(DB*, const DBT* val1, const DBT* val2);
188
189 /// Simple and fast comparison function for tables with
190 /// non-segmented "double" keys
191 /// Used when the data file is in a different byte order architecture.
192 NCBI_BDB_EXPORT int
193 BDB_ByteSwap_DoubleCompare(DB*, const DBT* val1, const DBT* val2);
194
195
196 /// General purpose hash function
197 unsigned int
198 NCBI_BDB_EXPORT BDB_Hash(DB *, const void *bytes, unsigned length);
199
200 /// Hash method for databases with a single (unique) UInt4 key
201 unsigned int
202 NCBI_BDB_EXPORT BDB_Uint4Hash(DB *, const void *bytes, unsigned length);
203
204
205 }
206
207
208 class CBDB_BufferManager;
209 class CBDB_Field;
210 class CBDB_File;
211 class CBDB_FileCursor;
212 class CBDB_FC_Condition;
213
214
215
216
217 /// BDB Data Field interface definition.
218 ///
219 /// Every relational table in BDB library consists of fields, supporting
220 /// basic IBDB_Field interface
221 class NCBI_BDB_EXPORT IBDB_Field
222 {
223 public:
224 virtual ~IBDB_Field();
225
226 /// Comparison function. p1 and p2 are void pointers on field buffers.
227 /// Positive if p1>p2, zero if p1==p2, negative if p1<p2.
228 /// NOTE: both buffers can be unaligned.
229 /// byte_swapped TRUE indicates that buffers values are in
230 /// a different byte order architecture
231 virtual int Compare(const void* p1,
232 const void* p2,
233 bool byte_swapped) const = 0;
234
235 /// Return current effective size of the buffer.
236 virtual size_t GetDataLength(const void* buf) const = 0;
237
238 /// Set minimal possible value for the field type
239 virtual void SetMinVal() = 0;
240
241 /// Set maximum possible value for the field type
242 virtual void SetMaxVal() = 0;
243 };
244
245
246
247 /// BDB Data Field conversion interface definition.
248 /// All interface functions by default throw "bad conversion" exception.
249
250 class NCBI_BDB_EXPORT IBDB_FieldConvert
251 {
252 public:
~IBDB_FieldConvert()253 virtual ~IBDB_FieldConvert() {}
254
SetInt(int)255 virtual void SetInt(int)
256 { BDB_THROW(eType, "Bad conversion"); }
SetUint(unsigned)257 virtual void SetUint(unsigned)
258 { BDB_THROW(eType, "Bad conversion"); }
GetInt() const259 virtual int GetInt() const
260 { BDB_THROW(eType, "Bad conversion"); }
GetUint() const261 virtual unsigned GetUint() const
262 { BDB_THROW(eType, "Bad conversion"); }
SetString(const char *)263 virtual void SetString(const char*)
264 { BDB_THROW(eType, "Bad conversion"); }
SetStdString(const string &)265 virtual void SetStdString(const string&)
266 { BDB_THROW(eType, "Bad conversion"); }
SetFloat(float)267 virtual void SetFloat(float)
268 { BDB_THROW(eType, "Bad conversion"); }
SetDouble(double)269 virtual void SetDouble(double)
270 { BDB_THROW(eType, "Bad conversion"); }
271
272 virtual string GetString() const = 0;
273
274 virtual void ToString(string& str) const = 0;
275 };
276
277
278
279 /// Interface definition class for field construction.
280 /// Used for interfaces' "access rights management".
281
282 class CBDB_FieldInterfaces : public IBDB_Field,
283 public IBDB_FieldConvert
284 {
285 friend class CBDB_FileCursor;
286 };
287
288
289
290 /// Base class for constructing BDB fields. Implements field buffer pointer.
291 ///
292 /// All DBD field types do not own their buffers.
293 /// It works as a pointer on external memory kept by the record manager
294 /// (CBDB_FieldBuf). Class cannot be used independently without record manager.
295
296 class NCBI_BDB_EXPORT CBDB_Field : public CBDB_FieldInterfaces
297 {
298 public:
299 /// Length based classificator for fields (fixed-variable)
300 enum ELengthType {
301 eFixedLength, //!< fixed-length (like int)
302 eVariableLength //!< variable-length (like string)
303 };
304 CBDB_Field(ELengthType length_type = eFixedLength);
~CBDB_Field()305 virtual ~CBDB_Field() {}
306
307 /// Virtual constructor - class factory for BDB fields.
308 /// Default (zero) value of 'buf-len' uses GetBufferSize().
309 /// For fixed length fields this buf_size parameter has no effect
310 virtual CBDB_Field* Construct(size_t buf_size = 0) const = 0;
311
312 /// Return address to the type specific comparison function
313 /// By default it's universal BDB_Compare
314 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const;
315
316 /// Return TRUE if field can be NULL
317 bool IsNullable() const;
318
319 /// Assign field value to NULL
320 void SetNull();
321
322 /// Return TRUE if field is NULL
323 bool IsNull() const;
324
325 /// Return symbolic name for the field
326 const string& GetName() const;
327
328 /// Get pointer to the data. NULL if not yet attached.
329 const void* GetBuffer() const;
330 /// Get pointer to the data. NULL if not yet attached.
331 void* GetBuffer();
332
333 /// Return maximum possible buffer length
334 size_t GetBufferSize() const;
335
336 /// Get length of the actual data
337 size_t GetLength() const;
338
339 protected:
340
341 /// Field comparison function
342 int CompareWith(const CBDB_Field& field) const;
343
344 /// Copies field value from another field.
345 /// The field type MUST be the same, or an exception will be thrown.
346 void CopyFrom(const CBDB_Field& src);
347
348 // Buffer management functions:
349
350 /// Return TRUE if it is a variable length variable (like string)
351 bool IsVariableLength() const;
352
353 /// Return TRUE if external buffer has already been attached
354 bool IsBufferAttached() const;
355
356 /// RTTI based check if fld is of the same type
357 bool IsSameType(const CBDB_Field& field) const;
358
359 /// Return TRUE if field belongs to a file with an alternative
360 /// byte order
361 bool IsByteSwapped() const;
362
363
364 /// Mark field as "NULL" capable.
365 void SetNullable();
366
367 /// Set "is NULL" flag to FALSE
368 void SetNotNull();
369
370 /// Set symbolic name for the field
371 void SetName(const char* name);
372
373 /// Set field position in the buffer manager
374 void SetBufferIdx(unsigned int idx);
375
376
377 protected:
378 /// Unpack the buffer which contains this field (using CBDB_BufferManager).
379 /// Return new pointer to the field data -- located in the unpacked buffer.
380 void* Unpack();
381 /// Set external buffer pointer and length.
382 /// Zero 'buf_size' means GetBufferSize() is used to obtain the buf. size.
383 void SetBuffer(void* buf, size_t buf_size = 0);
384 /// Set the buffer size.
385 void SetBufferSize(size_t size);
386 /// Set data size, taking into account possible extra data for some fields
387 void SetDataSize(size_t size);
388 /// Hook for defining extra data length
389 virtual size_t GetExtraDataLength();
390 /// Set CBDB_BufferManager -- which works as a memory manager for BDB fields.
391 void SetBufferManager(CBDB_BufferManager* owner);
392
393 /// Copy buffer value from the external source
394 void CopyFrom(const void* src_buf);
395
396 private:
397 CBDB_Field& operator= (const CBDB_Field& data);
398 CBDB_Field(const CBDB_Field& data);
399
400 protected:
401 CBDB_BufferManager* m_BufferManager;
402 struct {
403 unsigned VariableLength : 1;
404 unsigned Attached : 1;
405 unsigned Nullable : 1;
406 } m_Flags;
407 private:
408 void* m_Buffer; // Pointer to the field data (in buf. mgr.)
409 size_t m_BufferSize; // Field data buffer capacity
410 unsigned m_BufferIdx; // Fields' position in the managing buffer
411 string m_Name; // Field's symbolic name
412
413 // Friends
414 friend class CBDB_BufferManager;
415 friend class CBDB_File;
416 friend class CBDB_BLobFile;
417 };
418
419
420
421 /// Template class for building simple scalar data fields.
422 /// (int, float, double)
423
424 template<typename T>
425 class CBDB_FieldSimple : public CBDB_Field
426 {
427 public:
428 typedef T TFieldType;
429 public:
CBDB_FieldSimple()430 CBDB_FieldSimple()
431 : CBDB_Field(eFixedLength)
432 {
433 SetBufferSize(sizeof(T));
434 }
435
SetField(const CBDB_FieldSimple & field)436 void SetField(const CBDB_FieldSimple& field)
437 {
438 if ( field.IsNull() ) {
439 SetNull();
440 } else {
441 if (IsByteSwapped() != field.IsByteSwapped()) {
442 BDB_THROW(eInvalidValue, "Byte order incompatibility");
443 }
444 #ifdef HAVE_UNALIGNED_READS
445 TFieldType* b = (TFieldType*) GetBuffer();
446 TFieldType* f = (TFieldType*) field.GetBuffer();
447 *b = *f;
448 #else
449 ::memcpy(GetBuffer(), field.GetBuffer(), sizeof(T));
450 #endif
451 SetNotNull();
452 }
453 }
454
455 // IDBD_Field implementation
456
Compare(const void * p1,const void * p2,bool) const457 virtual int Compare(const void* p1,
458 const void* p2,
459 bool/* byte_swapped*/) const
460 {
461 // Default implementation ignores byte swapping
462 T v1, v2;
463
464 #ifdef HAVE_UNALIGNED_READS
465 v1 = *((TFieldType*)p1);
466 v2 = *((TFieldType*)p2);
467 #else
468 ::memcpy(&v1, p1, sizeof(v1));
469 ::memcpy(&v2, p2, sizeof(v2));
470 #endif
471 if (v1 < v2) return -1;
472 if (v2 < v1) return 1;
473 return 0;
474 }
475
GetDataLength(const void *) const476 virtual size_t GetDataLength(const void* /*buf*/) const
477 {
478 return sizeof(T);
479 }
480 };
481
482
483
484 /// Template class for building simple scalar integer compatible data fields.
485 /// (int, short, char)
486
487 template<typename T>
488 class CBDB_FieldSimpleInt : public CBDB_FieldSimple<T>
489 {
490 public:
CBDB_FieldSimpleInt()491 CBDB_FieldSimpleInt() : CBDB_FieldSimple<T>() {}
492
Set(T val)493 void Set(T val)
494 {
495 if (this->IsByteSwapped()) {
496
497 if (sizeof(T) == 2) {
498 CByteSwap::PutInt2((unsigned char*)this->GetBuffer(),
499 (Int2) val);
500 } else
501 if (sizeof(T) == 4) {
502 CByteSwap::PutInt4((unsigned char*)this->GetBuffer(),
503 (Int4) val);
504 } else
505 if (sizeof(T) == 8) {
506 CByteSwap::PutInt8((unsigned char*)this->GetBuffer(),
507 (Int8) val);
508 }
509 else {
510 _ASSERT(0);
511 }
512
513 } else {
514 #ifdef HAVE_UNALIGNED_READS
515 typename CBDB_FieldSimple<T>::TFieldType* b =
516 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
517 *b = val;
518 #else
519 ::memcpy(this->GetBuffer(), &val, sizeof(T));
520 #endif
521 }
522 this->SetNotNull();
523 }
524
SetInt(int val)525 virtual void SetInt (int val) { Set((T) val); }
SetUint(unsigned int val)526 virtual void SetUint (unsigned int val) { Set((T) val); }
SetString(const char * val)527 virtual void SetString (const char* val)
528 {
529 long v = ::atol(val);
530 Set((T) v);
531 }
532
GetInt() const533 virtual int GetInt() const
534 {
535 int value;
536 #ifdef HAVE_UNALIGNED_READS
537 typename CBDB_FieldSimple<T>::TFieldType* b =
538 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
539 value = (int)*b;
540 #else
541 ::memcpy(&value, this->GetBuffer(), sizeof(T));
542 #endif
543 return value;
544 }
545
GetUint() const546 virtual unsigned GetUint() const
547 {
548 unsigned value;
549 #ifdef HAVE_UNALIGNED_READS
550 typename CBDB_FieldSimple<T>::TFieldType* b =
551 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
552 value = (unsigned)*b;
553 #else
554 ::memcpy(&value, this->GetBuffer(), sizeof(T));
555 #endif
556 return value;
557 }
558
SetStdString(const string & str)559 virtual void SetStdString(const string& str)
560 {
561 SetString(str.c_str());
562 }
563
Compare(const void * p1,const void * p2,bool byte_swapped) const564 virtual int Compare(const void* p1,
565 const void* p2,
566 bool byte_swapped) const
567 {
568 if (!byte_swapped)
569 return CBDB_FieldSimple<T>::Compare(p1, p2, byte_swapped);
570
571 T v1, v2;
572 v1 = (T) CByteSwap::GetInt4((unsigned char*)p1);
573 v2 = (T) CByteSwap::GetInt4((unsigned char*)p2);
574 if (v1 < v2) return -1;
575 if (v2 < v1) return 1;
576 return 0;
577 }
578
SetMinVal()579 virtual void SetMinVal()
580 {
581 Set(numeric_limits<T>::min());
582 }
583
SetMaxVal()584 virtual void SetMaxVal()
585 {
586 Set(numeric_limits<T>::max());
587 }
588 };
589
590
591
592 /// Template class for building simple scalar floating point compatible fields.
593 /// (float, double)
594 ///
595
596 template<typename T>
597 class CBDB_FieldSimpleFloat : public CBDB_FieldSimple<T>
598 {
599 public:
CBDB_FieldSimpleFloat()600 CBDB_FieldSimpleFloat() : CBDB_FieldSimple<T>() {}
601
Set(T val)602 void Set(T val)
603 {
604 if (this->IsByteSwapped()) {
605
606 if (sizeof(T) == 4) {
607 CByteSwap::PutFloat((unsigned char*)this->GetBuffer(),
608 (float)val);
609 } else
610 if (sizeof(T) == 8) {
611 CByteSwap::PutDouble((unsigned char*)this->GetBuffer(), val);
612 }
613 else {
614 _ASSERT(0);
615 }
616 } else {
617 #ifdef HAVE_UNALIGNED_READS
618 typename CBDB_FieldSimple<T>::TFieldType* b =
619 (typename CBDB_FieldSimple<T>::TFieldType*) this->GetBuffer();
620 *b = val;
621 #else
622 ::memcpy(this->GetBuffer(), &val, sizeof(T));
623 #endif
624 }
625 this->SetNotNull();
626 }
627
SetInt(int val)628 virtual void SetInt (int val) { Set((T) val); }
SetUint(unsigned int val)629 virtual void SetUint (unsigned int val) { Set((T) val); }
SetString(const char * val)630 virtual void SetString (const char* val)
631 {
632 double v = ::atof(val);
633 Set((T) v);
634 }
SetStdString(const string & str)635 virtual void SetStdString(const string& str)
636 {
637 SetString(str.c_str());
638 }
639
SetFloat(float val)640 virtual void SetFloat (float val) { Set((T) val); }
SetDouble(double val)641 virtual void SetDouble(double val) { Set((T) val); }
642
SetMinVal()643 virtual void SetMinVal()
644 {
645 Set(numeric_limits<T>::min());
646 }
647
SetMaxVal()648 virtual void SetMaxVal()
649 {
650 Set(numeric_limits<T>::max());
651 }
652 };
653
654
655 /// Int8 field type
656 ///
657
658 class NCBI_BDB_EXPORT CBDB_FieldInt8 : public CBDB_FieldSimpleInt<Int8>
659 {
660 public:
operator =(Int8 val)661 CBDB_FieldInt8& operator= (Int8 val)
662 {
663 Set(val);
664 return *this;
665 }
666
operator =(const CBDB_FieldInt8 & val)667 CBDB_FieldInt8& operator= (const CBDB_FieldInt8& val)
668 {
669 Set(val);
670 return *this;
671 }
672
Construct(size_t) const673 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
674 {
675 return new CBDB_FieldInt8();
676 }
677
Get() const678 Int8 Get() const
679 {
680 Int8 v;
681
682 _ASSERT(!IsNull());
683
684 if (IsByteSwapped()) {
685 v = CByteSwap::GetInt8((unsigned char*)GetBuffer());
686 } else {
687 #ifdef HAVE_UNALIGNED_READS
688 TFieldType* b = (TFieldType*) this->GetBuffer();
689 v = *b;
690 #else
691 ::memcpy(&v, GetBuffer(), sizeof(Int8));
692 #endif
693 }
694 return v;
695 }
696
GetString() const697 virtual string GetString() const
698 {
699 Int8 v = Get();
700 return NStr::Int8ToString(v);
701 }
702
ToString(string & str) const703 virtual void ToString(string& str) const
704 {
705 Int8 v = Get();
706 NStr::Int8ToString(str, v);
707 }
708
operator Int8() const709 operator Int8() const
710 {
711 return Get();
712 }
713
GetCompareFunction(bool byte_swapped) const714 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
715 {
716 if (byte_swapped)
717 return BDB_ByteSwap_Int8Compare;
718 return BDB_Int8Compare;
719 }
720
Compare(const void * p1,const void * p2,bool byte_swapped) const721 virtual int Compare(const void* p1,
722 const void* p2,
723 bool byte_swapped) const
724 {
725 if (!byte_swapped)
726 return CBDB_FieldSimpleInt<Int8>::Compare(p1, p2, byte_swapped);
727
728 Int8 v1, v2;
729 v1 = CByteSwap::GetInt8((unsigned char*)p1);
730 v2 = CByteSwap::GetInt8((unsigned char*)p2);
731 if (v1 < v2) return -1;
732 if (v2 < v1) return 1;
733 return 0;
734 }
735
736 };
737
738
739 /// Uint8 field type
740 ///
741
742 class NCBI_BDB_EXPORT CBDB_FieldUint8 : public CBDB_FieldSimpleInt<Uint8>
743 {
744 public:
operator =(Uint8 val)745 CBDB_FieldUint8& operator= (Uint8 val)
746 {
747 Set(val);
748 return *this;
749 }
750
operator =(const CBDB_FieldUint8 & val)751 CBDB_FieldUint8& operator= (const CBDB_FieldUint8& val)
752 {
753 Set(val);
754 return *this;
755 }
756
Construct(size_t) const757 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
758 {
759 return new CBDB_FieldUint8();
760 }
761
Get() const762 Uint8 Get() const
763 {
764 Uint8 v;
765
766 _ASSERT(!IsNull());
767
768 if (IsByteSwapped()) {
769 v = CByteSwap::GetInt8((unsigned char*)GetBuffer());
770 } else {
771 #ifdef HAVE_UNALIGNED_READS
772 TFieldType* b = (TFieldType*) GetBuffer();
773 v = *b;
774 #else
775 ::memcpy(&v, GetBuffer(), sizeof(Uint8));
776 #endif
777 }
778 return v;
779 }
780
GetString() const781 virtual string GetString() const
782 {
783 Uint8 v = Get();
784 return NStr::UInt8ToString(v);
785 }
786
ToString(string & str) const787 virtual void ToString(string& str) const
788 {
789 Uint8 v = Get();
790 NStr::UInt8ToString(str, v);
791 }
792
operator Uint8() const793 operator Uint8() const
794 {
795 return Get();
796 }
797
GetCompareFunction(bool byte_swapped) const798 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
799 {
800 if (byte_swapped)
801 return BDB_ByteSwap_Uint8Compare;
802 return BDB_Uint8Compare;
803 }
804
Compare(const void * p1,const void * p2,bool byte_swapped) const805 virtual int Compare(const void* p1,
806 const void* p2,
807 bool byte_swapped) const
808 {
809 if (!byte_swapped)
810 return CBDB_FieldSimpleInt<Uint8>::Compare(p1, p2, byte_swapped);
811
812 Uint8 v1, v2;
813 v1 = CByteSwap::GetInt8((unsigned char*)p1);
814 v2 = CByteSwap::GetInt8((unsigned char*)p2);
815 if (v1 < v2) return -1;
816 if (v2 < v1) return 1;
817 return 0;
818 }
819
820 };
821
822
823 /// Int4 field type
824 ///
825
826 class NCBI_BDB_EXPORT CBDB_FieldInt4 : public CBDB_FieldSimpleInt<Int4>
827 {
828 public:
operator =(Int4 val)829 CBDB_FieldInt4& operator= (Int4 val)
830 {
831 Set(val);
832 return *this;
833 }
834
operator =(const CBDB_FieldInt4 & val)835 CBDB_FieldInt4& operator= (const CBDB_FieldInt4& val)
836 {
837 Set(val);
838 return *this;
839 }
840
Construct(size_t) const841 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
842 {
843 return new CBDB_FieldInt4();
844 }
845
Get() const846 Int4 Get() const
847 {
848 Int4 v;
849
850 _ASSERT(!IsNull());
851
852 if (IsByteSwapped()) {
853 v = CByteSwap::GetInt4((unsigned char*)GetBuffer());
854 } else {
855 #ifdef HAVE_UNALIGNED_READS
856 TFieldType* b = (TFieldType*)GetBuffer();
857 v = *b;
858 #else
859 ::memcpy(&v, GetBuffer(), sizeof(Int4));
860 #endif
861 }
862 return v;
863 }
864
GetString() const865 virtual string GetString() const
866 {
867 Int4 v = Get();
868 return NStr::IntToString(v);
869 }
870
ToString(string & str) const871 virtual void ToString(string& str) const
872 {
873 Int4 v = Get();
874 NStr::IntToString(str, v);
875 }
876
operator Int4() const877 operator Int4() const
878 {
879 return Get();
880 }
881
GetCompareFunction(bool byte_swapped) const882 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
883 {
884 if (byte_swapped)
885 return BDB_ByteSwap_Int4Compare;
886 return BDB_Int4Compare;
887 }
888
Compare(const void * p1,const void * p2,bool byte_swapped) const889 virtual int Compare(const void* p1,
890 const void* p2,
891 bool byte_swapped) const
892 {
893 if (!byte_swapped)
894 return CBDB_FieldSimpleInt<Int4>::Compare(p1, p2, byte_swapped);
895
896 Int4 v1, v2;
897 v1 = CByteSwap::GetInt4((unsigned char*)p1);
898 v2 = CByteSwap::GetInt4((unsigned char*)p2);
899 if (v1 < v2) return -1;
900 if (v2 < v1) return 1;
901 return 0;
902 }
903
904 };
905
906
907 /// Int2 field type
908 ///
909
910 class NCBI_BDB_EXPORT CBDB_FieldInt2 : public CBDB_FieldSimpleInt<Int2>
911 {
912 public:
operator =(Int2 val)913 CBDB_FieldInt2& operator= (Int2 val)
914 {
915 Set(val);
916 return *this;
917 }
918
operator =(const CBDB_FieldInt2 & val)919 CBDB_FieldInt2& operator= (const CBDB_FieldInt2& val)
920 {
921 Set(val);
922 return *this;
923 }
924
Construct(size_t) const925 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
926 {
927 return new CBDB_FieldInt2();
928 }
929
Get() const930 Int2 Get() const
931 {
932 Int2 v;
933
934 _ASSERT(!IsNull());
935
936 if (IsByteSwapped()) {
937 v = CByteSwap::GetInt2((unsigned char*)GetBuffer());
938 } else {
939 #ifdef HAVE_UNALIGNED_READS
940 TFieldType* b = (TFieldType*) GetBuffer();
941 v = *b;
942 #else
943 ::memcpy(&v, GetBuffer(), sizeof(Int2));
944 #endif
945 }
946 return v;
947 }
948
GetString() const949 virtual string GetString() const
950 {
951 Int4 v = Get();
952 return NStr::IntToString(v);
953 }
954
ToString(string & str) const955 virtual void ToString(string& str) const
956 {
957 Int4 v = Get();
958 NStr::IntToString(str, v);
959 }
960
operator Int2() const961 operator Int2() const
962 {
963 return Get();
964 }
965
GetCompareFunction(bool byte_swapped) const966 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
967 {
968 if (byte_swapped)
969 return BDB_ByteSwap_Int2Compare;
970 return BDB_Int2Compare;
971 }
972
Compare(const void * p1,const void * p2,bool byte_swapped) const973 virtual int Compare(const void* p1,
974 const void* p2,
975 bool byte_swapped) const
976 {
977 if (!byte_swapped)
978 return CBDB_FieldSimpleInt<Int2>::Compare(p1, p2, byte_swapped);
979
980 Int2 v1, v2;
981 v1 = CByteSwap::GetInt2((unsigned char*)p1);
982 v2 = CByteSwap::GetInt2((unsigned char*)p2);
983 if (v1 < v2) return -1;
984 if (v2 < v1) return 1;
985 return 0;
986 }
987
988 };
989
990
991 /// Uint2 field type
992 ///
993
994 class NCBI_BDB_EXPORT CBDB_FieldUint2 : public CBDB_FieldSimpleInt<Uint2>
995 {
996 public:
operator =(Uint2 val)997 CBDB_FieldUint2& operator= (Uint2 val)
998 {
999 Set(val);
1000 return *this;
1001 }
1002
operator =(const CBDB_FieldUint2 & val)1003 CBDB_FieldUint2& operator= (const CBDB_FieldUint2& val)
1004 {
1005 Set(val);
1006 return *this;
1007 }
1008
Construct(size_t) const1009 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
1010 {
1011 return new CBDB_FieldUint2();
1012 }
1013
Get() const1014 Uint2 Get() const
1015 {
1016 Uint2 v;
1017
1018 _ASSERT(!IsNull());
1019
1020 if (IsByteSwapped()) {
1021 v = CByteSwap::GetInt2((unsigned char*)GetBuffer());
1022 } else {
1023 #ifdef HAVE_UNALIGNED_READS
1024 TFieldType* b = (TFieldType*) GetBuffer();
1025 v = *b;
1026 #else
1027 ::memcpy(&v, GetBuffer(), sizeof(Uint2));
1028 #endif
1029 }
1030 return v;
1031 }
1032
GetString() const1033 virtual string GetString() const
1034 {
1035 Int4 v = Get();
1036 return NStr::IntToString(v);
1037 }
1038
ToString(string & str) const1039 virtual void ToString(string& str) const
1040 {
1041 Int4 v = Get();
1042 NStr::IntToString(str, v);
1043 }
1044
operator Uint2() const1045 operator Uint2() const
1046 {
1047 return Get();
1048 }
1049
GetCompareFunction(bool byte_swapped) const1050 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
1051 {
1052 if (byte_swapped)
1053 return BDB_ByteSwap_Uint2Compare;
1054 return BDB_Uint2Compare;
1055 }
1056
Compare(const void * p1,const void * p2,bool byte_swapped) const1057 virtual int Compare(const void* p1,
1058 const void* p2,
1059 bool byte_swapped) const
1060 {
1061 if (!byte_swapped)
1062 return CBDB_FieldSimpleInt<Uint2>::Compare(p1, p2, byte_swapped);
1063
1064 Uint2 v1, v2;
1065 v1 = CByteSwap::GetInt2((unsigned char*)p1);
1066 v2 = CByteSwap::GetInt2((unsigned char*)p2);
1067 if (v1 < v2) return -1;
1068 if (v2 < v1) return 1;
1069 return 0;
1070 }
1071
1072 };
1073
1074 /// Char field type
1075 ///
1076
1077 class CBDB_FieldUChar : public CBDB_FieldSimpleInt<unsigned char>
1078 {
1079 public:
operator =(unsigned char val)1080 CBDB_FieldUChar& operator = (unsigned char val)
1081 {
1082 Set(val);
1083 return *this;
1084 }
1085
operator =(const CBDB_FieldUChar & val)1086 CBDB_FieldUChar& operator = (const CBDB_FieldUChar& val)
1087 {
1088 Set(val);
1089 return *this;
1090 }
1091
Construct(size_t) const1092 virtual CBDB_Field * Construct(size_t) const
1093 {
1094 return new CBDB_FieldUChar();
1095 }
1096
Get() const1097 unsigned char Get() const
1098 {
1099 _ASSERT(!IsNull());
1100
1101 return *(const unsigned char*)GetBuffer();
1102 }
1103
operator char() const1104 operator char () const
1105 {
1106 return Get();
1107 }
1108
GetString() const1109 virtual string GetString() const
1110 {
1111 return string(1, Get());
1112 }
1113
ToString(string & s) const1114 virtual void ToString(string& s) const
1115 {
1116 s.assign(1, Get());
1117 }
1118
GetCompareFunction(bool) const1119 virtual BDB_CompareFunction GetCompareFunction(bool) const
1120 {
1121 return BDB_UCharCompare;
1122 }
1123
Compare(const void * p1,const void * p2,bool) const1124 virtual int Compare(const void * p1,
1125 const void * p2,
1126 bool) const
1127 {
1128 const unsigned char& c1 = *(const unsigned char *)p1;
1129 const unsigned char& c2 = *(const unsigned char *)p2;
1130
1131 return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
1132 }
1133 };
1134
1135 class CBDB_FieldChar : public CBDB_FieldSimpleInt<char>
1136 {
1137 public:
operator =(char val)1138 CBDB_FieldChar& operator = (char val)
1139 {
1140 Set(val);
1141 return *this;
1142 }
1143
operator =(const CBDB_FieldChar & val)1144 CBDB_FieldChar& operator = (const CBDB_FieldChar& val)
1145 {
1146 Set(val);
1147 return *this;
1148 }
1149
Construct(size_t) const1150 virtual CBDB_Field * Construct(size_t) const
1151 {
1152 return new CBDB_FieldChar();
1153 }
1154
Get() const1155 char Get() const
1156 {
1157 _ASSERT(!IsNull());
1158
1159 return *(const char*)GetBuffer();
1160 }
1161
operator char() const1162 operator char () const
1163 {
1164 return Get();
1165 }
1166
GetString() const1167 virtual string GetString() const
1168 {
1169 return string(1, Get());
1170 }
1171
ToString(string & s) const1172 virtual void ToString(string& s) const
1173 {
1174 s.assign(1, Get());
1175 }
1176
GetCompareFunction(bool) const1177 virtual BDB_CompareFunction GetCompareFunction(bool) const
1178 {
1179 return BDB_CharCompare;
1180 }
1181
Compare(const void * p1,const void * p2,bool) const1182 virtual int Compare(const void * p1,
1183 const void * p2,
1184 bool) const
1185 {
1186 const char& c1 = *(const char *)p1;
1187 const char& c2 = *(const char *)p2;
1188
1189 return (c1 < c2) ? -1 : (c1 > c2) ? 1 : 0;
1190 }
1191 };
1192
1193 /// Int1 field type
1194 ///
1195
1196 class CBDB_FieldInt1 : public CBDB_FieldChar
1197 {
1198 public:
operator =(Int1 val)1199 CBDB_FieldInt1& operator=(Int1 val)
1200 {
1201 Set(val);
1202 return *this;
1203 }
1204
operator =(const CBDB_FieldChar & val)1205 CBDB_FieldInt1& operator=(const CBDB_FieldChar& val)
1206 {
1207 Set(val);
1208 return *this;
1209 }
1210
Construct(size_t) const1211 virtual CBDB_Field * Construct(size_t) const
1212 {
1213 return new CBDB_FieldInt1();
1214 }
1215
GetString() const1216 virtual string GetString() const
1217 {
1218 return NStr::UIntToString(Get());
1219 }
1220
ToString(string & s) const1221 virtual void ToString(string& s) const
1222 {
1223 s = GetString();
1224 }
1225 };
1226
1227
1228 /// Uint1 field type
1229 ///
1230
1231 class CBDB_FieldUint1 : public CBDB_FieldUChar
1232 {
1233 public:
operator =(unsigned char val)1234 CBDB_FieldUint1& operator= (unsigned char val)
1235 {
1236 Set(val);
1237 return *this;
1238 }
1239
operator =(const CBDB_FieldUChar & val)1240 CBDB_FieldUint1& operator= (const CBDB_FieldUChar& val)
1241 {
1242 Set(val);
1243 return *this;
1244 }
1245
Construct(size_t) const1246 virtual CBDB_Field * Construct(size_t) const
1247 {
1248 return new CBDB_FieldUint1();
1249 }
1250
GetString() const1251 virtual string GetString() const
1252 {
1253 return NStr::UIntToString(Get());
1254 }
1255
ToString(string & s) const1256 virtual void ToString(string& s) const
1257 {
1258 s = GetString();
1259 }
1260 };
1261
1262
1263 /// Uint4 field type
1264 ///
1265
1266 class NCBI_BDB_EXPORT CBDB_FieldUint4 : public CBDB_FieldSimpleInt<Uint4>
1267 {
1268 public:
operator =(Uint4 val)1269 CBDB_FieldUint4& operator= (Uint4 val)
1270 {
1271 Set(val);
1272 return *this;
1273 }
1274
operator =(const CBDB_FieldUint4 & val)1275 CBDB_FieldUint4& operator= (const CBDB_FieldUint4& val)
1276 {
1277 Set(val);
1278 return *this;
1279 }
1280
Construct(size_t) const1281 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
1282 {
1283 return new CBDB_FieldUint4();
1284 }
1285
Get() const1286 Uint4 Get() const
1287 {
1288 Uint4 v;
1289
1290 _ASSERT(!IsNull());
1291
1292 if (IsByteSwapped()) {
1293 v = (Uint4)CByteSwap::GetInt4((unsigned char*)GetBuffer());
1294 } else {
1295 #ifdef HAVE_UNALIGNED_READS
1296 TFieldType* b = (TFieldType*) GetBuffer();
1297 v = *b;
1298 #else
1299 ::memcpy(&v, GetBuffer(), sizeof(Uint4));
1300 #endif
1301 }
1302 return v;
1303 }
1304
GetString() const1305 virtual string GetString() const
1306 {
1307 Uint4 v = Get();
1308 return NStr::UIntToString(v);
1309 }
1310
ToString(string & str) const1311 virtual void ToString(string& str) const
1312 {
1313 Uint4 v = Get();
1314 NStr::UIntToString(str, v);
1315 }
1316
operator Uint4() const1317 operator Uint4() const
1318 {
1319 return Get();
1320 }
1321
GetCompareFunction(bool byte_swapped) const1322 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
1323 {
1324 if (byte_swapped)
1325 return BDB_ByteSwap_Uint4Compare;
1326 return BDB_Uint4Compare;
1327 }
1328
Compare(const void * p1,const void * p2,bool byte_swapped) const1329 virtual int Compare(const void* p1,
1330 const void* p2,
1331 bool byte_swapped) const
1332 {
1333 if (!byte_swapped)
1334 return CBDB_FieldSimpleInt<Uint4>::Compare(p1, p2, byte_swapped);
1335
1336 Uint4 v1, v2;
1337 v1 = (Uint4)CByteSwap::GetInt4((unsigned char*)p1);
1338 v2 = (Uint4)CByteSwap::GetInt4((unsigned char*)p2);
1339 if (v1 < v2) return -1;
1340 if (v2 < v1) return 1;
1341 return 0;
1342 }
1343
1344 };
1345
1346
1347
1348 /// Float field type
1349 ///
1350
1351 class NCBI_BDB_EXPORT CBDB_FieldFloat : public CBDB_FieldSimpleFloat<float>
1352 {
1353 public:
operator =(float val)1354 CBDB_FieldFloat& operator= (float val)
1355 {
1356 Set(val);
1357 return *this;
1358 }
1359
operator =(const CBDB_FieldFloat & val)1360 CBDB_FieldFloat& operator= (const CBDB_FieldFloat& val)
1361 {
1362 Set(val);
1363 return *this;
1364 }
1365
Construct(size_t) const1366 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
1367 {
1368 return new CBDB_FieldFloat();
1369 }
1370
Get() const1371 float Get() const
1372 {
1373 float v;
1374
1375 _ASSERT(!IsNull());
1376
1377 if (IsByteSwapped()) {
1378 v = CByteSwap::GetFloat((unsigned char*)GetBuffer());
1379 } else {
1380 #ifdef HAVE_UNALIGNED_READS
1381 TFieldType* b = (TFieldType*) this->GetBuffer();
1382 v = *b;
1383 #else
1384 ::memcpy(&v, GetBuffer(), sizeof(float));
1385 #endif
1386 }
1387 return v;
1388 }
1389
GetString() const1390 virtual string GetString() const
1391 {
1392 double v = Get();
1393 return NStr::DoubleToString(v);
1394 }
1395
ToString(string & str) const1396 virtual void ToString(string& str) const
1397 {
1398 double v = Get();
1399 NStr::DoubleToString(str, v);
1400 }
1401
operator float() const1402 operator float() const
1403 {
1404 return Get();
1405 }
1406
GetCompareFunction(bool byte_swapped) const1407 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
1408 {
1409 if (byte_swapped)
1410 return BDB_ByteSwap_FloatCompare;
1411
1412 return BDB_FloatCompare;
1413 }
1414
Compare(const void * p1,const void * p2,bool byte_swapped) const1415 virtual int Compare(const void* p1,
1416 const void* p2,
1417 bool byte_swapped) const
1418 {
1419 if (!byte_swapped)
1420 return CBDB_FieldSimpleFloat<float>::Compare(p1, p2, byte_swapped);
1421
1422 float v1, v2;
1423 v1 = CByteSwap::GetFloat((unsigned char*)p1);
1424 v2 = CByteSwap::GetFloat((unsigned char*)p2);
1425 if (v1 < v2) return -1;
1426 if (v2 < v1) return 1;
1427 return 0;
1428 }
1429 };
1430
1431
1432 /// Double precision floating point field type
1433 ///
1434
1435 class NCBI_BDB_EXPORT CBDB_FieldDouble : public CBDB_FieldSimpleFloat<double>
1436 {
1437 public:
operator =(double val)1438 CBDB_FieldDouble& operator= (double val)
1439 {
1440 Set(val);
1441 return *this;
1442 }
1443
operator =(const CBDB_FieldDouble & val)1444 CBDB_FieldDouble& operator= (const CBDB_FieldDouble& val)
1445 {
1446 Set(val);
1447 return *this;
1448 }
1449
Construct(size_t) const1450 virtual CBDB_Field* Construct(size_t /*buf_size*/) const
1451 {
1452 return new CBDB_FieldDouble();
1453 }
1454
Get() const1455 double Get() const
1456 {
1457 double v;
1458
1459 _ASSERT(!IsNull());
1460
1461 if (IsByteSwapped()) {
1462 v = CByteSwap::GetDouble((unsigned char*)GetBuffer());
1463 } else {
1464 #ifdef HAVE_UNALIGNED_READS
1465 TFieldType* b = (TFieldType*) GetBuffer();
1466 v = *b;
1467 #else
1468 ::memcpy(&v, GetBuffer(), sizeof(double));
1469 #endif
1470 }
1471 return v;
1472 }
1473
GetString() const1474 virtual string GetString() const
1475 {
1476 double v = Get();
1477 return NStr::DoubleToString(v);
1478 }
1479
ToString(string & str) const1480 virtual void ToString(string& str) const
1481 {
1482 double v = Get();
1483 NStr::DoubleToString(str, v);
1484 }
1485
operator double() const1486 operator double() const
1487 {
1488 return Get();
1489 }
1490
GetCompareFunction(bool byte_swapped) const1491 virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const
1492 {
1493 if (byte_swapped)
1494 return BDB_ByteSwap_DoubleCompare;
1495
1496 return BDB_DoubleCompare;
1497 }
1498
Compare(const void * p1,const void * p2,bool byte_swapped) const1499 virtual int Compare(const void* p1,
1500 const void* p2,
1501 bool byte_swapped) const
1502 {
1503 if (!byte_swapped)
1504 return CBDB_FieldSimpleFloat<double>::Compare(p1, p2, byte_swapped);
1505
1506 double v1, v2;
1507 v1 = CByteSwap::GetDouble((unsigned char*)p1);
1508 v2 = CByteSwap::GetDouble((unsigned char*)p2);
1509 if (v1 < v2) return -1;
1510 if (v2 < v1) return 1;
1511 return 0;
1512 }
1513
1514 };
1515
1516 /// Fixed length bytestring. (Can hold 0 chars).
1517 ///
1518 class NCBI_BDB_EXPORT CBDB_FieldFixedByteString : public CBDB_Field
1519 {
1520 public:
1521 CBDB_FieldFixedByteString();
1522
Construct(size_t buf_size) const1523 virtual CBDB_Field* Construct(size_t buf_size) const
1524 {
1525 CBDB_FieldFixedByteString* fld = new CBDB_FieldFixedByteString();
1526 fld->SetBufferSize(buf_size ? buf_size : GetBufferSize());
1527 return fld;
1528 }
1529 operator const char* () const;
1530 CBDB_FieldFixedByteString& operator=
1531 (const CBDB_FieldFixedByteString& str);
1532
1533 void Set(const char* str);
SetString(const char * val)1534 virtual void SetString (const char* val) { Set(val); }
1535 string Get() const;
GetString() const1536 virtual string GetString() const { return Get(); }
1537
IsEmpty() const1538 bool IsEmpty() const { return false; }
IsBlank() const1539 bool IsBlank() const { return false; }
1540
1541
1542 // IField
1543 virtual int Compare(const void* p1,
1544 const void* p2,
1545 bool /* byte_swapped */) const;
1546 virtual size_t GetDataLength(const void* buf) const;
1547 virtual void SetMinVal();
1548 virtual void SetMaxVal();
1549
SetStdString(const string & str)1550 virtual void SetStdString(const string& str)
1551 {
1552 _ASSERT(str.length() == GetBufferSize());
1553 SetString(str.c_str());
1554 }
ToString(string & str) const1555 virtual void ToString(string& str) const
1556 {
1557 str.assign((const char*) GetBuffer(), GetBufferSize());
1558 }
1559
GetCompareFunction(bool) const1560 virtual BDB_CompareFunction GetCompareFunction(bool) const
1561 {
1562 return BDB_FixedByteStringCompare;
1563 }
1564
1565 };
1566
1567
1568 ///
1569 /// String field type
1570 ///
1571 class NCBI_BDB_EXPORT CBDB_FieldStringBase : public CBDB_Field
1572 {
1573 public:
1574 enum EOverflowAction {
1575 eThrowOnOverflow,
1576 eTruncateOnOverflow,
1577 eTruncateOnOverflowLogError
1578 };
1579
1580 protected:
CBDB_FieldStringBase()1581 CBDB_FieldStringBase() : CBDB_Field(eVariableLength) {}
1582 };
1583
1584
1585 ///
1586 /// String field type designed to work with C-strings (ASCIIZ)
1587 ///
1588
1589 class NCBI_BDB_EXPORT CBDB_FieldString : public CBDB_FieldStringBase
1590 {
1591 public:
1592 CBDB_FieldString();
1593
1594 /// Class factory for string fields.
1595 /// Default (zero) value of 'buf_size' uses GetBufferSize().
Construct(size_t buf_size) const1596 virtual CBDB_Field* Construct(size_t buf_size) const
1597 {
1598 CBDB_FieldString* fld = new CBDB_FieldString();
1599 fld->SetBufferSize(buf_size ? buf_size : GetBufferSize());
1600 return fld;
1601 }
1602
1603 operator const char* () const;
1604 CBDB_FieldString& operator= (const CBDB_FieldString& str);
1605 CBDB_FieldString& operator= (const char* str);
1606 CBDB_FieldString& operator= (const string& str);
1607
1608 void Set(const char* str, EOverflowAction if_overflow = eThrowOnOverflow);
Get() const1609 string Get() const { return string((const char*)GetBuffer()); }
1610
GetString() const1611 virtual string GetString() const
1612 {
1613 return Get();
1614 }
1615
1616 bool IsEmpty() const;
1617 bool IsBlank() const;
1618
1619
1620 // IField
1621 virtual int Compare(const void* p1,
1622 const void* p2,
1623 bool /* byte_swapped */) const;
1624 virtual size_t GetDataLength(const void* buf) const;
1625 virtual void SetMinVal();
1626 virtual void SetMaxVal();
1627
1628 virtual void SetString(const char*);
SetStdString(const string & str)1629 virtual void SetStdString(const string& str)
1630 {
1631 SetString(str.c_str());
1632 }
ToString(string & str) const1633 virtual void ToString(string& str) const
1634 {
1635 str = (const char*) GetBuffer();
1636 }
1637
GetCompareFunction(bool) const1638 virtual BDB_CompareFunction GetCompareFunction(bool) const
1639 {
1640 return BDB_StringCompare;
1641 }
1642 };
1643
1644
1645
1646 /// Case-insensitive (but case preserving) string field type
1647 ///
1648
1649 class NCBI_BDB_EXPORT CBDB_FieldStringCase : public CBDB_FieldString
1650 {
1651 public:
1652 typedef CBDB_FieldString CParent;
1653
CBDB_FieldStringCase()1654 explicit CBDB_FieldStringCase() : CBDB_FieldString() {}
1655
Construct(size_t buf_size) const1656 virtual CBDB_Field* Construct(size_t buf_size) const
1657 {
1658 CBDB_FieldStringCase* fld = new CBDB_FieldStringCase();
1659 fld->SetBufferSize(buf_size ? buf_size : GetBufferSize());
1660 return fld;
1661 }
1662
1663 // Accessors
operator const char*() const1664 operator const char* () const { return (const char*) GetBuffer(); }
1665
operator =(const CBDB_FieldString & str)1666 CBDB_FieldStringCase& operator= (const CBDB_FieldString& str)
1667 {
1668 Set(str);
1669 return *this;
1670 }
operator =(const CBDB_FieldStringCase & str)1671 CBDB_FieldStringCase& operator= (const CBDB_FieldStringCase& str)
1672 {
1673 Set(str);
1674 return *this;
1675 }
operator =(const char * str)1676 CBDB_FieldStringCase& operator= (const char* str)
1677 {
1678 Set(str);
1679 return *this;
1680 }
operator =(const string & str)1681 CBDB_FieldStringCase& operator= (const string& str)
1682 {
1683 Set(str.c_str());
1684 return *this;
1685 }
1686
Compare(const void * p1,const void * p2,bool) const1687 virtual int Compare(const void* p1,
1688 const void* p2,
1689 bool/* byte_swapped */) const
1690 {
1691 _ASSERT(p1 && p2);
1692 return NStr::CompareNocase((const char*) p1, (const char*) p2);
1693 }
1694
1695 virtual
GetCompareFunction(bool) const1696 BDB_CompareFunction GetCompareFunction(bool /* byte_swapped */) const
1697 {
1698 return BDB_StringCaseCompare;
1699 }
1700
1701 };
1702
1703
1704 ///
1705 /// Length prefised string field type
1706 ///
1707
1708 class NCBI_BDB_EXPORT CBDB_FieldLString : public CBDB_FieldStringBase
1709 {
1710 public:
1711 CBDB_FieldLString();
1712
1713 // Class factory for string fields.
1714 // Default (zero) value of 'buf_size' uses GetBufferSize().
1715 virtual CBDB_Field* Construct(size_t buf_size) const;
1716
operator string() const1717 operator string() const { return GetString(); }
1718 CBDB_FieldLString& operator= (const CBDB_FieldLString& str);
1719 CBDB_FieldLString& operator= (const char* str);
1720 CBDB_FieldLString& operator= (const string& str);
1721
1722 void Set(const char* str, EOverflowAction if_overflow = eThrowOnOverflow);
1723 void Set(const char* str, size_t size,
1724 EOverflowAction if_overflow = eThrowOnOverflow);
1725 string Get() const;
1726
GetString() const1727 virtual string GetString() const
1728 {
1729 return Get();
1730 }
1731
1732 bool IsEmpty() const;
1733 bool IsBlank() const;
1734
1735
1736 // IField
1737 virtual int Compare(const void* p1,
1738 const void* p2,
1739 bool /* byte_swapped */) const;
1740 virtual size_t GetDataLength(const void* buf) const;
1741 virtual void SetMinVal();
1742 virtual void SetMaxVal();
1743
1744 virtual void SetString(const char*);
1745 virtual void SetStdString(const string& str);
1746
GetCompareFunction(bool) const1747 virtual BDB_CompareFunction GetCompareFunction(bool) const
1748 {
1749 return BDB_LStringCompare;
1750 }
1751 virtual void ToString(string& str) const;
1752 protected:
1753 const unsigned char* GetLString(const unsigned char* str,
1754 bool check_legacy,
1755 int* str_len) const;
1756 virtual size_t GetExtraDataLength();
1757 };
1758
1759
1760
1761
1762 /// BDB Data Field Buffer manager class.
1763 /// For internal use in BDB library.
1764 ///
1765 /// @internal
1766
1767 class NCBI_BDB_EXPORT CBDB_BufferManager
1768 {
1769 public:
1770 /// Return number of fields attached using function Bind
1771 unsigned int FieldCount() const;
1772
1773 const CBDB_Field& GetField(unsigned int idx) const;
1774 CBDB_Field& GetField(unsigned int idx);
1775
1776 /// Find the field with the specified name. Name is case insensitive.
1777 /// @return -1 if field cannot be found
1778 int GetFieldIndex(const string& name) const;
1779
1780 /// Return TRUE if buffer is in a non-native byte order
IsByteSwapped() const1781 bool IsByteSwapped() const { return m_ByteSwapped; }
1782
1783 /// Sets maximum number of fields participating in comparison
1784 /// Should be less than total number of fields in the buffer
1785 void SetFieldCompareLimit(unsigned int n_fields);
1786
1787 /// Get number of fields in comparison.
1788 /// 0 - means no forced limit
1789 unsigned int GetFieldCompareLimit() const;
1790
1791 /// Return TRUE if buffer l-strings should check about legacy
1792 /// c-str compatibility
IsLegacyStrings() const1793 bool IsLegacyStrings() const { return m_LegacyString; }
1794
1795 /// Get DBT.size of the parent file (key or data area)
1796 /// (Set by CBDB_File after read)
GetDBT_Size() const1797 size_t GetDBT_Size() const { return m_DBT_Size; }
1798
1799 ~CBDB_BufferManager();
1800
1801 /// Check if any field is NULL
1802 bool HasNull() const;
1803
1804 /// Copy all fields from another manager with the same(a must!) structure
1805 void CopyFrom(const CBDB_BufferManager& bman);
1806
1807 /// Copy packed data (buffer) from an external source
1808 void CopyPackedFrom(void* data, size_t data_size);
1809
1810 protected:
1811 CBDB_BufferManager();
1812
1813 /// Create internal data buffer, assign places in this buffer to the fields
1814 void Construct();
1815
1816 /// Set minimum possible value to buffer fields from 'idx_from' to 'idx_to'
1817 void SetMinVal(unsigned int idx_from, unsigned int idx_to);
1818
1819 /// Set maximum possible value to buffer fields from 'idx_from' to 'idx_to'
1820 void SetMaxVal(unsigned int idx_from, unsigned int idx_to);
1821
1822 /// Attach 'field' to the buffer.
1823 /// NOTE: buffer manager will not own the attached object, nor will it
1824 /// keep ref counters or do any other automagic memory management,
1825 /// unless field ownership is set to TRUE
1826 void Bind(CBDB_Field* field, ENullable is_nullable = eNotNullable);
1827
1828 /// Copy all field values from the 'buf_mgr'.
1829 void CopyFieldsFrom(const CBDB_BufferManager& buf_mgr);
1830
1831 /// Duplicate (dynamic allocation is used) all fields from 'buf_mgr' and
1832 /// bind them to the this buffer manager. Field values are not copied.
1833 /// NOTE: CBDB_BufferManager does not own or deallocate fields,
1834 /// caller is responsible for deallocation,
1835 /// unless field ownership is set to TRUE
1836 void DuplicateStructureFrom(const CBDB_BufferManager& buf_mgr);
1837
1838 /// Compare fields of this buffer with those of 'buf_mgr' using
1839 /// CBDB_Field::CompareWith().
1840 /// Optional 'n_fields' parameter used when we want to compare only
1841 /// several first fields instead of all.
1842 int Compare(const CBDB_BufferManager& buf_mgr,
1843 unsigned int n_fields = 0) const;
1844
1845 /// Return TRUE if any field bound to this buffer manager has variable
1846 /// length (i.e. packable)
1847 bool IsPackable() const;
1848
1849 /// Check if all NOT NULLABLE fields were assigned.
1850 /// Throw an exception if not.
1851 void CheckNullConstraint() const;
1852
1853 void ArrangePtrsUnpacked();
1854 void ArrangePtrsPacked();
1855 void Clear();
1856 unsigned Pack();
1857 unsigned Unpack();
1858
1859 /// Pack the buffer and initialize DBT structure for write operation
1860 void PrepareDBT_ForWrite(DBT* dbt);
1861
1862 /// Initialize DBT structure for read operation.
1863 void PrepareDBT_ForRead(DBT* dbt);
1864
1865 /// Calculate buffer size
1866 size_t ComputeBufferSize() const;
1867
1868 /// Return TRUE if buffer can carry NULL fields
1869 bool IsNullable() const;
1870
1871 /// Set byte swapping flag for the buffer
SetByteSwapped(bool byte_swapped)1872 void SetByteSwapped(bool byte_swapped) { m_ByteSwapped = byte_swapped; }
1873
1874 /// Mark buffer as "NULL fields ready".
1875 /// NOTE: Should be called before buffer construction.
1876 void SetNullable();
1877
1878 void SetNull(unsigned int field_idx, bool value);
1879 bool IsNull (unsigned int field_idx) const;
1880
1881 size_t ComputeNullSetSize() const;
1882 bool TestNullBit(unsigned int idx) const;
1883 void SetNullBit (unsigned int idx, bool value);
1884 void SetAllNull();
1885
1886 /// Return buffer compare function
1887 BDB_CompareFunction GetCompareFunction() const;
1888
1889 /// Return buffer hash function
1890 BDB_HashFunction GetHashFunction() const;
1891
1892 /// Set C-str detection
SetLegacyStringsCheck(bool value)1893 void SetLegacyStringsCheck(bool value) { m_LegacyString = value; }
1894
SetDBT_Size(size_t size)1895 void SetDBT_Size(size_t size) { m_DBT_Size = size; }
1896
1897 /// Fields deletion is managed by the class when own_fields is TRUE
SetFieldOwnership(bool own_fields)1898 void SetFieldOwnership(bool own_fields) { m_OwnFields = own_fields; }
1899
1900 /// Return fields ownership flag
IsOwnFields() const1901 bool IsOwnFields() const { return m_OwnFields; }
1902
1903 /// Disable-enable packing
SetPackable(bool packable)1904 void SetPackable(bool packable) { m_Packable = packable; }
1905
1906 private:
1907 void x_ComputePackOpt();
1908 private:
1909 CBDB_BufferManager(const CBDB_BufferManager&);
1910 CBDB_BufferManager& operator= (const CBDB_BufferManager&);
1911
1912 private:
1913 typedef vector<CBDB_Field*> TFieldVector;
1914
1915 private:
1916 TFieldVector m_Fields;
1917 /// Array of pointers to the fields' data
1918 vector<void*> m_Ptrs;
1919 char* m_Buffer;
1920 size_t m_BufferSize;
1921 size_t m_PackedSize;
1922 size_t m_DBT_Size;
1923 bool m_Packable;
1924 /// TRUE if buffer is in a non-native arch.
1925 bool m_ByteSwapped;
1926
1927 /// TRUE if buffer can carry NULL fields
1928 bool m_Nullable;
1929 /// size of the 'is NULL' bitset in bytes
1930 size_t m_NullSetSize;
1931
1932 /// Number of fields in key comparison
1933 unsigned int m_CompareLimit;
1934
1935 /// Flag to check for legacy string compatibility
1936 bool m_LegacyString;
1937
1938 /// Field ownership flag
1939 bool m_OwnFields;
1940
1941
1942 // pack optimization fields
1943
1944 /// Pack optimization flag (turns TRUE on first Pack call)
1945 bool m_PackOptComputed;
1946 /// Index of first variable length field
1947 unsigned int m_FirstVarFieldIdx;
1948 /// Buffer offset of first variable length field
1949 unsigned int m_FirstVarFieldIdxOffs;
1950
1951 private:
1952 friend class CBDB_Field;
1953 friend class CBDB_BLobFile;
1954 friend class CBDB_File;
1955 friend class CBDB_FileCursor;
1956 friend class CBDB_FC_Condition;
1957 };
1958
1959 /// Class factory for BDB field types
1960 class NCBI_BDB_EXPORT CBDB_FieldFactory
1961 {
1962 public:
1963 enum EType
1964 {
1965 eUnknown,
1966
1967 eString,
1968 eLString,
1969 eInt8,
1970 eInt4,
1971 eUint4,
1972 eInt2,
1973 eUint1,
1974 eFloat,
1975 eDouble,
1976 eUChar,
1977 eBlob
1978 };
1979
1980 public:
1981 CBDB_FieldFactory();
1982
1983 /// Return type enumerator by string type (case insensitive)
1984 EType GetType(const string& type) const;
1985
1986
1987 CBDB_Field* Create(EType type) const;
1988
1989 /// Create field type by string. Caller is responsible for deletion.
1990 ///
1991 /// @param type
1992 /// string type ("string", "int4", "double"). Case insensitive.
1993
1994 CBDB_Field* Create(const string& type) const;
1995 };
1996
1997
1998 /////////////////////////////////////////////////////////////////////////////
1999 ///
2000 /// Type trait classes for finding the correct BDB field type automagically
2001 ///
2002
2003 ///
2004 /// SBDB_TypeTraits defines via template parameters a policy for mapping a
2005 /// built-in type to a BDB field type.
2006 ///
2007 template <class Type>
2008 struct SBDB_TypeTraits
2009 {
2010 typedef Type TType;
2011 typedef void* TFieldType;
2012 };
2013
2014
2015 ///
2016 /// 8-bit signed and unsigned integral types
2017 ///
2018 template<>
2019 struct SBDB_TypeTraits<Int1>
2020 {
2021 typedef Int4 TType;
2022 typedef CBDB_FieldInt1 TFieldType;
2023 };
2024
2025 template<>
2026 struct SBDB_TypeTraits<Uint1>
2027 {
2028 typedef Uint4 TType;
2029 typedef CBDB_FieldUint1 TFieldType;
2030 };
2031
2032
2033 ///
2034 /// 16-bit signed and unsigned integral types
2035 ///
2036 template<>
2037 struct SBDB_TypeTraits<Int2>
2038 {
2039 typedef Int4 TType;
2040 typedef CBDB_FieldInt2 TFieldType;
2041 };
2042
2043 template<>
2044 struct SBDB_TypeTraits<Uint2>
2045 {
2046 typedef Uint4 TType;
2047 typedef CBDB_FieldUint2 TFieldType;
2048 };
2049
2050
2051 ///
2052 /// 32-bit signed and unsigned integral types
2053 ///
2054 template<>
2055 struct SBDB_TypeTraits<Int4>
2056 {
2057 typedef Int4 TType;
2058 typedef CBDB_FieldInt4 TFieldType;
2059 };
2060
2061 template<>
2062 struct SBDB_TypeTraits<Uint4>
2063 {
2064 typedef Uint4 TType;
2065 typedef CBDB_FieldUint4 TFieldType;
2066 };
2067
2068
2069 ///
2070 /// 64-bit signed and unsigned integral types
2071 ///
2072 template<>
2073 struct SBDB_TypeTraits<Int8>
2074 {
2075 typedef Int8 TType;
2076 typedef CBDB_FieldInt8 TFieldType;
2077 };
2078
2079 template<>
2080 struct SBDB_TypeTraits<Uint8>
2081 {
2082 typedef Uint8 TType;
2083 typedef CBDB_FieldUint8 TFieldType;
2084 };
2085
2086
2087 ///
2088 /// string types
2089 ///
2090 template<>
2091 struct SBDB_TypeTraits<string>
2092 {
2093 typedef string TType;
2094 typedef CBDB_FieldString TFieldType;
2095 };
2096
2097
2098 ///
2099 /// 32- and 64- bit floating point types
2100 ///
2101 template<>
2102 struct SBDB_TypeTraits<float>
2103 {
2104 typedef float TType;
2105 typedef CBDB_FieldFloat TFieldType;
2106 };
2107
2108 template<>
2109 struct SBDB_TypeTraits<double>
2110 {
2111 typedef double TType;
2112 typedef CBDB_FieldDouble TFieldType;
2113 };
2114
2115
2116 /* @} */
2117
2118 /////////////////////////////////////////////////////////////////////////////
2119 // IMPLEMENTATION of INLINE functions
2120 /////////////////////////////////////////////////////////////////////////////
2121
2122
2123 /////////////////////////////////////////////////////////////////////////////
2124 // CBDB_Field::
2125 //
2126
2127
IsVariableLength() const2128 inline bool CBDB_Field::IsVariableLength() const
2129 {
2130 return m_Flags.VariableLength == 1;
2131 }
2132
2133
GetBufferSize() const2134 inline size_t CBDB_Field::GetBufferSize() const
2135 {
2136 return m_BufferSize;
2137 }
2138
2139
IsBufferAttached() const2140 inline bool CBDB_Field::IsBufferAttached() const
2141 {
2142 return m_Flags.Attached == 1;
2143 }
2144
2145
IsNullable() const2146 inline bool CBDB_Field::IsNullable() const
2147 {
2148 return m_Flags.Nullable == 1;
2149 }
2150
2151
SetNullable()2152 inline void CBDB_Field::SetNullable()
2153 {
2154 m_Flags.Nullable = 1;
2155 }
2156
2157
SetNotNull()2158 inline void CBDB_Field::SetNotNull()
2159 {
2160 m_BufferManager->SetNull(m_BufferIdx, false);
2161 }
2162
2163
SetNull()2164 inline void CBDB_Field::SetNull()
2165 {
2166 _ASSERT(m_BufferManager->IsNullable());
2167 m_BufferManager->SetNull(m_BufferIdx, true);
2168 }
2169
2170
IsNull() const2171 inline bool CBDB_Field::IsNull() const
2172 {
2173 return m_BufferManager->IsNull(m_BufferIdx);
2174 }
2175
2176
Unpack()2177 inline void* CBDB_Field::Unpack()
2178 {
2179 _ASSERT(m_BufferManager);
2180 m_BufferManager->Unpack();
2181 return GetBuffer();
2182 }
2183
2184
SetBuffer(void * buf,size_t buf_size)2185 inline void CBDB_Field::SetBuffer(void* buf, size_t buf_size)
2186 {
2187 m_Buffer = buf;
2188 if ( buf_size )
2189 m_BufferSize = buf_size;
2190 m_Flags.Attached = 1;
2191 }
2192
2193
SetBufferSize(size_t buf_size)2194 inline void CBDB_Field::SetBufferSize(size_t buf_size)
2195 {
2196 _ASSERT(buf_size != 0);
2197 m_BufferSize = buf_size;
2198 }
2199
2200
SetDataSize(size_t size)2201 inline void CBDB_Field::SetDataSize(size_t size)
2202 {
2203 m_BufferSize = size + GetExtraDataLength();
2204 }
2205
2206
SetBufferIdx(unsigned int idx)2207 inline void CBDB_Field::SetBufferIdx(unsigned int idx)
2208 {
2209 m_BufferIdx = idx;
2210 }
2211
2212
GetBuffer() const2213 inline const void* CBDB_Field::GetBuffer() const
2214 {
2215 return m_Buffer;
2216 }
2217
2218
GetBuffer()2219 inline void* CBDB_Field::GetBuffer()
2220 {
2221 return m_Buffer;
2222 }
2223
2224
SetBufferManager(CBDB_BufferManager * owner)2225 inline void CBDB_Field::SetBufferManager(CBDB_BufferManager* owner)
2226 {
2227 _ASSERT(owner);
2228 m_BufferManager = owner;
2229 }
2230
2231
GetLength() const2232 inline size_t CBDB_Field::GetLength() const
2233 {
2234 return GetDataLength(m_Buffer);
2235 }
2236
2237
CompareWith(const CBDB_Field & field) const2238 inline int CBDB_Field::CompareWith(const CBDB_Field& field) const
2239 {
2240 bool byte_swapped = m_BufferManager->IsByteSwapped();
2241 return Compare(GetBuffer(), field.GetBuffer(), byte_swapped);
2242 }
2243
2244
IsSameType(const CBDB_Field & field) const2245 inline bool CBDB_Field::IsSameType(const CBDB_Field& field) const
2246 {
2247 try {
2248 const type_info& t1 = typeid(*this);
2249 const type_info& t2 = typeid(field);
2250 return (t1 == t2) != 0;
2251 } catch (...) {
2252 }
2253 return false;
2254 }
2255
2256
2257
CopyFrom(const CBDB_Field & src)2258 inline void CBDB_Field::CopyFrom(const CBDB_Field& src)
2259 {
2260 if (this == &src)
2261 return;
2262
2263 if ( !IsSameType(src) ) {
2264 BDB_THROW(eType, "Wrong field type");
2265 }
2266
2267 CopyFrom(src.GetBuffer());
2268 }
2269
2270
CopyFrom(const void * src_buf)2271 inline void CBDB_Field::CopyFrom(const void* src_buf)
2272 {
2273 _ASSERT(src_buf);
2274
2275 void* dst_ptr = Unpack();
2276 _ASSERT(dst_ptr);
2277
2278 size_t max_len = GetBufferSize();
2279 size_t copy_len = GetDataLength(src_buf);
2280
2281 if (copy_len > max_len) {
2282 BDB_THROW(eOverflow, "Cannot copy. Data length exceeds max value");
2283 }
2284 ::memcpy(dst_ptr, src_buf, copy_len);
2285 SetNotNull();
2286 }
2287
2288
GetName() const2289 inline const string& CBDB_Field::GetName() const
2290 {
2291 return m_Name;
2292 }
2293
2294
SetName(const char * name)2295 inline void CBDB_Field::SetName(const char* name)
2296 {
2297 _ASSERT(name);
2298 m_Name = name;
2299 }
2300
IsByteSwapped() const2301 inline bool CBDB_Field::IsByteSwapped() const
2302 {
2303 return m_BufferManager->IsByteSwapped();
2304 }
2305
2306 /////////////////////////////////////////////////////////////////////////////
2307 // CBDB_FieldString::
2308 //
2309
operator const char*() const2310 inline CBDB_FieldFixedByteString::operator const char* () const
2311 {
2312 const char* str = (const char*) GetBuffer();
2313 _ASSERT(str);
2314 return str;
2315 }
2316
2317
2318 inline
Set(const char * str)2319 void CBDB_FieldFixedByteString::Set(const char* str)
2320 {
2321 ::memcpy((char*)GetBuffer(), str, GetBufferSize());
2322 }
2323
2324 inline
Get() const2325 string CBDB_FieldFixedByteString::Get() const
2326 {
2327 _ASSERT(!IsNull());
2328
2329 const char* buf = (const char*) GetBuffer();
2330 return string(buf, GetBufferSize());
2331 }
2332
2333 inline
Compare(const void * p1,const void * p2,bool) const2334 int CBDB_FieldFixedByteString::Compare(const void* p1,
2335 const void* p2,
2336 bool /*byte_swapped*/) const
2337 {
2338 return ::memcmp(p1, p2, GetBufferSize());
2339 }
2340
2341 inline
GetDataLength(const void *) const2342 size_t CBDB_FieldFixedByteString::GetDataLength(const void* /*buf*/) const
2343 {
2344 return GetBufferSize();
2345 }
2346
2347 inline
SetMinVal()2348 void CBDB_FieldFixedByteString::SetMinVal()
2349 {
2350 void* buf = Unpack();
2351 ::memset(buf, 0, GetBufferSize());
2352 }
2353
2354 inline
SetMaxVal()2355 void CBDB_FieldFixedByteString::SetMaxVal()
2356 {
2357 void* buf = Unpack();
2358 ::memset(buf, 0xFF, GetBufferSize());
2359 }
2360
2361 /////////////////////////////////////////////////////////////////////////////
2362 // CBDB_FieldString::
2363 //
2364
CBDB_FieldString()2365 inline CBDB_FieldString::CBDB_FieldString()
2366 : CBDB_FieldStringBase()
2367 {
2368 SetBufferSize(256);
2369 }
2370
2371
operator const char*() const2372 inline CBDB_FieldString::operator const char* () const
2373 {
2374 const char* str = (const char*) GetBuffer();
2375 _ASSERT(str);
2376 return str;
2377 }
2378
2379
2380 inline
2381 CBDB_FieldString&
operator =(const CBDB_FieldString & str)2382 CBDB_FieldString::operator= (const CBDB_FieldString& str)
2383 {
2384 if (this == &str)
2385 return *this;
2386
2387 size_t len = str.GetLength();
2388 if (len > GetBufferSize()) {
2389 // TODO: allow partial string assignment?
2390 BDB_THROW(eOverflow, "String field overflow.");
2391 }
2392 Unpack();
2393 ::strcpy((char*)GetBuffer(), (const char*) str);
2394
2395 if ( str.IsNull() ) {
2396 SetNull();
2397 } else {
2398 SetNotNull();
2399 }
2400
2401 return *this;
2402 }
2403
2404
2405 inline
Set(const char * str,EOverflowAction if_overflow)2406 void CBDB_FieldString::Set(const char* str, EOverflowAction if_overflow)
2407 {
2408 if ( !str )
2409 str = kEmptyCStr;
2410
2411 size_t new_len = ::strlen(str) + 1;
2412
2413 // check overflow
2414 if (new_len > GetBufferSize()) {
2415 switch (if_overflow) {
2416 case eTruncateOnOverflowLogError:
2417 ERR_POST(Warning << "Value truncated for field '"
2418 << GetName() << "'");
2419 NCBI_FALLTHROUGH;
2420 case eTruncateOnOverflow:
2421 new_len = GetBufferSize();
2422 break;
2423 case eThrowOnOverflow:
2424 string msg("String field '");
2425 msg += GetName();
2426 msg += "' overflow: max size = ";
2427 msg += NStr::SizetToString(GetBufferSize());
2428 msg += ", assignee size = ";
2429 msg += NStr::SizetToString(new_len);
2430 BDB_THROW(eOverflow, msg);
2431 break;
2432 }
2433 }
2434 Unpack();
2435 ::memcpy(GetBuffer(), str, new_len);
2436 SetNotNull();
2437 }
2438
2439 inline
SetString(const char * str)2440 void CBDB_FieldString::SetString(const char* str)
2441 {
2442 operator=(str);
2443 }
2444
Compare(const void * p1,const void * p2,bool) const2445 inline int CBDB_FieldString::Compare(const void* p1,
2446 const void* p2,
2447 bool /*byte_swapped*/) const
2448 {
2449 _ASSERT(p1 && p2);
2450 return ::strcmp((const char*) p1, (const char*) p2);
2451 }
2452
2453
SetMinVal()2454 inline void CBDB_FieldString::SetMinVal()
2455 {
2456 ((char*) Unpack())[0] = '\0';
2457 }
2458
2459
SetMaxVal()2460 inline void CBDB_FieldString::SetMaxVal()
2461 {
2462 void* buf = Unpack();
2463 // TODO: find out whether xFF or 0x7F should be used, and how
2464 // (because of possible 'signed char' comparison in strcmp()).
2465 ::memset(buf, 0x7F, GetBufferSize()); // 0xFF for international
2466 ((char*) buf)[GetBufferSize() - 1] = '\0';
2467
2468 SetNotNull();
2469 }
2470
2471
IsEmpty() const2472 inline bool CBDB_FieldString::IsEmpty() const
2473 {
2474 const char* str = (const char*) GetBuffer();
2475 _ASSERT(str);
2476 return !*str;
2477 }
2478
2479
IsBlank() const2480 inline bool CBDB_FieldString::IsBlank() const
2481 {
2482 const char* str = (const char*) GetBuffer();
2483 _ASSERT(str);
2484 for (; *str; ++str) {
2485 if ( !isspace((unsigned char)(*str)) )
2486 return false;
2487 }
2488 return true;
2489 }
2490
2491
GetDataLength(const void * buf) const2492 inline size_t CBDB_FieldString::GetDataLength(const void* buf) const
2493 {
2494 _ASSERT(buf);
2495 return ::strlen((const char*) buf) + 1;
2496 }
2497
2498
operator =(const char * str)2499 inline CBDB_FieldString& CBDB_FieldString::operator= (const char* str)
2500 {
2501 Set(str, eThrowOnOverflow);
2502 return *this;
2503 }
2504
operator =(const string & str)2505 inline CBDB_FieldString& CBDB_FieldString::operator= (const string& str)
2506 {
2507 return this->operator=(str.c_str());
2508 }
2509
2510
2511
2512 /////////////////////////////////////////////////////////////////////////////
2513 // CBDB_BufferManager::
2514 //
2515
2516
GetField(unsigned int n) const2517 inline const CBDB_Field& CBDB_BufferManager::GetField(unsigned int n) const
2518 {
2519 return *m_Fields[n];
2520 }
2521
2522
GetField(unsigned int n)2523 inline CBDB_Field& CBDB_BufferManager::GetField(unsigned int n)
2524 {
2525 return *m_Fields[n];
2526 }
2527
2528
FieldCount() const2529 inline unsigned int CBDB_BufferManager::FieldCount() const
2530 {
2531 return (unsigned int)m_Fields.size();
2532 }
2533
2534
IsPackable() const2535 inline bool CBDB_BufferManager::IsPackable() const
2536 {
2537 return m_Packable;
2538 }
2539
2540
IsNullable() const2541 inline bool CBDB_BufferManager::IsNullable() const
2542 {
2543 return m_Nullable;
2544 }
2545
2546
SetNullable()2547 inline void CBDB_BufferManager::SetNullable()
2548 {
2549 _ASSERT(m_Buffer == 0);
2550 m_Nullable = true;
2551 }
2552
2553
ComputeNullSetSize() const2554 inline size_t CBDB_BufferManager::ComputeNullSetSize() const
2555 {
2556 if ( !IsNullable() )
2557 return 0;
2558
2559 return (FieldCount() + 7) / 8;
2560 }
2561
2562
TestNullBit(unsigned int n) const2563 inline bool CBDB_BufferManager::TestNullBit(unsigned int n) const
2564 {
2565 _ASSERT(IsNullable());
2566
2567 const unsigned char* buf = (unsigned char*) m_Buffer;
2568 unsigned char mask = (unsigned char) (1 << (n & 7));
2569 const unsigned char* offs = buf + (n >> 3);
2570
2571 return ((*offs) & mask) != 0;
2572 }
2573
2574
SetNullBit(unsigned int n,bool value)2575 inline void CBDB_BufferManager::SetNullBit(unsigned int n, bool value)
2576 {
2577 _ASSERT(IsNullable());
2578
2579 unsigned char* buf = (unsigned char*) m_Buffer;
2580 unsigned char mask = (unsigned char) (1 << (n & 7));
2581 unsigned char* offs = buf + (n >> 3);
2582
2583 (void) (value ? (*offs |= mask) : (*offs &= (unsigned char)~mask));
2584 }
2585
2586
SetNull(unsigned int field_idx,bool value)2587 inline void CBDB_BufferManager::SetNull(unsigned int field_idx, bool value)
2588 {
2589 if ( !IsNullable() )
2590 return;
2591 _ASSERT(field_idx < m_Fields.size());
2592 SetNullBit(field_idx, value);
2593 }
2594
2595
SetAllNull()2596 inline void CBDB_BufferManager::SetAllNull()
2597 {
2598 if ( !IsNullable() )
2599 return;
2600 unsigned char* buf = (unsigned char*) m_Buffer;
2601 for (size_t i = 0; i < m_NullSetSize; ++i) {
2602 *buf++ = (unsigned char) 0xFF;
2603 }
2604 }
2605
2606
HasNull() const2607 inline bool CBDB_BufferManager::HasNull() const
2608 {
2609 if (IsNullable()) {
2610 for (size_t i = 0; i < m_NullSetSize; ++i) {
2611 if (m_Buffer[i])
2612 return true;
2613 }
2614 }
2615 return false;
2616 }
2617
2618
IsNull(unsigned field_idx) const2619 inline bool CBDB_BufferManager::IsNull(unsigned field_idx) const
2620 {
2621 if ( !IsNullable() )
2622 return false;
2623
2624 _ASSERT(field_idx < m_Fields.size());
2625
2626 return TestNullBit(field_idx);
2627 }
2628
2629
ArrangePtrsUnpacked()2630 inline void CBDB_BufferManager::ArrangePtrsUnpacked()
2631 {
2632 if ( !m_PackedSize )
2633 return;
2634
2635 if ( !IsPackable() ) {
2636 m_PackedSize = 0;
2637 return;
2638 }
2639
2640 for (size_t i = 0; i < m_Fields.size(); ++i) {
2641 CBDB_Field& df = GetField((unsigned)i);
2642 df.SetBuffer(m_Ptrs[i]);
2643 }
2644
2645 m_PackedSize = 0; // not packed
2646 }
2647
2648
Clear()2649 inline void CBDB_BufferManager::Clear()
2650 {
2651 ::memset(m_Buffer, 0, m_BufferSize);
2652 ArrangePtrsUnpacked();
2653 }
2654
2655
2656 inline
CopyFieldsFrom(const CBDB_BufferManager & buf_mgr)2657 void CBDB_BufferManager::CopyFieldsFrom(const CBDB_BufferManager& buf_mgr)
2658 {
2659 unsigned int field_count = min(FieldCount(), buf_mgr.FieldCount());
2660
2661 for (unsigned int i = 0; i < field_count; ++i) {
2662 CBDB_Field* fld = m_Fields[i];
2663 fld->CopyFrom(buf_mgr.GetField(i));
2664 }
2665 }
2666
2667
2668 inline
SetMinVal(unsigned int idx_from,unsigned int idx_to)2669 void CBDB_BufferManager::SetMinVal(unsigned int idx_from, unsigned int idx_to)
2670 {
2671 _ASSERT(idx_to <= FieldCount());
2672
2673 for ( ; idx_from < idx_to; ++idx_from) {
2674 CBDB_Field& fld = GetField(idx_from);
2675 fld.SetMinVal();
2676 }
2677 }
2678
2679
2680 inline
SetMaxVal(unsigned int idx_from,unsigned int idx_to)2681 void CBDB_BufferManager::SetMaxVal(unsigned int idx_from, unsigned int idx_to)
2682 {
2683 _ASSERT(idx_to <= FieldCount());
2684
2685 for ( ; idx_from < idx_to; ++idx_from) {
2686 CBDB_Field& fld = GetField(idx_from);
2687 fld.SetMaxVal();
2688 }
2689 }
2690
2691 inline
SetFieldCompareLimit(unsigned int n_fields)2692 void CBDB_BufferManager::SetFieldCompareLimit(unsigned int n_fields)
2693 {
2694 m_CompareLimit = n_fields;
2695 }
2696
2697 inline
GetFieldCompareLimit() const2698 unsigned int CBDB_BufferManager::GetFieldCompareLimit() const
2699 {
2700 return m_CompareLimit;
2701 }
2702
2703 // Delete all field objects bound to field buffer.
2704 // Should be used with extreme caution. After calling this buf object should
2705 // never be used again. All fields bound to the buffer must be dynamically
2706 // allocated.
2707 inline
DeleteFields(CBDB_BufferManager & buf)2708 void DeleteFields(CBDB_BufferManager& buf)
2709 {
2710 for (unsigned int i = 0; i < buf.FieldCount(); ++i) {
2711 CBDB_Field* fld = &buf.GetField(i);
2712 delete fld;
2713 }
2714 }
2715
2716
2717 END_NCBI_SCOPE
2718
2719
2720
2721 #endif /* BDB_TYPES__HPP */
2722