1// mk4.h -- 2// $Id: mk4.h 1669 2007-06-16 00:23:25Z jcw $ 3// This is part of Metakit, see http://www.equi4.com/metakit.html 4 5/** @file 6 * Main Metakit library include file 7 */ 8 9#ifndef __MK4_H__ 10#define __MK4_H__ 11 12//--------------------------------------------------------------------------- 13// 14// TITLE 15// 16// The Metakit Library, by Jean-Claude Wippler, Equi4 Software, NL. 17// 18// DESCRIPTION 19// 20// Structured data storage with commit / rollback and on-demand loading. 21// 22// ACKNOWLEDGEMENTS 23// 24// To Liesbeth and Myra, for making this possible. 25// 26//--------------------------------------------------------------------------- 27// 28// NAMING CONVENTIONS PREFIX REMARKS 29// 30// Compile time options q4_ Always defined as 1 or 0, capitalized 31// Preprocessor defines d4_ Use with "#ifdef" or "#if defined()" 32// Classes c4_ Classes, listed at start of headers 33// Typedefs t4_ Type definitions, if outside classes 34// Global functions f4_ Internal, these are rarely defined 35// 36// Member functions Start in uppercase 37// Instance variables _ And start in lowercase 38// Static members _ And start in uppercase 39// 40// Local variable names Start in lowercase 41// Formal parameter names Start lowercase, end with underscore 42// 43//--------------------------------------------------------------------------- 44 45/// Current release = 100 * major + 10 * minor + maintenance 46#define d4_MetakitLibraryVersion 249 // 2.4.9.7 release, Jun 16, 2007 47#define d4_MetaKitLibraryVersion d4_MetakitLibraryVersion // compat, yuck 48 49//--------------------------------------------------------------------------- 50// Declarations in this file 51 52class c4_View; // a view on underlying data 53class c4_Cursor; // an index into a view 54class c4_RowRef; // a reference to a row 55class c4_Row; // one row in a view 56class c4_Bytes; // used to pass around generic data 57class c4_Storage; // manages view persistence 58class c4_CustomViewer; // used for customizable views 59class c4_Stream; // abstract stream class 60class c4_Strategy; // system and file interface 61 62class c4_Property; // for access inside rows 63class c4_IntProp; 64class c4_LongProp; 65class c4_FloatProp; 66class c4_DoubleProp; 67class c4_StringProp; 68class c4_BytesProp; 69class c4_ViewProp; 70 71// Everything below is part of the implementation, not for public use 72 73class c4_Sequence; // a collection of rows 74 75class c4_Reference; // refers to the actual data values 76class c4_IntRef; 77class c4_LongRef; 78class c4_FloatRef; 79class c4_DoubleRef; 80class c4_BytesRef; 81class c4_StringRef; 82class c4_ViewRef; 83 84class c4_Dependencies; // not defined here 85class c4_Handler; // not defined here 86class c4_Notifier; // not defined here 87class c4_Persist; // not defined here 88 89//--------------------------------------------------------------------------- 90 91// determine whether we need to include "mk4dll.h" to link as DLL 92#if defined (MKDLL_EXPORTS) && !defined (q4_KITDLL) 93#define q4_KITDLL 1 94#endif 95 96// omit floats and doubles in small model 16-bit Intel builds 97#if defined (_DOS) && defined (_M_I86SM) && !defined (q4_TINY) 98#define q4_TINY 1 99#endif 100 101// and here's the other end of the scale... 102#if !defined (_WIN32) && !defined (q4_LONG64) 103#if defined (_PA_RISC2_0) || defined (__powerpc64__) || defined(__sparcv9) || \ 104defined(__x86_64__) || defined(__s390x__) || defined(__alpha) || \ 105 (defined(__ia64) && (!defined(__HP_aCC) || defined(__LP64__))) || \ 106 (defined(__APPLE__) && defined(__LP64__)) 107#define q4_LONG64 1 108#endif 109#endif 110 111// default to inlining for maximum performance 112#if !defined (q4_INLINE) 113#define q4_INLINE 1 114#endif 115 116//--------------------------------------------------------------------------- 117 118// Borland C++ and C++ Builder 119#if defined (__BORLANDC__) 120// by default, if runtime is linked as a DLL, then so is Metakit 121#if defined (_RTLDLL) && !defined (q4_KITDLL) 122#define q4_KITDLL 1 123#endif 124 125// Borland 5.0 supports the bool datatype 126#if __BORLANDC__ >= 0x500 127#define q4_BOOL 1 128#endif 129#endif // __BORLANDC__ 130 131// IRIX supports the bool datatype 132// define before gcc to cover both the gcc and MipsPRO compiler 133#if defined (sgi) 134#define q4_BOOL 1 135#undef bool 136#undef true 137#undef false 138#endif 139 140// GNU gcc/egcs 141#if defined (__GNUC__) 142#ifndef q4_BOOL 143#define q4_BOOL 1 144#endif 145#ifndef HAVE_LONG_LONG 146#define HAVE_LONG_LONG 1 147#endif 148#endif 149 150// HP aCC 151#if defined (__HP_aCC) 152#ifndef HAVE_LONG_LONG 153#define HAVE_LONG_LONG 1 154#endif 155#endif 156 157// Metrowerks CodeWarrior 158#if defined (__MWERKS__) 159#if __option(bool) 160#define q4_BOOL 1 // bool datatype is optionally supported 161// undef, these conflict with c4_Storage::c4_Storage overloading 162#undef bool 163#undef true 164#undef false 165#endif 166#endif 167 168// Microsoft Visual C++ 169#if defined (_MSC_VER) 170// MSVC 5.0 supports the bool datatype, MSVC 4.x has no namespaces 171#if _MSC_VER >= 1100 172#define q4_BOOL 1 173#define LONG_LONG __int64 174#else 175#define q4_NO_NS 1 176#endif 177 178// a kludge to avoid having to use ugly DLL exprt defs in this header 179#pragma warning(disable: 4273) // inconsistent dll linkage 180#endif // _MSC_VER 181 182//--------------------------------------------------------------------------- 183// Other definitions needed by the public Metakit library header files 184 185#if !q4_BOOL && !q4_STD // define a bool datatype 186#define false 0 187#define true 1 188#define bool int 189#endif 190 191#if q4_KITDLL // add declaration specifiers 192#include "mk4dll.h" 193#endif 194 195#if q4_INLINE // enable inline expansion 196#define d4_inline inline 197#else 198#define d4_inline 199#endif 200 201typedef unsigned char t4_byte; // create typedefs for t4_byte, etc. 202 203#if q4_LONG64 204typedef int t4_i32; // if longs are 64b, then int must be 32b 205#else 206typedef long t4_i32; // if longs aren't 64b, then they are 32b 207#endif 208 209#if q4_LONG64 // choose a way to represent 64b integers 210typedef long t4_i64; 211#elif defined (LONG_LONG) 212typedef LONG_LONG t4_i64; 213#elif HAVE_LONG_LONG 214typedef long long t4_i64; 215#else 216struct t4_i64 { 217 long l1; 218 long l2; 219}; 220bool operator == (const t4_i64 a_, const t4_i64 b_); 221bool operator < (const t4_i64 a_, const t4_i64 b_); 222#endif 223 224//--------------------------------------------------------------------------- 225 226class c4_View { 227 protected: 228 c4_Sequence *_seq; 229 230 public: 231 /* Construction / destruction / assignment */ 232 c4_View(c4_Sequence * = 0); 233 c4_View(c4_CustomViewer*); 234 c4_View(c4_Stream*); 235 c4_View(const c4_Property &property_); 236 c4_View(const c4_View &); 237 ~c4_View(); 238 239 c4_View &operator = (const c4_View &); 240 c4_Persist *Persist()const; // added 16-11-2000 to simplify c4_Storage 241 242 /* Getting / setting the number of rows */ 243 int GetSize()const; 244 void SetSize(int, int = - 1); 245 246 void RemoveAll(); 247 248 /*: Getting / setting individual elements */ 249 c4_RowRef GetAt(int)const; 250 c4_RowRef operator[](int)const; 251 252 void SetAt(int, const c4_RowRef &); 253 c4_RowRef ElementAt(int); 254 255 bool GetItem(int, int, c4_Bytes &)const; 256 void SetItem(int, int, const c4_Bytes &)const; 257 258 /* These can increase the number of rows */ 259 void SetAtGrow(int, const c4_RowRef &); 260 int Add(const c4_RowRef &); 261 262 /* Insertion / deletion of rows */ 263 void InsertAt(int, const c4_RowRef &, int = 1); 264 void RemoveAt(int, int = 1); 265 void InsertAt(int, const c4_View &); 266 267 bool IsCompatibleWith(const c4_View &)const; 268 void RelocateRows(int, int, c4_View &, int); 269 270 /* Dealing with the properties of this view */ 271 int NumProperties()const; 272 const c4_Property &NthProperty(int)const; 273 int FindProperty(int); 274 int FindPropIndexByName(const char*)const; 275 c4_View Duplicate()const; 276 c4_View Clone()const; 277 int AddProperty(const c4_Property &); 278 c4_View operator, (const c4_Property &)const; 279 280 const char *Description()const; 281 282 /* Derived views */ 283 c4_View Sort()const; 284 c4_View SortOn(const c4_View &)const; 285 c4_View SortOnReverse(const c4_View &, const c4_View &)const; 286 287 c4_View Select(const c4_RowRef &)const; 288 c4_View SelectRange(const c4_RowRef &, const c4_RowRef &)const; 289 290 c4_View Project(const c4_View &)const; 291 c4_View ProjectWithout(const c4_View &)const; 292 293 int GetIndexOf(const c4_RowRef &)const; 294 int RestrictSearch(const c4_RowRef &, int &, int &); 295 296 /* Custom views */ 297 c4_View Slice(int, int = - 1, int = 1)const; 298 c4_View Product(const c4_View &)const; 299 c4_View RemapWith(const c4_View &)const; 300 c4_View Pair(const c4_View &)const; 301 c4_View Concat(const c4_View &)const; 302 c4_View Rename(const c4_Property &, const c4_Property &)const; 303 304 c4_View GroupBy(const c4_View &, const c4_ViewProp &)const; 305 c4_View Counts(const c4_View &, const c4_IntProp &)const; 306 c4_View Unique()const; 307 308 c4_View Union(const c4_View &)const; 309 c4_View Intersect(const c4_View &)const; 310 c4_View Different(const c4_View &)const; 311 c4_View Minus(const c4_View &)const; 312 313 c4_View JoinProp(const c4_ViewProp &, bool = false)const; 314 c4_View Join(const c4_View &, const c4_View &, bool = false)const; 315 316 c4_View ReadOnly()const; 317 c4_View Hash(const c4_View &, int = 1)const; 318 c4_View Blocked()const; 319 c4_View Ordered(int = 1)const; 320 c4_View Indexed(const c4_View &, const c4_View &, bool = false)const; 321 322 /* Searching */ 323 int Find(const c4_RowRef &, int = 0)const; 324 int Search(const c4_RowRef &)const; 325 int Locate(const c4_RowRef &, int * = 0)const; 326 327 /* Comparing view contents */ 328 int Compare(const c4_View &)const; 329 330 friend bool operator == (const c4_View &, const c4_View &); 331 friend bool operator != (const c4_View &, const c4_View &); 332 friend bool operator < (const c4_View &, const c4_View &); 333 friend bool operator > (const c4_View &, const c4_View &); 334 friend bool operator <= (const c4_View &, const c4_View &); 335 friend bool operator >= (const c4_View &, const c4_View &); 336 337 protected: 338 void _IncSeqRef(); 339 void _DecSeqRef(); 340 341 /// View references are allowed to peek inside view objects 342 friend class c4_ViewRef; 343 344 // DROPPED: Structure() const; 345 // DROPPED: Description(const c4_View& view_); 346}; 347 348//--------------------------------------------------------------------------- 349 350#if defined(os_aix) && defined(compiler_ibmcxx) && (compiler_ibmcxx > 500) 351bool operator == (const c4_RowRef &a_, const c4_RowRef &b_); 352bool operator != (const c4_RowRef &a_, const c4_RowRef &b_); 353bool operator <= (const c4_RowRef &a_, const c4_RowRef &b_); 354bool operator >= (const c4_RowRef &a_, const c4_RowRef &b_); 355bool operator > (const c4_RowRef &a_, const c4_RowRef &b_); 356bool operator < (const c4_RowRef &a_, const c4_RowRef &b_); 357#endif 358 359class c4_Cursor { 360 public: 361 /// Pointer to the sequence 362 c4_Sequence *_seq; 363 /// Current index into the sequence 364 int _index; 365 366 /* Construction / destruction / dereferencing */ 367 /// Construct a new cursor 368 c4_Cursor(c4_Sequence &, int); 369 370 /// Dereference this cursor to "almost" a row 371 c4_RowRef operator *()const; 372 373 /// This is the same as *(cursor + offset) 374 c4_RowRef operator[](int)const; 375 376 /* Stepping the iterator forwards / backwards */ 377 /// Pre-increment the cursor 378 c4_Cursor &operator++(); 379 /// Post-increment the cursor 380 c4_Cursor operator++(int); 381 /// Pre-decrement the cursor 382 c4_Cursor &operator--(); 383 /// Post-decrement the cursor 384 c4_Cursor operator--(int); 385 386 /// Advance by a given offset 387 c4_Cursor &operator += (int); 388 /// Back up by a given offset 389 c4_Cursor &operator -= (int); 390 391 /// Subtract a specified offset 392 c4_Cursor operator - (int)const; 393 /// Return the distance between two cursors 394 int operator - (c4_Cursor)const; 395 396 /// Add specified offset 397 friend c4_Cursor operator + (c4_Cursor, int); 398 /// Add specified offset to cursor 399 friend c4_Cursor operator + (int, c4_Cursor); 400 401 /* Comparing row positions */ 402 /// Return true if both cursors are equal 403 friend bool operator == (c4_Cursor, c4_Cursor); 404 /// Return true if both cursors are not equal 405 friend bool operator != (c4_Cursor, c4_Cursor); 406 /// True if first cursor is less than second cursor 407 friend bool operator < (c4_Cursor, c4_Cursor); 408 /// True if first cursor is greater than second cursor 409 friend bool operator > (c4_Cursor, c4_Cursor); 410 /// True if first cursor is less or equal to second cursor 411 friend bool operator <= (c4_Cursor, c4_Cursor); 412 /// True if first cursor is greater or equal to second cursor 413 friend bool operator >= (c4_Cursor, c4_Cursor); 414 415 /* Comparing row contents */ 416 /// Return true if the contents of both rows are equal 417 friend bool operator == (const c4_RowRef &, const c4_RowRef &); 418 /// Return true if the contents of both rows are not equal 419 friend bool operator != (const c4_RowRef &, const c4_RowRef &); 420 /// True if first row is less than second row 421 friend bool operator < (const c4_RowRef &, const c4_RowRef &); 422 /// True if first row is greater than second row 423 friend bool operator > (const c4_RowRef &, const c4_RowRef &); 424 /// True if first row is less or equal to second row 425 friend bool operator <= (const c4_RowRef &, const c4_RowRef &); 426 /// True if first row is greater or equal to second row 427 friend bool operator >= (const c4_RowRef &, const c4_RowRef &); 428}; 429 430//--------------------------------------------------------------------------- 431 432class c4_RowRef { 433 /// A row reference is a cursor in disguise 434 c4_Cursor _cursor; 435 436 public: 437 /* General operations */ 438 /// Assign the value of another row to this one 439 c4_RowRef operator = (const c4_RowRef &); 440 /// Return the cursor associated to this row 441 c4_Cursor operator &()const; 442 /// Return the underlying container view 443 c4_View Container()const; 444 445 protected: 446 /// Constructor, not for general use 447 c4_RowRef(c4_Cursor); 448 449 friend class c4_Cursor; 450 friend class c4_Row; 451}; 452 453//--------------------------------------------------------------------------- 454/// An entry in a collection with copy semantics. 455// 456// Rows can exist by themselves and as contents of views. Row assignment 457// implies that a copy of the contents of the originating row is made. 458// 459// A row is implemented as an unattached view with exactly one element. 460 461class c4_Row: public c4_RowRef { 462 public: 463 /// Construct a row with no properties 464 c4_Row(); 465 /// Construct a row from another one 466 c4_Row(const c4_Row &); 467 /// Construct a row copy from a row reference 468 c4_Row(const c4_RowRef &); 469 /// Destructor 470 ~c4_Row(); 471 472 /// Assign a copy of another row to this one 473 c4_Row &operator = (const c4_Row &); 474 /// Copy another row to this one 475 c4_Row &operator = (const c4_RowRef &); 476 477 /// Add all properties and values into this row 478 void ConcatRow(const c4_RowRef &); 479 /// Return a new row which is the concatenation of two others 480 friend c4_Row operator + (const c4_RowRef &, const c4_RowRef &); 481 482 private: 483 static c4_Cursor Allocate(); 484 static void Release(c4_Cursor); 485}; 486 487//--------------------------------------------------------------------------- 488 489class c4_Bytes { 490 union { 491 t4_byte _buffer[16]; 492 double _aligner; // on a Sparc, the int below wasn't enough... 493 }; 494 495 t4_byte *_contents; 496 int _size; 497 bool _copy; 498 499 public: 500 c4_Bytes(); 501 c4_Bytes(const void *, int); 502 c4_Bytes(const void *, int, bool); 503 c4_Bytes(const c4_Bytes &); 504 ~c4_Bytes(); 505 506 c4_Bytes &operator = (const c4_Bytes &); 507 void Swap(c4_Bytes &); 508 509 int Size()const; 510 const t4_byte *Contents()const; 511 512 t4_byte *SetBuffer(int); 513 t4_byte *SetBufferClear(int); 514 515 friend bool operator == (const c4_Bytes &, const c4_Bytes &); 516 friend bool operator != (const c4_Bytes &, const c4_Bytes &); 517 518 private: 519 void _MakeCopy(); 520 void _LoseCopy(); 521}; 522 523//--------------------------------------------------------------------------- 524 525class c4_Storage: public c4_View { 526 public: 527 /// Construct streaming-only storage object 528 c4_Storage(); 529 /// Construct a storage using the specified strategy handler 530 c4_Storage(c4_Strategy &, bool = false, int = 1); 531 /// Construct a storage object, keeping the current structure 532 c4_Storage(const char *, int); 533 /// Reconstruct a storage object from a suitable view 534 c4_Storage(const c4_View &); 535 /// Destructor, usually closes file, but does not commit by default 536 ~c4_Storage(); 537 538 void SetStructure(const char*); 539 bool AutoCommit(bool = true); 540 c4_Strategy &Strategy()const; 541 const char *Description(const char * = 0); 542 543 bool SetAside(c4_Storage &); 544 c4_Storage *GetAside()const; 545 546 bool Commit(bool = false); 547 bool Rollback(bool = false); 548 549 c4_ViewRef View(const char*); 550 c4_View GetAs(const char*); 551 552 bool LoadFrom(c4_Stream &); 553 void SaveTo(c4_Stream &); 554 555 t4_i32 FreeSpace(t4_i32 *bytes_ = 0); 556 557 //DROPPED: c4_Storage (const char* filename_, const char* description_); 558 //DROPPED: c4_View Store(const char* name_, const c4_View& view_); 559 //DROPPED: c4_HandlerSeq& RootTable() const; 560 //DROPPED: c4_RowRef xContents() const; 561 562 private: 563 void Initialize(c4_Strategy &, bool, int); 564}; 565 566//--------------------------------------------------------------------------- 567 568class c4_Property { 569 short _id; 570 char _type; 571 572 public: 573 /// Construct a new property with the give type and id 574 c4_Property(char, int); 575 /// Construct a new property with the give type and name 576 c4_Property(char, const char*); 577 ~c4_Property(); 578 579 c4_Property(const c4_Property &); 580 void operator = (const c4_Property &); 581 582 const char *Name()const; 583 char Type()const; 584 585 int GetId()const; 586 587 c4_Reference operator()(const c4_RowRef &)const; 588 589 void Refs(int)const; 590 591 c4_View operator, (const c4_Property &)const; 592 593 static void CleanupInternalData(); 594}; 595 596/// Integer properties. 597class c4_IntProp: public c4_Property { 598 public: 599 /// Construct a new property 600 c4_IntProp(const char*); 601 /// Destructor 602 ~c4_IntProp(); 603 604 /// Get or set an integer property in a row 605 c4_IntRef operator()(const c4_RowRef &)const; 606 /// Get an integer property in a row 607 t4_i32 Get(const c4_RowRef &)const; 608 /// Set an integer property in a row 609 void Set(const c4_RowRef &, t4_i32)const; 610 611 /// Creates a row with one integer, shorthand for AsRow. 612 c4_Row operator[](t4_i32)const; 613 /// Creates a row with one integer. 614 c4_Row AsRow(t4_i32)const; 615}; 616 617#if !q4_TINY 618 619/// Long int properties. 620class c4_LongProp: public c4_Property { 621 public: 622 /// Construct a new property 623 c4_LongProp(const char*); 624 /// Destructor 625 ~c4_LongProp(); 626 627 /// Get or set a long int property in a row 628 c4_LongRef operator()(const c4_RowRef &)const; 629 /// Get a long int property in a row 630 t4_i64 Get(const c4_RowRef &)const; 631 /// Set a long int property in a row 632 void Set(const c4_RowRef &, t4_i64)const; 633 634 /// Creates a row with one long int, shorthand for AsRow. 635 c4_Row operator[](t4_i64)const; 636 /// Creates a row with one long int. 637 c4_Row AsRow(t4_i64)const; 638}; 639 640/// Floating point properties. 641class c4_FloatProp: public c4_Property { 642 public: 643 /// Construct a new property 644 c4_FloatProp(const char*); 645 /// Destructor 646 ~c4_FloatProp(); 647 648 /// Get or set a floating point property in a row 649 c4_FloatRef operator()(const c4_RowRef &)const; 650 /// Get a floating point property in a row 651 double Get(const c4_RowRef &)const; 652 /// Set a floating point property in a row 653 void Set(const c4_RowRef &, double)const; 654 655 /// Create a row with one floating point value, shorthand for AsRow 656 c4_Row operator[](double)const; 657 /// Create a row with one floating point value 658 c4_Row AsRow(double)const; 659}; 660 661/// Double precision properties. 662class c4_DoubleProp: public c4_Property { 663 public: 664 /// Construct a new property. 665 c4_DoubleProp(const char*); 666 /// Destructor 667 ~c4_DoubleProp(); 668 669 /// Get or set a double precision property in a row 670 c4_DoubleRef operator()(const c4_RowRef &)const; 671 /// Get a double precision property in a row 672 double Get(const c4_RowRef &)const; 673 /// Set a double precision property in a row 674 void Set(const c4_RowRef &, double)const; 675 676 /// Create a row with one double precision value, shorthand for AsRow 677 c4_Row operator[](double)const; 678 /// Create a row with one double precision value 679 c4_Row AsRow(double)const; 680}; 681#endif // !q4_TINY 682 683/// String properties. 684class c4_StringProp: public c4_Property { 685 public: 686 /// Construct a new property 687 c4_StringProp(const char*); 688 /// Destructor 689 ~c4_StringProp(); 690 691 /// Get or set a string property in a row 692 c4_StringRef operator()(const c4_RowRef &)const; 693 /// Get a string property in a row 694 const char *Get(const c4_RowRef &)const; 695 /// Set a string property in a row 696 void Set(const c4_RowRef &, const char*)const; 697 698 /// Create a row with one string, shorthand for AsRow 699 c4_Row operator[](const char*)const; 700 /// Create a row with one string 701 c4_Row AsRow(const char*)const; 702}; 703 704/// Binary properties. 705class c4_BytesProp: public c4_Property { 706 public: 707 /// Construct a new property 708 c4_BytesProp(const char*); 709 /// Destructor 710 ~c4_BytesProp(); 711 712 /// Get or set a bytes property in a row 713 c4_BytesRef operator()(const c4_RowRef &)const; 714 /// Get a bytes property in a row 715 c4_Bytes Get(const c4_RowRef &)const; 716 /// Set a bytes property in a row 717 void Set(const c4_RowRef &, const c4_Bytes &)const; 718 719 /// Create a row with one bytes object, shorthand for AsRow 720 c4_Row operator[](const c4_Bytes &)const; 721 /// Create a row with one bytes object 722 c4_Row AsRow(const c4_Bytes &)const; 723}; 724 725/// View properties. 726class c4_ViewProp: public c4_Property { 727 public: 728 /// Construct a new property 729 c4_ViewProp(const char*); 730 /// Destructor 731 ~c4_ViewProp(); 732 733 /// Get or set a view property in a row 734 c4_ViewRef operator()(const c4_RowRef &)const; 735 /// Get a view property in a row 736 c4_View Get(const c4_RowRef &)const; 737 /// Set a view property in a row 738 void Set(const c4_RowRef &, const c4_View &)const; 739 740 /// Create a row with one view, shorthand for AsRow 741 c4_Row operator[](const c4_View &)const; 742 /// Create a row with one view 743 c4_Row AsRow(const c4_View &)const; 744}; 745 746//--------------------------------------------------------------------------- 747 748class c4_CustomViewer { 749 protected: 750 /// Constructor, must be overriden in derived class 751 c4_CustomViewer(); 752 public: 753 /// Destructor 754 virtual ~c4_CustomViewer(); 755 756 /// Return the structure of this view (initialization, called once) 757 virtual c4_View GetTemplate() = 0; 758 /// Return the number of rows in this view 759 virtual int GetSize() = 0; 760 int Lookup(const c4_RowRef &, int &); 761 virtual int Lookup(c4_Cursor, int &); 762 /// Fetch one data item, return it as a generic data value 763 virtual bool GetItem(int, int, c4_Bytes &) = 0; 764 virtual bool SetItem(int, int, const c4_Bytes &); 765 bool InsertRows(int, const c4_RowRef &, int = 1); 766 virtual bool InsertRows(int, c4_Cursor, int = 1); 767 virtual bool RemoveRows(int, int = 1); 768}; 769 770//--------------------------------------------------------------------------- 771/// A stream is a virtual helper class to serialize in binary form. 772 773class c4_Stream { 774 public: 775 virtual ~c4_Stream(); 776 777 /// Fetch some bytes sequentially 778 virtual int Read(void *, int) = 0; 779 /// Store some bytes sequentially 780 virtual bool Write(const void *, int) = 0; 781}; 782 783//--------------------------------------------------------------------------- 784/// A strategy encapsulates code dealing with the I/O system interface. 785 786class c4_Strategy { 787 public: 788 c4_Strategy(); 789 virtual ~c4_Strategy(); 790 791 virtual bool IsValid()const; 792 virtual int DataRead(t4_i32, void *, int); 793 virtual void DataWrite(t4_i32, const void *, int); 794 virtual void DataCommit(t4_i32); 795 virtual void ResetFileMapping(); 796 virtual t4_i32 FileSize(); 797 virtual t4_i32 FreshGeneration(); 798 799 void SetBase(t4_i32); 800 t4_i32 EndOfData(t4_i32 = - 1); 801 802 /// True if the storage format is not native (default is false) 803 bool _bytesFlipped; 804 /// Error code of last failed I/O operation, zero if I/O was ok 805 int _failure; 806 /// First byte in file mapping, zero if not active 807 const t4_byte *_mapStart; 808 /// Number of bytes filled with active data 809 t4_i32 _dataSize; 810 /// All file positions are relative to this offset 811 t4_i32 _baseOffset; 812 /// The root position of the shallow tree walks 813 t4_i32 _rootPos; 814 /// The size of the root column 815 t4_i32 _rootLen; 816}; 817 818//--------------------------------------------------------------------------- 819/// A sequence is an abstract base class for views on ranges of records. 820// 821// Sequences represent arrays of rows (or indexed collections / tables). 822// Insertion and removal of entries is allowed, but could take linear time. 823// A reference count is maintained to decide when the object should go away. 824 825class c4_Sequence { 826 /// Reference count 827 int _refCount; 828 /// Pointer to dependency list, or null if nothing depends on this 829 c4_Dependencies *_dependencies; 830 831 protected: 832 /// Optimization: cached property index 833 int _propertyLimit; 834 /// Optimization: property map for faster access 835 short *_propertyMap; // see c4_HandlerSeq::Reset() 836 /// allocated on first use by c4_Sequence::Buffer() 837 c4_Bytes *_tempBuf; 838 839 public: 840 /* General */ 841 /// Abstract constructor 842 c4_Sequence(); 843 844 virtual int Compare(int, c4_Cursor)const; 845 virtual bool RestrictSearch(c4_Cursor, int &, int &); 846 void SetAt(int, c4_Cursor); 847 virtual int RemapIndex(int, const c4_Sequence*)const; 848 849 /* Reference counting */ 850 void IncRef(); 851 void DecRef(); 852 int NumRefs()const; 853 854 /* Adding / removing rows */ 855 /// Return the current number of rows 856 virtual int NumRows()const = 0; 857 void Resize(int, int = - 1); 858 859 virtual void InsertAt(int, c4_Cursor, int = 1); 860 virtual void RemoveAt(int, int = 1); 861 virtual void Move(int, int); 862 863 /* Properties */ 864 int NthPropId(int)const; 865 int PropIndex(int); 866 int PropIndex(const c4_Property &); 867 868 /// Return the number of data handlers in this sequence 869 virtual int NumHandlers()const = 0; 870 /// Return a reference to the N-th handler in this sequence 871 virtual c4_Handler &NthHandler(int)const = 0; 872 /// Return the context of the N-th handler in this sequence 873 virtual const c4_Sequence *HandlerContext(int)const = 0; 874 /// Add the specified data handler to this sequence 875 virtual int AddHandler(c4_Handler*) = 0; 876 /// Create a handler of the appropriate type 877 virtual c4_Handler *CreateHandler(const c4_Property &) = 0; 878 879 virtual const char *Description(); 880 881 /* Element access */ 882 /// Return width of specified data item 883 virtual int ItemSize(int, int); 884 /// Retrieve one data item from this sequence 885 virtual bool Get(int, int, c4_Bytes &); 886 /// Store a data item into this sequence 887 virtual void Set(int, const c4_Property &, const c4_Bytes &); 888 889 /* Dependency notification */ 890 void Attach(c4_Sequence*); 891 void Detach(c4_Sequence*); 892 /// Return a pointer to the dependencies, or null 893 c4_Dependencies *GetDependencies()const; 894 895 virtual c4_Notifier *PreChange(c4_Notifier &); 896 virtual void PostChange(c4_Notifier &); 897 898 const char *UseTempBuffer(const char*); 899 900 protected: 901 virtual ~c4_Sequence(); 902 903 void ClearCache(); 904 905 public: 906 //! for c4_Table::Sequence setup 907 virtual void SetNumRows(int) = 0; 908 virtual c4_Persist *Persist()const; 909 910 c4_Bytes &Buffer(); 911 912 private: 913 c4_Sequence(const c4_Sequence &); // not implemented 914 void operator = (const c4_Sequence &); // not implemented 915}; 916 917//--------------------------------------------------------------------------- 918/// A reference is used to get or set typed data, using derived classes. 919// 920// Objects of this class are only intended to be used as a temporary handle 921// while getting and setting properties in a row. They are normally only 922// constructed as result of function overload operators: "property (row)". 923 924class c4_Reference { 925 protected: 926 /// The cursor which points to the data 927 c4_Cursor _cursor; 928 /// The property associated to this reference 929 const c4_Property &_property; 930 931 public: 932 /// Constructor 933 c4_Reference(const c4_RowRef &, const c4_Property &); 934 935 /// Assignment of one data item 936 c4_Reference &operator = (const c4_Reference &); 937 938 /// Return width of the referenced data item 939 int GetSize()const; 940 /// Retrieve the value of the referenced data item 941 bool GetData(c4_Bytes &)const; 942 /// Store a value into the referenced data item 943 void SetData(const c4_Bytes &)const; 944 945 /// Return true if the contents of both references is equal 946 friend bool operator == (const c4_Reference &, const c4_Reference &); 947 /// Return true if the contents of both references is not equal 948 friend bool operator != (const c4_Reference &, const c4_Reference &); 949 950 private: 951 void operator &()const; // not implemented 952}; 953 954//--------------------------------------------------------------------------- 955 956/// Used to get or set integer values. 957class c4_IntRef: public c4_Reference { 958 public: 959 /// Constructor 960 c4_IntRef(const c4_Reference &); 961 /// Get the value as integer 962 operator t4_i32()const; 963 /// Set the value to the specified integer 964 c4_IntRef &operator = (t4_i32); 965}; 966 967#if !q4_TINY 968 969/// Used to get or set long int values. 970class c4_LongRef: public c4_Reference { 971 public: 972 /// Constructor 973 c4_LongRef(const c4_Reference &); 974 /// Get the value as long int 975 operator t4_i64()const; 976 /// Set the value to the specified long int 977 c4_LongRef &operator = (t4_i64); 978}; 979 980/// Used to get or set floating point values. 981class c4_FloatRef: public c4_Reference { 982 public: 983 /// Constructor 984 c4_FloatRef(const c4_Reference &); 985 /// Get the value as floating point 986 operator double()const; 987 /// Set the value to the specified floating point 988 c4_FloatRef &operator = (double); 989}; 990 991/// Used to get or set double precision values. 992class c4_DoubleRef: public c4_Reference { 993 public: 994 /// Constructor 995 c4_DoubleRef(const c4_Reference &); 996 /// Get the value as floating point 997 operator double()const; 998 /// Set the value to the specified floating point 999 c4_DoubleRef &operator = (double); 1000}; 1001 1002#endif // !q4_TINY 1003 1004/// Used to get or set binary object values. 1005class c4_BytesRef: public c4_Reference { 1006 public: 1007 /// Constructor 1008 c4_BytesRef(const c4_Reference &); 1009 /// Get the value as binary object 1010 operator c4_Bytes()const; 1011 /// Set the value to the specified binary object 1012 c4_BytesRef &operator = (const c4_Bytes &); 1013 1014 /// Fetch data from the memo field, up to end if length is zero 1015 c4_Bytes Access(t4_i32, int = 0, bool = false)const; 1016 /// Store data, resize by diff_ bytes, return true if successful 1017 bool Modify(const c4_Bytes &, t4_i32, int = 0)const; 1018}; 1019 1020/// Used to get or set string values. 1021class c4_StringRef: public c4_Reference { 1022 public: 1023 /// Constructor 1024 c4_StringRef(const c4_Reference &); 1025 /// Get the value as string 1026 operator const char *()const; 1027 /// Set the value to the specified string 1028 c4_StringRef &operator = (const char*); 1029}; 1030 1031/// Used to get or set view values. 1032class c4_ViewRef: public c4_Reference { 1033 public: 1034 /// Constructor 1035 c4_ViewRef(const c4_Reference &); 1036 /// Get the value as view 1037 operator c4_View()const; 1038 /// Set the value to the specified view 1039 c4_ViewRef &operator = (const c4_View &); 1040}; 1041 1042//--------------------------------------------------------------------------- 1043// Debug logging option, can generate log of changes for one/all properties 1044 1045#if q4_LOGPROPMODS 1046FILE *f4_LogPropMods(FILE *fp_, int propId_); 1047#else 1048#define f4_LogPropMods(a,b) 0 1049#endif 1050 1051//--------------------------------------------------------------------------- 1052 1053#if q4_INLINE 1054#include "mk4.inl" 1055#endif 1056 1057//--------------------------------------------------------------------------- 1058 1059#endif // __MK4_H__ 1060