/*
 * Copyright (C) 2003 Trevor van Bremen
 * Copyright (C) 2021 Ron Norman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.2,
 * or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.LIB.  If
 * not, write to the Free Software Foundation, Inc., 59 Temple Place,
 * Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef VISAM_INCL					   /* avoid multiple include problems */
#define VISAM_INCL

#include <sys/types.h>
#include <unistd.h>

#define vbisam_off_t    off_t
#define vbisam_rec_n    unsigned long

#define VB_CHAR     signed char
#define VB_UCHAR    unsigned char
#define VISAM_VERSION "2.2"

/* The old VBISAM code would close all ISAM files on iscommit/isrollback
 * If you want that behaviour change VB_CLOSE_ON_TREN to 1
 * Although it seems like a bug to me..
 */
#define VB_CLOSE_ON_TREN 0

/* To have the data flushed to disk on each commit/rollback
 * set VB_FLUSH_ON_TREN to 1
 */
#define VB_FLUSH_ON_TREN 0

/*
 *  define VISAM_NO_CISAM_CONFLICT to avoid name conflict with C-ISAM
 */
#if defined(VISAM_NO_CISAM_CONFLICT)
#include "visam_rename.h"
#endif

#include    <vdecimal.h>

#define     CHARTYPE        0
#define     INTTYPE         1		   /* two byte (short) integer */
#define     LONGTYPE        2		   /* four byte (long) integer */
#define     DOUBLETYPE      3		   /* ieee double floating point */
#define     FLOATTYPE       4		   /* ieee single floating point */
#define		MINTTYPE        5		   /* machine (native) short */
#define		MLONGTYPE       6		   /* machine (native) long */
#define     QUADTYPE        8

#define     CHARSIZE        1
#define     INTSIZE         2
#define     LONGSIZE        4
#define     FLOATSIZE       (sizeof (float))
#define     DOUBLESIZE      (sizeof (double))

#define     ISDESC          0x80

#define     BYTEMASK        0xFF	   /* Mask for one byte */
#define     BYTESHFT        8		   /* Shift for one byte */

#define     ISFIRST         0		   /* Position to first row */
#define     ISLAST          1		   /* Position to last row */
#define     ISNEXT          2		   /* Position to next row */
#define     ISPREV          3		   /* Position to previous row */
#define     ISCURR          4		   /* Position to current row */
#define     ISEQUAL         5		   /* Position to equal value */
#define     ISGREAT         6		   /* Position to greater value */
#define     ISGTEQ          7		   /* Position to >= value */

/* isread () locking modes */
#define     ISLOCK          0x100	   /* Row lock */
#define     ISSKIPLOCK      0x200	   /* Skip row even if locked */
#define     ISWAIT          0x400	   /* Wait for row lock */
#define     ISLCKW          ISLOCK | ISWAIT

/* isstart () lock modes */
#define     ISKEEPLOCK      0x800	   /* Keep rec lock in autolk mode */

/* isopen (), isbuild () lock modes */
#define     ISAUTOLOCK      0x200	   /* Automatic row lock */
#define     ISMANULOCK      0x400	   /* Manual row lock */
#define     ISEXCLLOCK      0x800	   /* Exclusive isam file lock */

/* isopen (), isbuild () file types */
#define     ISINPUT         0		   /* Open for input only */
#define     ISOUTPUT        1		   /* Open for output only */
#define     ISINOUT         2		   /* Open for input and output */
#define     ISTRANS         4		   /* Open for transaction proc */
#define     ISNOLOG         8		   /* No loggin for this file */
#define     ISVARLEN        0x10	   /* Variable length rows */
#define     ISFIXLEN        0x00	   /* (Non-flag) Fixed length rows only */
#define     ISREBUILD       0x20	   /* Open for Rebuild (forget some check) */
#define		ISSYNCWR		0x40	   /* synchronous writes */

/* isopen (), isbuild () additional file mode; Also used by D-ISAM */
	/* Defines the size in bytes of the 'duplicate' value; 2 or 4; VBISAM uses 8 */
#define		ISMDUPMASK		0x00070000
#define		ISMDUPSHIFT		16
#define		ISMDUPLEN(m)	((int)(m & ISMDUPMASK) >> ISMDUPSHIFT)
	/* Defines the index block size; number * 512 */
#define		ISMIDXMASK		0x1F000000
#define		ISMIDXSHIFT		24
#define		ISMIDXSIZE(m)	((int)(m & ISMIDXMASK) >> ISMIDXSHIFT)
/* isbuild () additional file mode; Only used here */
	/* If bit is set then isbuild a C-ISAM format file */
#define		ISMCISAM  		0x00100000
	/* If bit is set then isbuild an old VB-ISAM format file */
#define		ISMVBISAM  		0x00200000
#define		ISMMODEMASK		0x00300000
#define		ISMMODESHIFT	20
	/* If bit is set then isbuild does not create filename.dat */
#define		ISMNODAT		0x00400000

#define     VB_MAX_KEYLEN   511		   /* Maximum number of bytes in a key */
#define     NPARTS          8		   /* Maximum number of key parts */

/***************************************/
/* Used in isam.h so for compatibility */
#define MAXKEYSIZE	VB_MAX_KEYLEN
#define MAXTYPE		5
#define TYPEMASK	0x7F
/***************************************/

/* COBOL support ------------------------------------------------------*/
#define ISCOBOL     9				   /* COBOL support */

#if( ISCOBOL > 0 )					   /* the sum of these options:   */
#define ISCOBOL_STATS           1	   /* support for isstat codes    */
#define ISCOBOL_NO_NEW_EXT      2	   /* create data files no .dat   */
#define ISCOBOL_NO_DAT_EXT      4	   /* open expects no .dat ext    */
#define ISCOBOL_ANY_EXT         8	   /* open either data form       */
#define ISCOBOL_NEW_DUP_ONE    16	   /* new dups start at one       */
#endif

/* audit trail mode parameters */
#define     AUDSETNAME      0		   /* Set new audit trail name */
#define     AUDGETNAME      1		   /* Get audit trail name */
#define     AUDSTART        2		   /* Start audit trail */
#define     AUDSTOP         3		   /* Stop audit trail */
#define     AUDINFO         4		   /* Audit trail running */

struct keypart {
	short       kp_start;		/* Starting byte of key part */
	short       kp_leng;		/* Length in bytes */
	short       kp_type;		/* Type of key part (include ISDESC as needed) */
};

typedef struct keydesc {
	short       k_flags;		/* Flags (Compression) */
	short       k_nparts;		/* Number of parts in this key */
	struct keypart k_part[NPARTS];	/* Each key part */
	short       k_len;			/* Length of entire uncompressed key */
	unsigned long k_rootnode;	/* Pointer to rootnode */
} keydesc_t;

#define     k_start k_part[0].kp_start
#define     k_leng  k_part[0].kp_leng
#define     k_type  k_part[0].kp_type

/* Possible values for iFlags */
#define     ISNODUPS        0x00	   /* No duplicates allowed */
#define     ISDUPS          0x01	   /* Duplicates allowed */
#define     DCOMPRESS       0x02	   /* Duplicate compression */
#define     LCOMPRESS       0x04	   /* Leading compression */
#define     TCOMPRESS       0x08	   /* Trailing compression */
#define     COMPRESS        0x0e	   /* All compression */
#define     NULLKEY         0x20	   /* null key masking */

struct dictinfo {
	short       di_nkeys;		/* Number of keys defined (msb set if VARLEN) */
	short       di_recsize;		/* Maximum data row length */
	short       di_idxsize;		/* Number of bytes in an index node */
	unsigned long di_nrecords;	/* Number of rows in data file */
};

#define		ISERRBASE		100
/* Possible error return values */
#define     EDUPL           100		   /* Duplicate row */
#define     ENOTOPEN        101		   /* File not open */
#define     EBADARG         102		   /* Illegal argument */
#define     EBADKEY         103		   /* Illegal key desc */
#define     ETOOMANY        104		   /* Too many files open */
#define     EBADFILE        105		   /* Bad isam file format */
#define     ENOTEXCL        106		   /* Non-exclusive access */
#define     ELOCKED         107		   /* Row locked */
#define     EKEXISTS        108		   /* Key already exists */
#define     EPRIMKEY        109		   /* Is primary key */
#define     EENDFILE        110		   /* End/begin of file */
#define     ENOREC          111		   /* No row found */
#define     ENOCURR         112		   /* No current row */
#define     EFLOCKED        113		   /* File locked */
#define     EFNAME          114		   /* File name too long */
#define     EBADMEM         116		   /* Can't alloc memory */
#define     ELOGREAD        118		   /* Cannot read log rec */
#define     EBADLOG         119		   /* Bad log row */
#define     ELOGOPEN        120		   /* Cannot open log file */
#define     ELOGWRIT        121		   /* Cannot write log rec */
#define     ENOTRANS        122		   /* No transaction */
#define     ENOBEGIN        124		   /* No begin work yet */
#define     ENOPRIM         127		   /* No primary key */
#define     ENOLOG          128		   /* No logging enabled or allowed */
#define     ENOFREE         131		   /* No free disk space */
#define     EROWSIZE        132		   /* Row size too short / long */
#define     EAUDIT          133		   /* Audit trail exists */
#define     ENOLOCKS        134		   /* No more locks */
#define     EDEADLOK        143		   /* Deadlock avoidance */
#define     ENOMANU         153		   /* Must be in ISMANULOCK mode */
#define     EINTERUPT       157		   /* Interrupted isam call */
#define     EBADFORMAT      171		   /* Locking or NODESIZE change */


