
' Equates used during database creation
%CTX_DBASE  = 1  
%CTX_FOXPRO = 2  

' Equates used for setting the internal Memo buffer
%CTX_MEMO_USER    = 1
%CTX_MEMO_DISK    = 2
%MEMO_HEADER_SIZE = 512
%MEMO_BLOCK_SIZE  = 512   
%MAX_GARBAGECHAIN = 99    ' number of garbage chain entries that will fit in memo header
                  
' Equates for the Comet Indexing routines
$INDEX_IDBYTES         = "Comet Index" 
%INDEX_VERSION         = 100   ' version 1.0.0
%INDEX_NODE_SIZE       = 4096
%INDEX_MAX_TAGS        = 100   ' maximum of 100 Tags in the index (should be enough...) 
%INDEX_MAX_TAG_FIELDS  = 8
%INDEX_MAX_LOOKUP_KEYS = 511
                 
' Delimiter used to separate elements in the database create/open statements
$Delimiter = ";"  


Type DBF_HEADER_TYPE
   Ver              As Byte   ' &H30 FoxPro
   Year             As Byte   ' year  Add 2000 to value 
   Month            As Byte   ' month
   Day              As Byte   ' day of last update
   RecordCount      As Dword  ' number of records in this database
   HeaderLength     As Word   ' length of header
   RecSize          As Word   ' length of record (including deleted flag)
  
   Reserved1        As Asciiz * 16
  
   Table_Flags      As Byte   ' &H01  file has a structural .cdx
                              ' &H02  file has a memo field
                              ' &H04  file is a database (.dbc)
                              ' Byte can be the sum of any or all of the above
  
   CodePage         As Byte   ' &H03 Windows ANSI
  
   Reserved2        As Word
  
End Type
                                                                        
                                                                        

' The maximum number of fields is 255. If one or more fields can contain null
' values then the maximum number of fields is reduced by one to 254.
Type DBF_FIELD_TYPE                                                              
   '------------------------------------------------------------------------------
   ' The following elements are always 32 bytes in length and are saved
   ' and restored from the database header.
   FieldName    As Asciiz * 11   ' name of the field in ASCII
   FieldType    As String * 1    ' Types are described in dbf_createopen.inc
   FDA          As Dword         ' offset of field from beginning of record
   FieldLength  As Byte          ' Length
   DecimalCount As Byte          ' number of decimals in numeric field
   Field_Flags  As Byte          ' &H01  System column (not visible to user)
                                 ' &H02  Column can store null values
                                 ' &H04  Binary column (for CHAR and MEMO only)
   Reserved1    As Asciiz * 13   ' Blank
   '------------------------------------------------------------------------------
  
   ' The following are additional elements used internally by the
   ' library but are never saved to disk.
   FormatMask   As Asciiz * 13   ' numeric formatting mask
  
   ' Memo related data for this field
   MemoDirty        As Long     ' Memo was changed by the user and will need to be written 
   pMemoText        As Dword    ' assigned memory for temporary memo
   MemoTextLength   As Long     ' length of the actual text in MemoText (includes the &H1A's or BlockHeader)
   OrigNumBlocks    As Long     ' the number of blocks originally occupied by the memo
   OrigFirstBlock   As Long     ' the original first block where the memo started
End Type



' A 263-byte range that contains the backlink information (the relative 
' path of an associated database (.dbc)). If the first byte is 0x00 then 
' the file is not associated with a database.
' Hence, database files themselves always contain 0x00.
Type DBF_CONTAINER_TYPE
   Container      As Asciiz * 263  ' Database container (FoxPro)
End Type
            
            
Type DBF_GARBAGEMEMO_TYPE
   BlockNumber      As Dword      'Block that is free
   NumGarbageBlocks As Byte       'Number of consecutive blocks 
End Type
                       
                       
' Memo files contain one header record and any number of 
' block structures. The size of the blocks is determined 
' by the SET BLOCKSIZE command when the file is created. 
' The Header record starts at file position zero and occupies 
' 512 bytes. For dbase memo files, we do not use big endian
' format or a BlockSize (it is always 512). We also must set the Version field.
Type DBF_MEMOHEADER_TYPE
   NextFreeBlock As Dword '4     ' Location of next free block (FoxPro uses Big Endian format)
   Reserved1     As Word  '6     ' unused
   BlockSize     As Word  '8     ' Block size (0 for dBase) (Foxpro uses Big Endian format)
   Reserved2     As Long  '12    ' unused
   Reserved3     As Long  '16    ' unused
   MemVersion    As Byte  '17    ' Only used for dbase files (&H03)
  
   ' Reserved2   as asciiz * 495  ' unused
   ' points to an array of deleted blocks. This 
   ' is a Cheetah4 exclusive feature.
   GarbageChain(1 To %MAX_GARBAGECHAIN) As DBF_GARBAGEMEMO_TYPE  ' 495 bytes
