📄 bdb_types.hpp
字号:
/* * =========================================================================== * PRODUCTION $Log: bdb_types.hpp,v $ * PRODUCTION Revision 1000.4 2004/06/01 18:37:08 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.36 * PRODUCTION * =========================================================================== */#ifndef BDB_TYPES__HPP#define BDB_TYPES__HPP/* $Id: bdb_types.hpp,v 1000.4 2004/06/01 18:37:08 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Anatoliy Kuznetsov * * File Description: Field types classes. * */#include <bdb/bdb_expt.hpp>#include <corelib/ncbi_limits.hpp>#include <corelib/ncbi_bswap.hpp>#include <corelib/ncbistr.hpp>#include <string>#include <vector>#include <memory>extern "C" { // // Forward structure declarations, so we can declare pointers and // applications can get type checking. // Taken from <db.h> struct __db_dbt; typedef struct __db_dbt DBT; struct __db; typedef struct __db DB; struct __dbc; typedef struct __dbc DBC; struct __db_env; typedef struct __db_env DB_ENV; struct __db_txn; typedef struct __db_txn DB_TXN; typedef int (*BDB_CompareFunction)(DB*, const DBT*, const DBT*);}BEGIN_NCBI_SCOPE/** @addtogroup BDB_Types * * @{ */extern "C" {/// Simple and fast comparison function for tables with /// non-segmented "unsigned int" keysint BDB_UintCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "int" keysint BDB_IntCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "short int" keysint BDB_Int2Compare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "unsigned char" keysint BDB_UCharCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "float" keysint BDB_FloatCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "double" keysint BDB_DoubleCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "C string" keysint BDB_StringCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented length prefixed string keysint BDB_LStringCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "case insensitive C string" keysint BDB_StringCaseCompare(DB*, const DBT* val1, const DBT* val2);/// General purpose DBD comparison functionint BDB_Compare(DB* db, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "unsigned int" keys./// Used when the data file is in a different byte order architecture.int BDB_ByteSwap_UintCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "int" keys/// Used when the data file is in a different byte order architecture.int BDB_ByteSwap_IntCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "short int" keys/// Used when the data file is in a different byte order architecture.int BDB_ByteSwap_Int2Compare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "float" keys/// Used when the data file is in a different byte order architecture.int BDB_ByteSwap_FloatCompare(DB*, const DBT* val1, const DBT* val2);/// Simple and fast comparison function for tables with /// non-segmented "double" keys/// Used when the data file is in a different byte order architecture.int BDB_ByteSwap_DoubleCompare(DB*, const DBT* val1, const DBT* val2);}class CBDB_BufferManager;class CBDB_Field;class CBDB_File;class CBDB_FileCursor;class CBDB_FC_Condition;/// BDB Data Field interface definition.////// Every relational table in BDB library consists of fields, supporting/// basic IBDB_Field interfaceclass NCBI_BDB_EXPORT IBDB_Field{public: virtual ~IBDB_Field(); /// Comparison function. p1 and p2 are void pointers on field buffers. /// Positive if p1>p2, zero if p1==p2, negative if p1<p2. /// NOTE: both buffers can be unaligned. /// byte_swapped TRUE indicates that buffers values are in /// a different byte order architecture virtual int Compare(const void* p1, const void* p2, bool byte_swapped) const = 0; /// Return current effective size of the buffer. virtual size_t GetDataLength(const void* buf) const = 0; /// Set minimal possible value for the field type virtual void SetMinVal() = 0; /// Set maximum possible value for the field type virtual void SetMaxVal() = 0;};/// BDB Data Field conversion interface definition./// All interface functions by default throw "bad conversion" exception.class NCBI_BDB_EXPORT IBDB_FieldConvert{public: virtual ~IBDB_FieldConvert() {} virtual void SetInt(int) { BDB_THROW(eType, "Bad conversion"); } virtual void SetUint(unsigned) // ??? { BDB_THROW(eType, "Bad conversion"); } virtual void SetString(const char*) { BDB_THROW(eType, "Bad conversion"); } virtual void SetStdString(const string&) { BDB_THROW(eType, "Bad conversion"); } virtual void SetFloat(float) { BDB_THROW(eType, "Bad conversion"); } virtual void SetDouble(double) { BDB_THROW(eType, "Bad conversion"); } virtual string GetString() const = 0; virtual void ToString(string& str) const = 0;};/// Interface definition class for field construction./// Used for interfaces' "access rights management".class CBDB_FieldInterfaces : public IBDB_Field, public IBDB_FieldConvert{ friend class CBDB_FileCursor;};/// Base class for constructing BDB fields. Implements field buffer pointer.////// All DBD field types do not own their buffers. /// It works as a pointer on external memory kept by the record manager/// (CBDB_FieldBuf). Class cannot be used independently without record manager.class NCBI_BDB_EXPORT CBDB_Field : public CBDB_FieldInterfaces{public: /// Length based classificator for fields (fixed-variable) enum ELengthType { eFixedLength, //!< fixed-length (like int) eVariableLength //!< variable-length (like string) }; CBDB_Field(ELengthType length_type = eFixedLength); virtual ~CBDB_Field() {} /// Virtual constructor - class factory for BDB fields. /// Default (zero) value of 'buf-len' uses GetBufferSize(). /// For fixed length fields this buf_size parameter has no effect virtual CBDB_Field* Construct(size_t buf_size = 0) const = 0; /// Return address to the type specific comparison function /// By default it's universal BDB_Compare virtual BDB_CompareFunction GetCompareFunction(bool byte_swapped) const; /// Return TRUE if field can be NULL bool IsNullable() const; /// Assign field value to NULL void SetNull(); /// Return TRUE if field is NULL bool IsNull() const; /// Return symbolic name for the field const string& GetName() const; /// Get pointer to the data. NULL if not yet attached. const void* GetBuffer() const; /// Get pointer to the data. NULL if not yet attached. void* GetBuffer(); /// Return maximum possible buffer length size_t GetBufferSize() const; /// Get length of the actual data size_t GetLength() const;protected: /// Field comparison function int CompareWith(const CBDB_Field& field) const; /// Copies field value from another field. /// The field type MUST be the same, or an exception will be thrown. void CopyFrom(const CBDB_Field& src); // Buffer management functions: /// Return TRUE if it is a variable length variable (like string) bool IsVariableLength() const; /// Return TRUE if external buffer has already been attached bool IsBufferAttached() const; /// RTTI based check if fld is of the same type bool IsSameType(const CBDB_Field& field) const; /// Return TRUE if field belongs to a file with an alternative /// byte order bool IsByteSwapped() const; /// Mark field as "NULL" capable. void SetNullable(); /// Set "is NULL" flag to FALSE void SetNotNull(); /// Set symbolic name for the field void SetName(const char* name); /// Set field position in the buffer manager void SetBufferIdx(unsigned int idx);protected: /// Unpack the buffer which contains this field (using CBDB_BufferManager). /// Return new pointer to the field data -- located in the unpacked buffer. void* Unpack(); /// Set external buffer pointer and length. /// Zero 'buf_size' means GetBufferSize() is used to obtain the buf. size. void SetBuffer(void* buf, size_t buf_size = 0); /// Set the buffer size. void SetBufferSize(size_t size); /// Set CBDB_BufferManager -- which works as a memory manager for BDB fields. void SetBufferManager(CBDB_BufferManager* owner); /// Copy buffer value from the external source void CopyFrom(const void* src_buf);private: CBDB_Field& operator= (const CBDB_Field& data); CBDB_Field(const CBDB_Field& data);protected: CBDB_BufferManager* m_BufferManager; struct { unsigned VariableLength : 1; unsigned Attached : 1; unsigned Nullable : 1; } m_Flags;private: void* m_Buffer; // Pointer to the field data (in buf. mgr.) size_t m_BufferSize; // Field data buffer capacity unsigned m_BufferIdx; // Fields' position in the managing buffer string m_Name; // Field's symbolic name // Friends friend class CBDB_BufferManager; friend class CBDB_File; friend class CBDB_BLobFile;};/// Template class for building simple scalar data fields. /// (int, float, double)template<typename T>class CBDB_FieldSimple : public CBDB_Field{public: CBDB_FieldSimple() : CBDB_Field(eFixedLength) { SetBufferSize(sizeof(T)); } void SetField(const CBDB_FieldSimple& field) { if ( field.IsNull() ) { SetNull(); } else { if (IsByteSwapped() != field.IsByteSwapped()) { BDB_THROW(eInvalidValue, "Byte order incompatibility"); } ::memcpy(GetBuffer(), field.GetBuffer(), sizeof(T)); SetNotNull(); } } // IDBD_Field implementation virtual int Compare(const void* p1, const void* p2, bool/* byte_swapped*/) const { // Default implementation ignores byte swapping T v1, v2; ::memcpy(&v1, p1, sizeof(v1)); ::memcpy(&v2, p2, sizeof(v2)); if (v1 < v2) return -1; if (v2 < v1) return 1; return 0; } virtual size_t GetDataLength(const void* /*buf*/) const { return sizeof(T); }};/// Template class for building simple scalar integer compatible data fields./// (int, short, char)template<typename T>class CBDB_FieldSimpleInt : public CBDB_FieldSimple<T>{public: CBDB_FieldSimpleInt() : CBDB_FieldSimple<T>() {} void Set(T val) { if (this->IsByteSwapped()) { if (sizeof(T) == 2) { CByteSwap::PutInt2((unsigned char*)this->GetBuffer(), (Int2) val); } else if (sizeof(T) == 4) { CByteSwap::PutInt4((unsigned char*)this->GetBuffer(), (Int4) val); } else if (sizeof(T) == 8) { CByteSwap::PutInt8((unsigned char*)this->GetBuffer(), (Int8) val); } else { _ASSERT(0); } } else { ::memcpy(this->GetBuffer(), &val, sizeof(T)); } this->SetNotNull(); } virtual void SetInt (int val) { Set((T) val); } virtual void SetUint (unsigned int val) { Set((T) val); } virtual void SetString (const char* val) { long v = ::atol(val); Set((T) v); } virtual void SetStdString(const string& str) { SetString(str.c_str()); } virtual int Compare(const void* p1, const void* p2, bool byte_swapped) const { if (!byte_swapped) return CBDB_FieldSimple<T>::Compare(p1, p2, byte_swapped); T v1, v2; v1 = (T) CByteSwap::GetInt4((unsigned char*)p1); v2 = (T) CByteSwap::GetInt4((unsigned char*)p2); if (v1 < v2) return -1; if (v2 < v1) return 1; return 0; } virtual void SetMinVal() { Set(numeric_limits<T>::min()); } virtual void SetMaxVal() { Set(numeric_limits<T>::max()); }};/// Template class for building simple scalar floating point compatible fields./// (float, double)///template<typename T>class CBDB_FieldSimpleFloat : public CBDB_FieldSimple<T>{public: CBDB_FieldSimpleFloat() : CBDB_FieldSimple<T>() {} void Set(T val) { if (this->IsByteSwapped()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -