diff options
Diffstat (limited to 'akregator/src/mk4storage/metakit/include/mk4.h')
-rw-r--r-- | akregator/src/mk4storage/metakit/include/mk4.h | 1078 |
1 files changed, 1078 insertions, 0 deletions
diff --git a/akregator/src/mk4storage/metakit/include/mk4.h b/akregator/src/mk4storage/metakit/include/mk4.h new file mode 100644 index 000000000..33016dba0 --- /dev/null +++ b/akregator/src/mk4storage/metakit/include/mk4.h @@ -0,0 +1,1078 @@ +// mk4.h -- +// $Id$ +// This is part of Metakit, see http://www.equi4.com/metakit/ + +/** @file + * Main Metakit library include file + */ + +#ifndef __MK4_H__ +#define __MK4_H__ + +//--------------------------------------------------------------------------- +// +// TITLE +// +// The Metakit Library, by Jean-Claude Wippler, Equi4 Software, NL. +// +// DESCRIPTION +// +// Structured data storage with commit / rollback and on-demand loading. +// +// ACKNOWLEDGEMENTS +// +// To Liesbeth and Myra, for making this possible. +// +//--------------------------------------------------------------------------- +// +// NAMING CONVENTIONS PREFIX REMARKS +// +// Compile time options q4_ Always defined as 1 or 0, capitalized +// Preprocessor defines d4_ Use with "#ifdef" or "#if defined()" +// Classes c4_ Classes, listed at start of headers +// Typedefs t4_ Type definitions, if outside classes +// Global functions f4_ Internal, these are rarely defined +// +// Member functions Start in uppercase +// Instance variables _ And start in lowercase +// Static members _ And start in uppercase +// +// Local variable names Start in lowercase +// Formal parameter names Start lowercase, end with underscore +// +//--------------------------------------------------------------------------- + + /// Current release = 100 * major + 10 * minor + maintenance +#define d4_MetakitLibraryVersion 249 // 2.4.9.3 release, Jan 26, 2004 +#define d4_MetaKitLibraryVersion d4_MetakitLibraryVersion // compat, yuck + +//--------------------------------------------------------------------------- +// Declarations in this file + + class c4_View; // a view on underlying data + class c4_Cursor; // an index into a view + class c4_RowRef; // a reference to a row + class c4_Row; // one row in a view + class c4_Bytes; // used to pass around generic data + class c4_Storage; // manages view persistence + class c4_CustomViewer; // used for customizable views + class c4_Stream; // abstract stream class + class c4_Strategy; // system and file interface + + class c4_Property; // for access inside rows + class c4_IntProp; + class c4_LongProp; + class c4_FloatProp; + class c4_DoubleProp; + class c4_StringProp; + class c4_BytesProp; + class c4_ViewProp; + + // Everything below is part of the implementation, not for public use + + class c4_Sequence; // a collection of rows + + class c4_Reference; // refers to the actual data values + class c4_IntRef; + class c4_LongRef; + class c4_FloatRef; + class c4_DoubleRef; + class c4_BytesRef; + class c4_StringRef; + class c4_ViewRef; + + class c4_Dependencies; // not defined here + class c4_Handler; // not defined here + class c4_Notifier; // not defined here + class c4_Persist; // not defined here + +//--------------------------------------------------------------------------- + + // determine whether we need to include "mk4dll.h" to link as DLL +#if defined (MKDLL_EXPORTS) && !defined (q4_KITDLL) +#define q4_KITDLL 1 +#endif + + // omit floats and doubles in small model 16-bit Intel builds +#if defined (_DOS) && defined (_M_I86SM) && !defined (q4_TINY) +#define q4_TINY 1 +#endif + + // and here's the other end of the scale... +#if !defined (_WIN32) && !defined (q4_LONG64) +#if (defined (_PA_RISC2_0) && defined(__hpux)) || defined (__powerpc64__) || defined(__sparcv9) || \ + defined (__x86_64__) || defined (__s390x__) || defined (__alpha) || defined (__mips64) || \ + (defined (__ia64) && (!defined (__HP_aCC) || defined(__LP64__))) +#define q4_LONG64 1 +#endif +#endif + + // default to inlining for maximum performance +#if !defined (q4_INLINE) +#define q4_INLINE 1 +#endif + +//--------------------------------------------------------------------------- + + // Borland C++ and C++ Builder +#if defined (__BORLANDC__) + // by default, if runtime is linked as a DLL, then so is Metakit +#if defined (_RTLDLL) && !defined (q4_KITDLL) +#define q4_KITDLL 1 +#endif + + // Borland 5.0 supports the bool datatype +#if __BORLANDC__ >= 0x500 +#define q4_BOOL 1 +#endif +#endif // __BORLANDC__ + + // IRIX supports the bool datatype + // define before gcc to cover both the gcc and MipsPRO compiler +#if defined (sgi) +#define q4_BOOL 1 +#undef bool +#undef true +#undef false +#endif + + // GNU gcc/egcs +#if defined (__GNUC__) +#ifndef q4_BOOL +#define q4_BOOL 1 +#endif +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 +#endif +#endif + + // HP aCC +#if defined (__HP_aCC) +#ifndef HAVE_LONG_LONG +#define HAVE_LONG_LONG 1 +#endif +#endif + + // Metrowerks CodeWarrior +#if defined (__MWERKS__) +#if __option(bool) +#define q4_BOOL 1 // bool datatype is optionally supported + // undef, these conflict with c4_Storage::c4_Storage overloading +#undef bool +#undef true +#undef false +#endif +#endif + + // Microsoft Visual C++ +#if defined (_MSC_VER) + // MSVC 5.0 supports the bool datatype, MSVC 4.x has no namespaces +#if _MSC_VER >= 1100 +#define q4_BOOL 1 +#define LONG_LONG __int64 +#else +#define q4_NO_NS 1 +#endif + + // a kludge to avoid having to use ugly DLL exprt defs in this header +#pragma warning(disable: 4273) // inconsistent dll linkage +#endif // _MSC_VER + +//--------------------------------------------------------------------------- +// Other definitions needed by the public Metakit library header files + +#if !q4_BOOL && !q4_STD // define a bool datatype +#define false 0 +#define true 1 +#define bool int +#endif + +#if q4_KITDLL // add declaration specifiers +#include "mk4dll.h" +#endif + +#if q4_INLINE // enable inline expansion +#define d4_inline inline +#else +#define d4_inline +#endif + +typedef unsigned char t4_byte; // create typedefs for t4_byte, etc. + +#if q4_LONG64 +typedef int t4_i32; // if longs are 64b, then int must be 32b +#else +typedef long t4_i32; // if longs aren't 64b, then they are 32b +#endif + +#if q4_LONG64 // choose a way to represent 64b integers +typedef long t4_i64; +#elif defined (LONG_LONG) +typedef LONG_LONG t4_i64; +#elif HAVE_LONG_LONG +typedef long long t4_i64; +#else +struct t4_i64 { long l1; long l2; }; +bool operator== (const t4_i64 a_, const t4_i64 b_); +bool operator< (const t4_i64 a_, const t4_i64 b_); +#endif + +//--------------------------------------------------------------------------- + +class c4_View +{ +protected: + c4_Sequence* _seq; + +public: +/* Construction / destruction / assignment */ + c4_View (c4_Sequence* =0); + c4_View (c4_CustomViewer*); + c4_View (c4_Stream*); + c4_View (const c4_Property& property_); + c4_View (const c4_View&); + ~c4_View (); + + c4_View& operator= (const c4_View&); + c4_Persist* Persist() const; // added 16-11-2000 to simplify c4_Storage + +/* Getting / setting the number of rows */ + int GetSize() const; + void SetSize(int, int =-1); + + void RemoveAll(); + +/*: Getting / setting individual elements */ + c4_RowRef GetAt(int) const; + c4_RowRef operator[] (int) const; + + void SetAt(int, const c4_RowRef&); + c4_RowRef ElementAt(int); + + bool GetItem(int, int, c4_Bytes&) const; + void SetItem(int, int, const c4_Bytes&) const; + +/* These can increase the number of rows */ + void SetAtGrow(int, const c4_RowRef&); + int Add(const c4_RowRef&); + +/* Insertion / deletion of rows */ + void InsertAt(int, const c4_RowRef&, int =1); + void RemoveAt(int, int =1); + void InsertAt(int, const c4_View&); + + bool IsCompatibleWith(const c4_View&) const; + void RelocateRows(int, int, c4_View&, int); + +/* Dealing with the properties of this view */ + int NumProperties() const; + const c4_Property& NthProperty(int) const; + int FindProperty(int); + int FindPropIndexByName(const char*) const; + c4_View Duplicate() const; + c4_View Clone() const; + int AddProperty(const c4_Property&); + c4_View operator, (const c4_Property&) const; + + const char* Description() const; + +/* Derived views */ + c4_View Sort() const; + c4_View SortOn(const c4_View&) const; + c4_View SortOnReverse(const c4_View&, const c4_View&) const; + + c4_View Select(const c4_RowRef&) const; + c4_View SelectRange(const c4_RowRef&, const c4_RowRef&) const; + + c4_View Project(const c4_View&) const; + c4_View ProjectWithout(const c4_View&) const; + + int GetIndexOf(const c4_RowRef&) const; + int RestrictSearch(const c4_RowRef&, int&, int&); + +/* Custom views */ + c4_View Slice(int, int =-1, int =1) const; + c4_View Product(const c4_View&) const; + c4_View RemapWith(const c4_View&) const; + c4_View Pair(const c4_View&) const; + c4_View Concat(const c4_View&) const; + c4_View Rename(const c4_Property&, const c4_Property&) const; + + c4_View GroupBy(const c4_View&, const c4_ViewProp&) const; + c4_View Counts(const c4_View&, const c4_IntProp&) const; + c4_View Unique() const; + + c4_View Union(const c4_View&) const; + c4_View Intersect(const c4_View&) const; + c4_View Different(const c4_View&) const; + c4_View Minus(const c4_View&) const; + + c4_View JoinProp(const c4_ViewProp&, bool =false) const; + c4_View Join(const c4_View&, const c4_View&, bool =false) const; + + c4_View ReadOnly() const; + c4_View Hash(const c4_View&, int =1) const; + c4_View Blocked() const; + c4_View Ordered(int =1) const; + c4_View Indexed(const c4_View&, const c4_View&, bool =false) const; + +/* Searching */ + int Find(const c4_RowRef&, int =0) const; + int Search(const c4_RowRef&) const; + int Locate(const c4_RowRef&, int* =0) const; + +/* Comparing view contents */ + int Compare(const c4_View&) const; + + friend bool operator== (const c4_View&, const c4_View&); + friend bool operator!= (const c4_View&, const c4_View&); + friend bool operator< (const c4_View&, const c4_View&); + friend bool operator> (const c4_View&, const c4_View&); + friend bool operator<= (const c4_View&, const c4_View&); + friend bool operator>= (const c4_View&, const c4_View&); + +protected: + void _IncSeqRef(); + void _DecSeqRef(); + + /// View references are allowed to peek inside view objects + friend class c4_ViewRef; + + // DROPPED: Structure() const; + // DROPPED: Description(const c4_View& view_); +}; + +//--------------------------------------------------------------------------- + +#if defined(os_aix) && defined(compiler_ibmcxx) && (compiler_ibmcxx > 500) + bool operator== (const c4_RowRef& a_, const c4_RowRef& b_); + bool operator!= (const c4_RowRef& a_, const c4_RowRef& b_); + bool operator<= (const c4_RowRef& a_, const c4_RowRef& b_); + bool operator>= (const c4_RowRef& a_, const c4_RowRef& b_); + bool operator> (const c4_RowRef& a_, const c4_RowRef& b_); + bool operator< (const c4_RowRef& a_, const c4_RowRef& b_); +#endif + +class c4_Cursor +{ +public: + /// Pointer to the sequence + c4_Sequence* _seq; + /// Current index into the sequence + int _index; + +/* Construction / destruction / dereferencing */ + /// Construct a new cursor + c4_Cursor (c4_Sequence&, int); + + /// Dereference this cursor to "almost" a row + c4_RowRef operator* () const; + + /// This is the same as *(cursor + offset) + c4_RowRef operator[] (int) const; + +/* Stepping the iterator forwards / backwards */ + /// Pre-increment the cursor + c4_Cursor& operator++ (); + /// Post-increment the cursor + c4_Cursor operator++ (int); + /// Pre-decrement the cursor + c4_Cursor& operator-- (); + /// Post-decrement the cursor + c4_Cursor operator-- (int); + + /// Advance by a given offset + c4_Cursor& operator+= (int); + /// Back up by a given offset + c4_Cursor& operator-= (int); + + /// Subtract a specified offset + c4_Cursor operator- (int) const; + /// Return the distance between two cursors + int operator- (c4_Cursor) const; + + /// Add specified offset + friend c4_Cursor operator+ (c4_Cursor, int); + /// Add specified offset to cursor + friend c4_Cursor operator+ (int, c4_Cursor); + +/* Comparing row positions */ + /// Return true if both cursors are equal + friend bool operator== (c4_Cursor, c4_Cursor); + /// Return true if both cursors are not equal + friend bool operator!= (c4_Cursor, c4_Cursor); + /// True if first cursor is less than second cursor + friend bool operator< (c4_Cursor, c4_Cursor); + /// True if first cursor is greater than second cursor + friend bool operator> (c4_Cursor, c4_Cursor); + /// True if first cursor is less or equal to second cursor + friend bool operator<= (c4_Cursor, c4_Cursor); + /// True if first cursor is greater or equal to second cursor + friend bool operator>= (c4_Cursor, c4_Cursor); + +/* Comparing row contents */ + /// Return true if the contents of both rows are equal + friend bool operator== (const c4_RowRef&, const c4_RowRef&); + /// Return true if the contents of both rows are not equal + friend bool operator!= (const c4_RowRef&, const c4_RowRef&); + /// True if first row is less than second row + friend bool operator< (const c4_RowRef&, const c4_RowRef&); + /// True if first row is greater than second row + friend bool operator> (const c4_RowRef&, const c4_RowRef&); + /// True if first row is less or equal to second row + friend bool operator<= (const c4_RowRef&, const c4_RowRef&); + /// True if first row is greater or equal to second row + friend bool operator>= (const c4_RowRef&, const c4_RowRef&); +}; + +//--------------------------------------------------------------------------- + +class c4_RowRef +{ + /// A row reference is a cursor in disguise + c4_Cursor _cursor; + +public: +/* General operations */ + /// Assign the value of another row to this one + c4_RowRef operator= (const c4_RowRef&); + /// Return the cursor associated to this row + c4_Cursor operator& () const; + /// Return the underlying container view + c4_View Container() const; + +protected: + /// Constructor, not for general use + c4_RowRef (c4_Cursor); + + friend class c4_Cursor; + friend class c4_Row; +}; + +//--------------------------------------------------------------------------- +/// An entry in a collection with copy semantics. +// +// Rows can exist by themselves and as contents of views. Row assignment +// implies that a copy of the contents of the originating row is made. +// +// A row is implemented as an unattached view with exactly one element. + +class c4_Row : public c4_RowRef +{ +public: + /// Construct a row with no properties + c4_Row (); + /// Construct a row from another one + c4_Row (const c4_Row&); + /// Construct a row copy from a row reference + c4_Row (const c4_RowRef&); + /// Destructor + ~c4_Row (); + + /// Assign a copy of another row to this one + c4_Row& operator= (const c4_Row&); + /// Copy another row to this one + c4_Row& operator= (const c4_RowRef&); + + /// Add all properties and values into this row + void ConcatRow(const c4_RowRef&); + /// Return a new row which is the concatenation of two others + friend c4_Row operator+ (const c4_RowRef&, const c4_RowRef&); + +private: + static c4_Cursor Allocate(); + static void Release(c4_Cursor); +}; + +//--------------------------------------------------------------------------- + +class c4_Bytes +{ + union { + t4_byte _buffer [16]; + double _aligner; // on a Sparc, the int below wasn't enough... + }; + + t4_byte* _contents; + int _size; + bool _copy; + +public: + c4_Bytes (); + c4_Bytes (const void*, int); + c4_Bytes (const void*, int, bool); + c4_Bytes (const c4_Bytes&); + ~c4_Bytes (); + + c4_Bytes& operator= (const c4_Bytes&); + void Swap(c4_Bytes&); + + int Size() const; + const t4_byte* Contents() const; + + t4_byte* SetBuffer(int); + t4_byte* SetBufferClear(int); + + friend bool operator== (const c4_Bytes&, const c4_Bytes&); + friend bool operator!= (const c4_Bytes&, const c4_Bytes&); + +private: + void _MakeCopy(); + void _LoseCopy(); +}; + +//--------------------------------------------------------------------------- + +class c4_Storage : public c4_View +{ +public: + /// Construct streaming-only storage object + c4_Storage (); + /// Construct a storage using the specified strategy handler + c4_Storage (c4_Strategy&, bool =false, int =1); + /// Construct a storage object, keeping the current structure + c4_Storage (const char*, int); + /// Reconstruct a storage object from a suitable view + c4_Storage (const c4_View&); + /// Destructor, usually closes file, but does not commit by default + ~c4_Storage (); + + void SetStructure(const char*); + bool AutoCommit(bool =true); + c4_Strategy& Strategy() const; + const char* Description(const char* =0); + + bool SetAside(c4_Storage&); + c4_Storage* GetAside() const; + + bool Commit(bool =false); + bool Rollback(bool =false); + + c4_ViewRef View(const char*); + c4_View GetAs(const char*); + + bool LoadFrom(c4_Stream&); + void SaveTo(c4_Stream&); + + //DROPPED: c4_Storage (const char* filename_, const char* description_); + //DROPPED: c4_View Store(const char* name_, const c4_View& view_); + //DROPPED: c4_HandlerSeq& RootTable() const; + //DROPPED: c4_RowRef xContents() const; + +private: + void Initialize(c4_Strategy&, bool, int); +}; + +//--------------------------------------------------------------------------- + +class c4_Property +{ + short _id; + char _type; + +public: + /// Construct a new property with the give type and id + c4_Property (char, int); + /// Construct a new property with the give type and name + c4_Property (char, const char*); + ~c4_Property (); + + c4_Property (const c4_Property&); + void operator= (const c4_Property&); + + const char* Name() const; + char Type() const; + + int GetId() const; + + c4_Reference operator() (const c4_RowRef&) const; + + void Refs(int) const; + + c4_View operator, (const c4_Property&) const; + + static void CleanupInternalData(); +}; + + /// Integer properties. +class c4_IntProp : public c4_Property +{ +public: + /// Construct a new property + c4_IntProp (const char*); + /// Destructor + ~c4_IntProp (); + + /// Get or set an integer property in a row + c4_IntRef operator() (const c4_RowRef&) const; + /// Get an integer property in a row + t4_i32 Get(const c4_RowRef&) const; + /// Set an integer property in a row + void Set(const c4_RowRef&, t4_i32) const; + + /// Creates a row with one integer, shorthand for AsRow. + c4_Row operator[] (t4_i32) const; + /// Creates a row with one integer. + c4_Row AsRow(t4_i32) const; +}; + +#if !q4_TINY + + /// Long int properties. +class c4_LongProp : public c4_Property +{ +public: + /// Construct a new property + c4_LongProp (const char*); + /// Destructor + ~c4_LongProp (); + + /// Get or set a long int property in a row + c4_LongRef operator() (const c4_RowRef&) const; + /// Get a long int property in a row + t4_i64 Get(const c4_RowRef&) const; + /// Set a long int property in a row + void Set(const c4_RowRef&, t4_i64) const; + + /// Creates a row with one long int, shorthand for AsRow. + c4_Row operator[] (t4_i64) const; + /// Creates a row with one long int. + c4_Row AsRow(t4_i64) const; +}; + + /// Floating point properties. +class c4_FloatProp : public c4_Property +{ +public: + /// Construct a new property + c4_FloatProp (const char*); + /// Destructor + ~c4_FloatProp (); + + /// Get or set a floating point property in a row + c4_FloatRef operator() (const c4_RowRef&) const; + /// Get a floating point property in a row + double Get(const c4_RowRef&) const; + /// Set a floating point property in a row + void Set(const c4_RowRef&, double) const; + + /// Create a row with one floating point value, shorthand for AsRow + c4_Row operator[] (double) const; + /// Create a row with one floating point value + c4_Row AsRow(double) const; +}; + + /// Double precision properties. +class c4_DoubleProp : public c4_Property +{ +public: + /// Construct a new property. + c4_DoubleProp (const char*); + /// Destructor + ~c4_DoubleProp (); + + /// Get or set a double precision property in a row + c4_DoubleRef operator() (const c4_RowRef&) const; + /// Get a double precision property in a row + double Get(const c4_RowRef&) const; + /// Set a double precision property in a row + void Set(const c4_RowRef&, double) const; + + /// Create a row with one double precision value, shorthand for AsRow + c4_Row operator[] (double) const; + /// Create a row with one double precision value + c4_Row AsRow(double) const; +}; +#endif // !q4_TINY + + /// String properties. +class c4_StringProp : public c4_Property +{ +public: + /// Construct a new property + c4_StringProp (const char*); + /// Destructor + ~c4_StringProp (); + + /// Get or set a string property in a row + c4_StringRef operator() (const c4_RowRef&) const; + /// Get a string property in a row + const char* Get(const c4_RowRef&) const; + /// Set a string property in a row + void Set(const c4_RowRef&, const char*) const; + + /// Create a row with one string, shorthand for AsRow + c4_Row operator[] (const char*) const; + /// Create a row with one string + c4_Row AsRow(const char*) const; +}; + + /// Binary properties. +class c4_BytesProp : public c4_Property +{ +public: + /// Construct a new property + c4_BytesProp (const char*); + /// Destructor + ~c4_BytesProp (); + + /// Get or set a bytes property in a row + c4_BytesRef operator() (const c4_RowRef&) const; + /// Get a bytes property in a row + c4_Bytes Get(const c4_RowRef&) const; + /// Set a bytes property in a row + void Set(const c4_RowRef&, const c4_Bytes&) const; + + /// Create a row with one bytes object, shorthand for AsRow + c4_Row operator[] (const c4_Bytes&) const; + /// Create a row with one bytes object + c4_Row AsRow(const c4_Bytes&) const; +}; + + /// View properties. +class c4_ViewProp : public c4_Property +{ +public: + /// Construct a new property + c4_ViewProp (const char*); + /// Destructor + ~c4_ViewProp (); + + /// Get or set a view property in a row + c4_ViewRef operator() (const c4_RowRef&) const; + /// Get a view property in a row + c4_View Get(const c4_RowRef&) const; + /// Set a view property in a row + void Set(const c4_RowRef&, const c4_View&) const; + + /// Create a row with one view, shorthand for AsRow + c4_Row operator[] (const c4_View&) const; + /// Create a row with one view + c4_Row AsRow(const c4_View&) const; +}; + +//--------------------------------------------------------------------------- + +class c4_CustomViewer +{ +protected: + /// Constructor, must be overriden in derived class + c4_CustomViewer (); +public: + /// Destructor + virtual ~c4_CustomViewer (); + + /// Return the structure of this view (initialization, called once) + virtual c4_View GetTemplate() = 0; + /// Return the number of rows in this view + virtual int GetSize() = 0; + int Lookup(const c4_RowRef&, int&); + virtual int Lookup(c4_Cursor, int&); + /// Fetch one data item, return it as a generic data value + virtual bool GetItem(int, int, c4_Bytes&) = 0; + virtual bool SetItem(int, int, const c4_Bytes&); + bool InsertRows(int, const c4_RowRef&, int =1); + virtual bool InsertRows(int, c4_Cursor, int =1); + virtual bool RemoveRows(int, int =1); +}; + +//--------------------------------------------------------------------------- +/// A stream is a virtual helper class to serialize in binary form. + +class c4_Stream +{ +public: + virtual ~c4_Stream (); + + /// Fetch some bytes sequentially + virtual int Read(void*, int) = 0; + /// Store some bytes sequentially + virtual bool Write(const void*, int) = 0; +}; + +//--------------------------------------------------------------------------- +/// A strategy encapsulates code dealing with the I/O system interface. + +class c4_Strategy +{ +public: + c4_Strategy (); + virtual ~c4_Strategy (); + + virtual bool IsValid() const; + virtual int DataRead(t4_i32, void*, int); + virtual void DataWrite(t4_i32, const void*, int); + virtual void DataCommit(t4_i32); + virtual void ResetFileMapping(); + virtual t4_i32 FileSize(); + virtual t4_i32 FreshGeneration(); + + void SetBase(t4_i32); + t4_i32 EndOfData(t4_i32 =-1); + + /// True if the storage format is not native (default is false) + bool _bytesFlipped; + /// Error code of last failed I/O operation, zero if I/O was ok + int _failure; + /// First byte in file mapping, zero if not active + const t4_byte* _mapStart; + /// Number of bytes filled with active data + t4_i32 _dataSize; + /// All file positions are relative to this offset + t4_i32 _baseOffset; + /// The root position of the shallow tree walks + t4_i32 _rootPos; + /// The size of the root column + t4_i32 _rootLen; +}; + +//--------------------------------------------------------------------------- +/// A sequence is an abstract base class for views on ranges of records. +// +// Sequences represent arrays of rows (or indexed collections / tables). +// Insertion and removal of entries is allowed, but could take linear time. +// A reference count is maintained to decide when the object should go away. + +class c4_Sequence +{ + /// Reference count + int _refCount; + /// Pointer to dependency list, or null if nothing depends on this + c4_Dependencies* _dependencies; + +protected: + /// Optimization: cached property index + int _propertyLimit; + /// Optimization: property map for faster access + short* _propertyMap; // see c4_HandlerSeq::Reset() + /// allocated on first use by c4_Sequence::Buffer() + c4_Bytes* _tempBuf; + +public: +/* General */ + /// Abstract constructor + c4_Sequence (); + + virtual int Compare(int, c4_Cursor) const; + virtual bool RestrictSearch(c4_Cursor, int&, int&); + void SetAt(int, c4_Cursor); + virtual int RemapIndex(int, const c4_Sequence*) const; + +/* Reference counting */ + void IncRef(); + void DecRef(); + int NumRefs() const; + +/* Adding / removing rows */ + /// Return the current number of rows + virtual int NumRows() const = 0; + void Resize(int, int =-1); + + virtual void InsertAt(int, c4_Cursor, int =1); + virtual void RemoveAt(int, int =1); + virtual void Move(int, int); + +/* Properties */ + int NthPropId(int) const; + int PropIndex(int); + int PropIndex(const c4_Property&); + + /// Return the number of data handlers in this sequence + virtual int NumHandlers() const = 0; + /// Return a reference to the N-th handler in this sequence + virtual c4_Handler& NthHandler(int) const = 0; + /// Return the context of the N-th handler in this sequence + virtual const c4_Sequence* HandlerContext(int) const = 0; + /// Add the specified data handler to this sequence + virtual int AddHandler(c4_Handler*) = 0; + /// Create a handler of the appropriate type + virtual c4_Handler* CreateHandler(const c4_Property&) = 0; + + virtual const char* Description(); + +/* Element access */ + /// Return width of specified data item + virtual int ItemSize(int, int); + /// Retrieve one data item from this sequence + virtual bool Get(int, int, c4_Bytes&); + /// Store a data item into this sequence + virtual void Set(int, const c4_Property&, const c4_Bytes&); + +/* Dependency notification */ + void Attach(c4_Sequence*); + void Detach(c4_Sequence*); + /// Return a pointer to the dependencies, or null + c4_Dependencies* GetDependencies() const; + + virtual c4_Notifier* PreChange(c4_Notifier&); + virtual void PostChange(c4_Notifier&); + + const char* UseTempBuffer(const char*); + +protected: + virtual ~c4_Sequence (); + + void ClearCache(); + +public: //! for c4_Table::Sequence setup + virtual void SetNumRows(int) = 0; + virtual c4_Persist* Persist() const; + + c4_Bytes& Buffer(); + +private: + c4_Sequence (const c4_Sequence&); // not implemented + void operator= (const c4_Sequence&); // not implemented +}; + +//--------------------------------------------------------------------------- +/// A reference is used to get or set typed data, using derived classes. +// +// Objects of this class are only intended to be used as a temporary handle +// while getting and setting properties in a row. They are normally only +// constructed as result of function overload operators: "property (row)". + +class c4_Reference +{ +protected: + /// The cursor which points to the data + c4_Cursor _cursor; + /// The property associated to this reference + const c4_Property& _property; + +public: + /// Constructor + c4_Reference (const c4_RowRef&, const c4_Property&); + + /// Assignment of one data item + c4_Reference& operator= (const c4_Reference&); + + /// Return width of the referenced data item + int GetSize() const; + /// Retrieve the value of the referenced data item + bool GetData(c4_Bytes&) const; + /// Store a value into the referenced data item + void SetData(const c4_Bytes&) const; + + /// Return true if the contents of both references is equal + friend bool operator== (const c4_Reference&, const c4_Reference&); + /// Return true if the contents of both references is not equal + friend bool operator!= (const c4_Reference&, const c4_Reference&); + +private: + void operator& () const; // not implemented +}; + +//--------------------------------------------------------------------------- + + /// Used to get or set integer values. +class c4_IntRef : public c4_Reference +{ +public: + /// Constructor + c4_IntRef (const c4_Reference&); + /// Get the value as integer + operator t4_i32 () const; + /// Set the value to the specified integer + c4_IntRef& operator= (t4_i32); +}; + +#if !q4_TINY + + /// Used to get or set long int values. +class c4_LongRef : public c4_Reference +{ +public: + /// Constructor + c4_LongRef (const c4_Reference&); + /// Get the value as long int + operator t4_i64 () const; + /// Set the value to the specified long int + c4_LongRef& operator= (t4_i64); +}; + + /// Used to get or set floating point values. +class c4_FloatRef : public c4_Reference +{ +public: + /// Constructor + c4_FloatRef (const c4_Reference&); + /// Get the value as floating point + operator double () const; + /// Set the value to the specified floating point + c4_FloatRef& operator= (double); +}; + + /// Used to get or set double precision values. +class c4_DoubleRef : public c4_Reference +{ +public: + /// Constructor + c4_DoubleRef (const c4_Reference&); + /// Get the value as floating point + operator double () const; + /// Set the value to the specified floating point + c4_DoubleRef& operator= (double); +}; + +#endif // !q4_TINY + + /// Used to get or set binary object values. +class c4_BytesRef : public c4_Reference +{ +public: + /// Constructor + c4_BytesRef (const c4_Reference&); + /// Get the value as binary object + operator c4_Bytes () const; + /// Set the value to the specified binary object + c4_BytesRef& operator= (const c4_Bytes&); + + /// Fetch data from the memo field, up to end if length is zero + c4_Bytes Access(t4_i32, int =0) const; + /// Store data, resize by diff_ bytes, return true if successful + bool Modify(const c4_Bytes&, t4_i32, int =0) const; +}; + + /// Used to get or set string values. +class c4_StringRef : public c4_Reference +{ +public: + /// Constructor + c4_StringRef (const c4_Reference&); + /// Get the value as string + operator const char* () const; + /// Set the value to the specified string + c4_StringRef& operator= (const char*); +}; + + /// Used to get or set view values. +class c4_ViewRef : public c4_Reference +{ +public: + /// Constructor + c4_ViewRef (const c4_Reference&); + /// Get the value as view + operator c4_View () const; + /// Set the value to the specified view + c4_ViewRef& operator= (const c4_View&); +}; + +//--------------------------------------------------------------------------- +// Debug logging option, can generate log of changes for one/all properties + +#if q4_LOGPROPMODS +FILE* f4_LogPropMods(FILE* fp_, int propId_); +#else +#define f4_LogPropMods(a,b) 0 +#endif + +//--------------------------------------------------------------------------- + +#if q4_INLINE +#include "mk4.inl" +#endif + +//--------------------------------------------------------------------------- + +#endif // __MK4_H__ |