End Type
    
    
Type DBF_MEMOBLOCK_TYPE  ' used for FoxPro memo entries
   Signature  As Dword   ' Block signature (indicates the type of data in the block) 
                         ' (uses Big Endian format)
                         ' 0 - picture/object (picture field type) 
                         ' 1 - text (memo field type)                                
   MemoLength As Dword   ' Length of memo (in bytes) (uses Big Endian format)
End Type
      


'// Regular Node type - It must equal to %NODE_SIZE.
Type INDEX_REGULAR_NODE_TYPE
   'Index node structure:
   '   PrevNode        (4 bytes)
   '   NextNode        (4 bytes)
   '   NumKeys         (2 bytes)
   '   Key+Rec#        (Keysize+4)   ' 4: holds the record number in the DBF
   '
   ' Therefore, use the following formulas to calculate the max number of keys per
   ' node, or the keysize given the number of keys.
   '
   ' #Keys = (%NODESIZE - 10) / (Keysize+4)
  
   PrevNode As Long     '4
   NextNode As Long     '4
   NumKeys  As Integer  '2
   Buffer   As String * (%INDEX_NODE_SIZE - (4+4+2))  'holds the keys/rec#'s.
End Type



'//  Each Tag can have one or more Lookup nodes. These nodes are
'//  a fast lookup that tells the engine where to start looking for
'//  the key based on the first 4 letters of the index key. 
Type INDEX_LOOKUP_NODE_TYPE
   Reserved  As Long        
   NextNode  As Long
   Key ( 1 To %INDEX_MAX_LOOKUP_KEYS ) As String * 4    ' must be space and not asciiz
   Node( 1 To %INDEX_MAX_LOOKUP_KEYS ) As Long                         
End Type


'// The Tag node (as held on disk)
Type INDEX_TAG_TYPE_DISK
   TagName          As Asciiz * 11
   FirstLookupNode  As Long 
   KeySize          As Integer      ' size of key string (does not include associated record number)
   MaxKeys          As Integer      ' maximum # of keys to fit on a node
   HalfNode         As Integer      ' MaxKeys/2 pre-calculated for speed
   UpperCase        As Byte         ' allow for case insensitive seeks
   Reserved         As Byte         ' future use
   Fields( 1 To %INDEX_MAX_TAG_FIELDS ) As Integer  ' Field numbers in the database that the key is based on
End Type   ' 39 bytes


'// Tag type that is held in memory
Type INDEX_TAG_TYPE_MEMORY 
   pNextTAG        As INDEX_TAG_TYPE_MEMORY Ptr  ' next TAG in the linked list
   pBTX            As Dword                      ' Index that this Tag belongs to
   pTagDisk        As INDEX_TAG_TYPE_DISK Ptr    ' points to the Tags() array in the index header                     
   LookupNode      As INDEX_LOOKUP_NODE_TYPE     ' currently loaded lookup node
   RegularNode     As INDEX_REGULAR_NODE_TYPE    ' currently loaded regular node
   LookupNodeNum   As Long                       ' node number of current lookup node
   LookupNodePos   As Long                       ' current position within current LookupNode
   RegularNodeNum  As Long                       ' node number of current regular node
   RegularNodePos  As Long                       ' current position within current RegularNode
   zLastMoveKey    As Asciiz Ptr                 ' save last key during move 
   nLastMoveRecNum As Long                       ' save last recnum during move 
End Type


                        
'// The header node for an entire index file 
Type INDEX_HEADER_NODE_TYPE
   idBytes           As Asciiz * 20     ' Comet Index
   Version           As Long            ' e.g. 100   
   FreeList          As Long            ' first node in the free linked list
   NumTags           As Long            ' Current number of tags in this index file 
   TotalNodes        As Long            ' 
   reserved          As Asciiz * ( %INDEX_NODE_SIZE - 20 - 4 - 4 - 4 - 4 - _
                                     (%INDEX_MAX_TAGS * 39) )
   Tags( 1 To %INDEX_MAX_TAGS ) As INDEX_TAG_TYPE_DISK