struct DICTINFO;
struct VBLOCK;
struct VBTREE;
struct SLOGHDR;
#define	MAXSUBS		        32		   /* Maximum number of indexes per table */
/* Define so other code knows that 'ispid' is available */
#define ISEXTENDED 1

/* Found in vblocking.c */
extern int  iserrno;
extern int  iserrio;
extern int  isreclen;
extern int  ispid;
extern unsigned long isrecnum;
extern char isstat1;
extern char isstat2;
extern char isstat3;
extern char isstat4;

struct audhead {
	VB_CHAR     au_type[2];		/* Audit row type aa,dd,rr,ww */
	VB_CHAR     au_time[4];		/* Audit date-time */
	VB_CHAR     au_procid[2];	/* Process id number */
	VB_CHAR     au_userid[2];	/* User id number */
	VB_CHAR     au_recnum[4];	/* Row number - RXW Set to 4 */
	VB_CHAR     au_reclen[2];	/* audit row length beyond header */
};

/* Number of bytes in audit header */
#define     AUDHEADSIZE     14
/* VARLEN num of bytes in audit header */
#define     VAUDHEADSIZE    16

/* Prototypes for file manipulation functions */
extern int  isaddindex (int ihandle, struct keydesc *pskeydesc);
extern int  isaudit (int ihandle, VB_CHAR * pcfilename, int imode);
extern int  isbegin (void);
extern int  isbuild (const VB_CHAR * pcfilename, int imaxrowlength,
					 struct keydesc *pskey, int imode);
extern int  ischeck (const VB_CHAR * pcfile, const int rebuild, const int format);
extern int  iscleanup (void);
extern int  isclose (int ihandle);
extern int  iscluster (int ihandle, struct keydesc *pskeydesc);
extern int  iscommit (void);
extern int  isdelcurr (int ihandle);
extern int  isdelete (int ihandle, VB_CHAR * pcrow);
extern int  isdelindex (int ihandle, struct keydesc *pskeydesc);
extern int  isdelindex (int ihandle, struct keydesc *pskeydesc);
extern int  isdelrec (int ihandle, unsigned long trownumber);
extern int  iserase (VB_CHAR * pcfilename);
extern int  isflush (int ihandle);
extern int  isfullclose (int ihandle);
extern int  isindexinfo (int ihandle, void *pskeydesc, int ikeynumber);
extern int  islock (int ihandle);
extern int  islogclose (void);
extern int  islogopen (VB_CHAR * pcfilename);
extern int  isopen (const VB_CHAR * pcfilename, int imode);
extern int  isread (int ihandle, VB_CHAR * pcrow, int imode);
extern int  isrecover (void);
extern int  isrelcurr (int ihandle);
extern int  isrelease (int ihandle);
extern int  isrelrec (int ihandle, unsigned long trownumber);
extern int  isrename (VB_CHAR * pcoldname, VB_CHAR * pcnewname);
extern int  isrewcurr (int ihandle, VB_CHAR * pcrow);
extern int  isrewrec (int ihandle, unsigned long trownumber, VB_CHAR * pcrow);
extern int  isrewrite (int ihandle, VB_CHAR * pcrow);
extern int  isrollback (void);
extern int  issetcollate (int ihandle, VB_UCHAR * collating_sequence);
extern int  issetunique (int ihandle, unsigned long tuniqueid);
extern int  isstart (int ihandle, struct keydesc *pskeydesc,
					 int ilength, VB_CHAR * pcrow, int imode);
extern int  isuniqueid (int ihandle, unsigned long *ptuniqueid);
extern int  isunlock (int ihandle);
extern int  iswrcurr (int ihandle, VB_CHAR * pcrow);
extern int  iswrite (int ihandle, VB_CHAR * pcrow);

extern void ldchar (VB_CHAR * pcsource, int ilength, VB_CHAR * pcdestination);
extern void stchar (VB_CHAR * pcsource, VB_CHAR * pcdestination, int ilength);
extern int  ldint (void *pclocation);
extern void stint (int ivalue, void *pclocation);
extern int  ldlong (void *pclocation);
extern void stlong (int lvalue, void *pclocation);
extern double ldfloat (void *pclocation);
extern void stfloat (double dsource, void *pcdestination);
extern double ldfltnull (void *pclocation, short *pinullflag);
extern void stfltnull (double dsource, void *pcdestination, int inullflag);
extern double lddbl (void *pclocation);
extern void stdbl (double dsource, void *pcdestination);
extern double lddblnull (void *pclocation, short *pinullflag);
extern void stdblnull (double dsource, void *pcdestination, int inullflag);
extern int  lddecimal (VB_UCHAR * cp, int len, dec_t * dp);
extern void stdecimal (dec_t * dp, VB_UCHAR * cp, int len);

#endif /* VISAM_INCL */