End Type


' Type variable that is used for each opened index.
Type BTX_TYPE
   pNextBTX               As BTX_TYPE Ptr       ' address of Next Index in linked list.
   pFirstTAG              As INDEX_TAG_TYPE_MEMORY Ptr  ' first Tag in the linked list
   
   hFile                  As Long          ' file handle for the index.   
   
   pDBF                   As dword         ' back pointer to the DBF
   
   StandAlone             As Byte          ' T/F: index can operate without a database
   MultiUser              As Byte          ' T/F: if False then some nodes can be cached  
   
   BTH                    As INDEX_HEADER_NODE_TYPE

End Type


' Type variable that is used for each opened database.
Type DBF_TYPE
   pNextDBF               As DBF_TYPE Ptr       ' address of Next DBF in linked list.
   nFileType              As Long               ' %CTX_DBASE or %CTX_FOXPRO
   hFile                  As Long               ' file handle for the database.   
   hFileMemo              As Long               ' file handle for a memo file.
   DBH                    As DBF_HEADER_TYPE 
   DBH_MEMO               As DBF_MEMOHEADER_TYPE 
   NumMemoFields          As Long         

   nLastMoveRecord        As Long               ' used for the xdbMove routines
                         
   NumFields              As Long                                      
   pFields                As DBF_FIELD_TYPE Ptr
   pFieldLookup           As Asciiz Ptr         ' quickly lookup fields to get field number
                         
   pRecordBuffer          As Asciiz Ptr   
   pRecordBuffer_original As Asciiz Ptr         ' unchanged record buffer needed when determining index keys to delete. The
                                                ' buffer is the original record prior to any field changes.             
   RecordBuffer_RecNum    As Long               ' RecNum of current record in the buffer
   
   pFirstBTX              As BTX_TYPE Ptr       ' pointer to the first index in the linked list
   
End Type


'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
'Type variable that is allocated at the start of the program and
'destroyed at the end (XDBSHUTDOWN).
Type WORKSPACE_TYPE
   pFirstDBF         As DBF_TYPE Ptr  'address to first DBF in linked list
   NumOpenDatabases  As Long          'number of open databases
End Type





Declare Function ctx_Shutdown_Internal( ByVal xdb As CHEETAH4_TYPE Ptr) As Long
Declare Function ctx_CreateDatabase_Internal( ByVal xdb As CHEETAH4_TYPE Ptr) As Long
Declare Function ctx_OpenDatabase_Internal( ByVal xdb As CHEETAH4_TYPE Ptr) As Long 
Declare Function ctx_CloseDatabase_Internal( ByVal xdb As CHEETAH4_TYPE Ptr) As Long 
Declare Function ctx_DeallocateDBFmemory (ByVal pDBF As DBF_TYPE Ptr) As Long
Declare Function ctx_WriteDBFHeader_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_ReadDBFHeader_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_ClearBuffer_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_SetField_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_DeleteRecord_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_RecallRecord_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_IsDeleted_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_PackDatabase_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_MakeDateTime_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Double
Declare Function ctx_PutRecord_Internal( ByVal xdb As CHEETAH4_TYPE Ptr) As Long
Declare Function ctx_CopyRecordBuffer_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_GetRecord_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_GetField_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_FieldInfo_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_ZapDatabase_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_FieldNumber_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_SetMemoBuffer_dBase_Internal( ByVal xdb As CHEETAH4_TYPE Ptr, _
                                                   ByVal nSetMode As Long _
                                                   ) As Long 
Declare Function ctx_WriteMemoBuffer_dBase_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_SetMemoBuffer_foxpro_Internal( ByVal xdb As CHEETAH4_TYPE Ptr, _
                                                   ByVal nSetMode As Long _
                                                   ) As Long 
Declare Function ctx_WriteMemoBuffer_foxpro_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_ReadMemoHeader_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_WriteMemoHeader_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
        
        
Declare Function FOpen( ByVal FilName As String, ByVal AccessMode As Long, ByVal ShareMode As Long, ByRef hFile As Long) As Long
Declare Function FSeek( ByVal hFilen As Long, ByVal mPosByte As Quad ) As Long
Declare Function FGet( ByVal hFile As Long, ByVal NumBytes As Long, ByVal MemoryAddress As Dword) As Long
Declare Function FGetAt( ByVal hFile As Long, ByVal mPositionByte As Quad, ByVal vNumBytes As Long, ByVal MemoryAddress As Dword ) As Long
Declare Function fWriteAt( ByVal hFile As Long, ByVal PosByte As Quad, ByVal NumBytes As Long, ByVal MemoryAddress As Dword ) As Long
Declare Sub      FClose ( ByRef hFile As Long)

Declare Function ctx_CreateIndex_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_CloseIndex_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long 
Declare Function ctx_DeallocateBTXmemory( ByVal pBTX As BTX_TYPE Ptr ) As Long
Declare Function ctx_GetTag_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_GetNode_Internal( ByVal pBTX As BTX_TYPE Ptr, _
                                       ByVal NodeNum As Long, _
                                       ByVal MemAddress As Dword _
                                       ) As Long
Declare Function ctx_PutNode_Internal( ByVal pBTX As BTX_TYPE Ptr, _
                                       ByVal NodeNum As Long, _
                                       ByVal MemAddress As Dword _
                                       ) As Long
Declare Function ctx_CreateTagType_Internal( ByVal pBTX As BTX_TYPE Ptr, _
                                     ByVal pTagDisk As INDEX_TAG_TYPE_DISK Ptr, _
                                     ByRef MemAddress As Dword _
                                     ) As Long
Declare Function ctx_GetFreeNode_Internal( ByVal pBTX As BTX_TYPE Ptr, _
                                           ByRef NodeNum As Long _
                                           ) As Long
Declare Function ctx_InsertKey_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_Move_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_Move_dbf_Internal( ByVal xdb  As CHEETAH4_TYPE Ptr, _
                                        ByVal pDBF As DBF_TYPE Ptr, _
                                        ByVal pBTX As BTX_TYPE Ptr, _
                                        ByVal pTAG As INDEX_TAG_TYPE_MEMORY Ptr _
                                        ) As Long
Declare Function ctx_Move_btx_Internal( ByVal xdb  As CHEETAH4_TYPE Ptr, _
                                        ByVal pDBF As DBF_TYPE Ptr, _
                                        ByVal pBTX As BTX_TYPE Ptr, _
                                        ByVal pTAG As INDEX_TAG_TYPE_MEMORY Ptr _
                                        ) As Long
Declare Function ctx_SeekEngine_Internal( ByVal xdb As CHEETAH4_TYPE Ptr, _
                                          ByVal pBTX As BTX_TYPE Ptr, _
                                          ByVal pTAG As INDEX_TAG_TYPE_MEMORY Ptr, _
                                          ByVal KeyAddress As Long, _
                                          ByVal KeyLength As Long, _
                                          ByVal nRecNum As Long, _
                                          ByVal SeekTypeFlag As Long _
                                          ) As Long
Declare Function ctx_DeleteTagKey_Internal( ByVal xdb As CHEETAH4_TYPE Ptr, _
                                            ByVal pBTX As BTX_TYPE Ptr, _
                                            ByVal pTAG As INDEX_TAG_TYPE_MEMORY Ptr, _
                                            ByVal sKey As String, _
                                            ByVal nRecNum As Long _
                                            ) As Long
Declare Function ctx_Reindex_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
Declare Function ctx_ResetIndexFiles_Internal( ByVal pDBF As DBF_TYPE Ptr ) As Long
Declare Function ctx_SetEndOfFile_Internal( ByVal hFile As Long, _
                                            ByVal nByteOffset As Long, _
                                            ByVal UseEOFchar As Long _
                                            ) As Long
Declare Function ctx_GenerateIndexKey_Internal( ByVal pDBF As DBF_TYPE Ptr, _
                                                ByVal pTAG As INDEX_TAG_TYPE_MEMORY Ptr, _
                                                ByVal UseOriginalBuffer As Long _
                                                ) As String
Declare Function ctx_DeallocateBTXmemory( ByVal pBTX As BTX_TYPE Ptr ) As Long
Declare Function ctx_DeallocateDBFmemory( ByVal pDBF As DBF_TYPE Ptr ) As Long
Declare Function ctx_DumpIndex_Internal( ByVal xdb As CHEETAH4_TYPE Ptr ) As Long
