summaryrefslogtreecommitdiff
path: root/xbase64
diff options
context:
space:
mode:
Diffstat (limited to 'xbase64')
-rwxr-xr-xxbase64/Makefile.am55
-rwxr-xr-xxbase64/Makefile.in475
-rwxr-xr-xxbase64/makebcc.bat32
-rwxr-xr-xxbase64/xbase64.cpp766
-rwxr-xr-xxbase64/xbase64.h239
-rwxr-xr-xxbase64/xbcdx.cpp113
-rwxr-xr-xxbase64/xbcdx.h150
-rw-r--r--xbase64/xbconfig.h131
-rwxr-xr-xxbase64/xbconfig.in130
-rwxr-xr-xxbase64/xbdate.cpp851
-rwxr-xr-xxbase64/xbdate.h278
-rwxr-xr-xxbase64/xbdbf.cpp2671
-rwxr-xr-xxbase64/xbdbf.h533
-rwxr-xr-xxbase64/xbexp.cpp1323
-rwxr-xr-xxbase64/xbexp.h290
-rwxr-xr-xxbase64/xbexpfnc.cpp1092
-rwxr-xr-xxbase64/xbexpprc.cpp549
-rwxr-xr-xxbase64/xbfields.cpp672
-rwxr-xr-xxbase64/xbfile.cpp69
-rwxr-xr-xxbase64/xbfile.h70
-rwxr-xr-xxbase64/xbfilter.cpp231
-rwxr-xr-xxbase64/xbfilter.h75
-rwxr-xr-xxbase64/xbindex.cpp220
-rwxr-xr-xxbase64/xbindex.h137
-rwxr-xr-xxbase64/xblock.cpp580
-rwxr-xr-xxbase64/xblock.h159
-rwxr-xr-xxbase64/xbmemo.cpp1173
-rwxr-xr-xxbase64/xbmindex.h14
-rwxr-xr-xxbase64/xbndx.cpp2402
-rwxr-xr-xxbase64/xbndx.h292
-rwxr-xr-xxbase64/xbnode.cpp6
-rwxr-xr-xxbase64/xbnode.h19
-rwxr-xr-xxbase64/xbntx.cpp2604
-rwxr-xr-xxbase64/xbntx.h213
-rwxr-xr-xxbase64/xbretcod.h99
-rwxr-xr-xxbase64/xbstring.cpp1041
-rwxr-xr-xxbase64/xbstring.h145
-rwxr-xr-xxbase64/xbtypes.h99
-rwxr-xr-xxbase64/xbwincfg.h82
39 files changed, 0 insertions, 20080 deletions
diff --git a/xbase64/Makefile.am b/xbase64/Makefile.am
deleted file mode 100755
index b0dff24..0000000
--- a/xbase64/Makefile.am
+++ /dev/null
@@ -1,55 +0,0 @@
-# This file is part of the xbase64 libraries
-# Copyright (C) 1998 Denis Pershin (dyp@inetlab.com)
-#
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, 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; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Contact:
-#
-# Email:
-#
-# xbase64-dev@lists.sourceforge.net
-# xbase64-users@lists.sourceforge.net
-#
-#
-
-INCLUDES = -I$(topdir)
-
-lib_LTLIBRARIES = libxbase64.la
-
-pkginclude_HEADERS = xbdbf.h xbexp.h xbndx.h xbretcod.h xbase64.h xbdate.h \
- xbtypes.h xbstring.h xbindex.h xbntx.h xbconfig.h xbfilter.h \
- xblock.h xbfile.h xbcdx.h xbwincfg.h xbmindex.h xbnode.h
-
-#install-data-hook:
-# (cd $(includedir); rm -f xbase64.h; ln -s xbase64/xbase64.h xbase64.h)
-
-libxbase64_la_SOURCES = xbdbf.cpp xbexp.cpp xbexpfnc.cpp xbexpprc.cpp \
- xbfields.cpp xbmemo.cpp xbndx.cpp xbase64.cpp xbdate.cpp \
- xbstring.cpp xbindex.cpp xbntx.cpp xbfilter.cpp xblock.cpp \
- xbfile.cpp xbcdx.cpp xbnode.cpp
-
-EXTRA_DIST = makebcc.bat
-# makefile.g95 \
-# makebcc.bat \
-# xbase.ide
-
-
-libxbase64_la_LDFLAGS = -version-info 1:0:0
-libxbase64_la_LIBADD =
-
-MAINTAINERCLEANFILES = Makefile.in stamp-h.in
-CLEANFILES = *.obj *.BAK *.bak *.tds *.lib compout
-
diff --git a/xbase64/Makefile.in b/xbase64/Makefile.in
deleted file mode 100755
index 981a6b9..0000000
--- a/xbase64/Makefile.in
+++ /dev/null
@@ -1,475 +0,0 @@
-# Makefile.in generated by automake 1.6.3 from Makefile.am.
-# @configure_input@
-
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-# This file is part of the xbase64 libraries
-# Copyright (C) 1998 Denis Pershin (dyp@inetlab.com)
-#
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, 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; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# Contact:
-#
-# Email:
-#
-# xbase64-dev@lists.sourceforge.net
-# xbase64-users@lists.sourceforge.net
-#
-#
-SHELL = @SHELL@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ..
-
-ACLOCAL = @ACLOCAL@
-AUTOCONF = @AUTOCONF@
-AUTOMAKE = @AUTOMAKE@
-AUTOHEADER = @AUTOHEADER@
-
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = @program_transform_name@
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-host_alias = @host_alias@
-host_triplet = @host@
-
-EXEEXT = @EXEEXT@
-OBJEXT = @OBJEXT@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-AMTAR = @AMTAR@
-AS = @AS@
-AWK = @AWK@
-CC = @CC@
-CXX = @CXX@
-DEPDIR = @DEPDIR@
-DLLTOOL = @DLLTOOL@
-ECHO = @ECHO@
-GXXVER = @GXXVER@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LIBTOOL = @LIBTOOL@
-LN_S = @LN_S@
-OBJDUMP = @OBJDUMP@
-PACKAGE = @PACKAGE@
-RANLIB = @RANLIB@
-RELEASE = @RELEASE@
-RHREL = @RHREL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-XSUBDIRS = @XSUBDIRS@
-am__include = @am__include@
-am__quote = @am__quote@
-doxygen = @doxygen@
-install_sh = @install_sh@
-topdir = @topdir@
-
-INCLUDES = -I$(topdir)
-
-lib_LTLIBRARIES = libxbase64.la
-
-pkginclude_HEADERS = xbdbf.h xbexp.h xbndx.h xbretcod.h xbase64.h xbdate.h \
- xbtypes.h xbstring.h xbindex.h xbntx.h xbconfig.h xbfilter.h \
- xblock.h xbfile.h xbcdx.h xbwincfg.h xbmindex.h xbnode.h
-
-
-
-#install-data-hook:
-# (cd $(includedir); rm -f xbase64.h; ln -s xbase64/xbase64.h xbase64.h)
-libxbase64_la_SOURCES = xbdbf.cpp xbexp.cpp xbexpfnc.cpp xbexpprc.cpp \
- xbfields.cpp xbmemo.cpp xbndx.cpp xbase64.cpp xbdate.cpp \
- xbstring.cpp xbindex.cpp xbntx.cpp xbfilter.cpp xblock.cpp \
- xbfile.cpp xbcdx.cpp xbnode.cpp
-
-
-EXTRA_DIST = makebcc.bat
-
-# makefile.g95 \
-# makebcc.bat \
-# xbase.ide
-libxbase64_la_LDFLAGS = -version-info 1:0:0
-libxbase64_la_LIBADD =
-
-MAINTAINERCLEANFILES = Makefile.in stamp-h.in
-CLEANFILES = *.obj *.BAK *.bak *.tds *.lib compout
-subdir = xbase64
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = xbconfig.h
-CONFIG_CLEAN_FILES =
-LTLIBRARIES = $(lib_LTLIBRARIES)
-
-libxbase64_la_DEPENDENCIES =
-am_libxbase64_la_OBJECTS = xbdbf.lo xbexp.lo xbexpfnc.lo xbexpprc.lo \
- xbfields.lo xbmemo.lo xbndx.lo xbase64.lo xbdate.lo xbstring.lo \
- xbindex.lo xbntx.lo xbfilter.lo xblock.lo xbfile.lo xbcdx.lo \
- xbnode.lo
-libxbase64_la_OBJECTS = $(am_libxbase64_la_OBJECTS)
-
-DEFS = @DEFS@
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
-CPPFLAGS = @CPPFLAGS@
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/xbase64.Plo ./$(DEPDIR)/xbcdx.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbdate.Plo ./$(DEPDIR)/xbdbf.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbexp.Plo ./$(DEPDIR)/xbexpfnc.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbexpprc.Plo ./$(DEPDIR)/xbfields.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbfile.Plo ./$(DEPDIR)/xbfilter.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbindex.Plo ./$(DEPDIR)/xblock.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbmemo.Plo ./$(DEPDIR)/xbndx.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbnode.Plo ./$(DEPDIR)/xbntx.Plo \
-@AMDEP_TRUE@ ./$(DEPDIR)/xbstring.Plo
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CXXFLAGS) $(CXXFLAGS)
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-CXXFLAGS = @CXXFLAGS@
-DIST_SOURCES = $(libxbase64_la_SOURCES)
-HEADERS = $(pkginclude_HEADERS)
-
-DIST_COMMON = $(pkginclude_HEADERS) Makefile.am Makefile.in xbconfig.in
-SOURCES = $(libxbase64_la_SOURCES)
-
-all: xbconfig.h
- $(MAKE) $(AM_MAKEFLAGS) all-am
-
-.SUFFIXES:
-.SUFFIXES: .cpp .lo .o .obj
-$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu xbase64/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
-
-xbconfig.h: stamp-h1
- @if test ! -f $@; then \
- rm -f stamp-h1; \
- $(MAKE) stamp-h1; \
- else :; fi
-
-stamp-h1: $(srcdir)/xbconfig.in $(top_builddir)/config.status
- @rm -f stamp-h1
- cd $(top_builddir) && $(SHELL) ./config.status xbase64/xbconfig.h
-
-$(srcdir)/xbconfig.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOHEADER)
- touch $(srcdir)/xbconfig.in
-
-distclean-hdr:
- -rm -f xbconfig.h stamp-h1
-libLTLIBRARIES_INSTALL = $(INSTALL)
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
- @$(NORMAL_INSTALL)
- $(mkinstalldirs) $(DESTDIR)$(libdir)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- if test -f $$p; then \
- f="`echo $$p | sed -e 's|^.*/||'`"; \
- echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
- $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
- else :; fi; \
- done
-
-uninstall-libLTLIBRARIES:
- @$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- p="`echo $$p | sed -e 's|^.*/||'`"; \
- echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
- $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
- done
-
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test -z "$dir" && dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
-libxbase64.la: $(libxbase64_la_OBJECTS) $(libxbase64_la_DEPENDENCIES)
- $(CXXLINK) -rpath $(libdir) $(libxbase64_la_LDFLAGS) $(libxbase64_la_OBJECTS) $(libxbase64_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT) core *.core
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbase64.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbcdx.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbdate.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbdbf.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbexp.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbexpfnc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbexpprc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbfields.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbfile.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbfilter.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbindex.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xblock.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbmemo.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbndx.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbnode.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbntx.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xbstring.Plo@am__quote@
-
-distclean-depend:
- -rm -rf ./$(DEPDIR)
-
-.cpp.o:
-@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
-
-.cpp.obj:
-@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- $(CXXCOMPILE) -c -o $@ `cygpath -w $<`
-
-.cpp.lo:
-@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
-@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
-CXXDEPMODE = @CXXDEPMODE@
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-distclean-libtool:
- -rm -f libtool
-uninstall-info-am:
-pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER)
-install-pkgincludeHEADERS: $(pkginclude_HEADERS)
- @$(NORMAL_INSTALL)
- $(mkinstalldirs) $(DESTDIR)$(pkgincludedir)
- @list='$(pkginclude_HEADERS)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f="`echo $$p | sed -e 's|^.*/||'`"; \
- echo " $(pkgincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(pkgincludedir)/$$f"; \
- $(pkgincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(pkgincludedir)/$$f; \
- done
-
-uninstall-pkgincludeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(pkginclude_HEADERS)'; for p in $$list; do \
- f="`echo $$p | sed -e 's|^.*/||'`"; \
- echo " rm -f $(DESTDIR)$(pkgincludedir)/$$f"; \
- rm -f $(DESTDIR)$(pkgincludedir)/$$f; \
- done
-
-ETAGS = etags
-ETAGSFLAGS =
-
-tags: TAGS
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- mkid -fID $$unique
-
-TAGS: $(HEADERS) $(SOURCES) xbconfig.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) xbconfig.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$tags$$unique" \
- || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-
-top_distdir = ..
-distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
-
-distdir: $(DISTFILES)
- @list='$(DISTFILES)'; for file in $$list; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test "$$dir" != "$$file" && test "$$dir" != "."; then \
- dir="/$$dir"; \
- $(mkinstalldirs) "$(distdir)$$dir"; \
- else \
- dir=''; \
- fi; \
- if test -d $$d/$$file; then \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES) $(HEADERS) xbconfig.h
-
-installdirs:
- $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(pkgincludedir)
-
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
- -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
- mostlyclean-am
-
-distclean: distclean-am
-
-distclean-am: clean-am distclean-compile distclean-depend \
- distclean-generic distclean-hdr distclean-libtool \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-pkgincludeHEADERS
-
-install-exec-am: install-libLTLIBRARIES
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \
- uninstall-pkgincludeHEADERS
-
-.PHONY: GTAGS all all-am check check-am clean clean-generic \
- clean-libLTLIBRARIES clean-libtool distclean distclean-compile \
- distclean-depend distclean-generic distclean-hdr \
- distclean-libtool distclean-tags distdir dvi dvi-am info \
- info-am install install-am install-data install-data-am \
- install-exec install-exec-am install-info install-info-am \
- install-libLTLIBRARIES install-man install-pkgincludeHEADERS \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- tags uninstall uninstall-am uninstall-info-am \
- uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/xbase64/makebcc.bat b/xbase64/makebcc.bat
deleted file mode 100755
index efdad66..0000000
--- a/xbase64/makebcc.bat
+++ /dev/null
@@ -1,32 +0,0 @@
-
-rem 2/14/04
-rem This batch file builds the xbase64 library using Borland C++ 5.5
-rem use -v for source level debugging
-
-del *.bak
-del *.obj
-
-bcc32 -c -I.. -Id:\borland\bcc55\include xbdate.cpp > compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xblock.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbdbf.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbexp.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbexpfnc.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbexpprc.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbfields.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbindex.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbase64.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbmemo.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbstring.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbfilter.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbndx.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbntx.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbcdx.cpp >> compout
-bcc32 -c -I.. -Id:\borland\bcc55\include xbfile.cpp >> compout
-
-
-del xbase64.lib
-tlib xbase64.lib /C +xbdbf.obj +xbexp.obj +xbexpfnc.obj >> compout
-tlib xbase64.lib /C +xbndx.obj +xbntx.obj +xbexpprc.obj >> compout
-tlib xbase64.lib /C +xbfields.obj +xbfile.obj +xbcdx.obj >> compout
-tlib xbase64.lib /C +xbindex.obj +xbfilter.obj +xbase64.obj >> compout
-tlib xbase64.lib /C +xbmemo.obj +xbdate.obj +xbstring.obj >> compout
diff --git a/xbase64/xbase64.cpp b/xbase64/xbase64.cpp
deleted file mode 100755
index fc5613d..0000000
--- a/xbase64/xbase64.cpp
+++ /dev/null
@@ -1,766 +0,0 @@
-/* xbase64.cpp
-
- Xbase64 project source code
-
- This file contains logic for the basic Xbase class.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbase64.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-#include <ctype.h>
-#include <string.h>
-
-//#include <xbase64/xbexcept.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_IO_H // windows locking
-#include <io.h>
-#endif
-
-#ifdef HAVE_DOS_H // windows _sleep
-#include <dos.h>
-#endif
-
-
-/*! \file xbase64.cpp
-*/
-
-/*************************************************************************/
-//! Constructor.
-/*!
-*/
-xbXBase::xbXBase()
-{
- xbShort e = 1;
- EndianType = *(char *) &e;
- if( EndianType )
- EndianType = 'L';
- else
- EndianType = 'B';
- DbfList = NULL;
- FreeDbfList = NULL;
-
-#ifdef XB_LOCKING_ON
- LockRetryCount = 5;
- LockMode = XB_SINGLE_USER_MODE;
-#endif
-
- DefaultDateFormat = "MM/DD/YY";
-}
-/*************************************************************************/
-//! Get pointer to named dbf.
-/*!
- Looks up an open DBF file by Name.
-
- \param Name
- \returns A pointer to the xbDbf class instance if found or NULL if
- not found.
-*/
-xbDbf *xbXBase::GetDbfPtr(const char *Name) {
- xbDbList *t;
-
- t = DbfList;
- xbShort len = strlen(Name);
-
- /* check for -> embedded in the name */
- for( xbShort i = 0; i < (len-1); i++ )
- if( Name[i] == '-' && Name[i+1] == '>' )
- len = i-1;
-
- while (t) {
- if (strncmp(Name, t->DbfName, len) == 0 )
- return t->dbf;
- t = t->NextDbf;
- }
- return NULL;
-}
-
-/*************************************************************************/
-//! Destructor.
-/*!
-*/
-xbXBase::~xbXBase()
-{
- xbDbList *i = FreeDbfList;
- while (i) {
- xbDbList *t = i->NextDbf;
- if (i->DbfName) {
- free(i->DbfName);
- }
- free(i);
- i = t;
- }
-}
-/*************************************************************************/
-//! Add dbf to dbf list.
-/*!
- Adds an xbDbf class instance to the list of dbf's.
-
- \param d the xbDbf instance to be added
- \param DatabaseName name of the database
-
- \returns One of the following return codes:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_NO_MEMORY</td><td>Out of memory</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No Error \\ \hline
- XB\_NO\_MEMORY & Out of memory \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbXBase::AddDbfToDbfList(xbDbf *d, const char *DatabaseName) {
- xbDbList *i, *s, *t;
-
- if(!FreeDbfList) {
- if((i = (xbDbList *)malloc(sizeof(xbDbList))) == NULL) {
- return XB_NO_MEMORY;
- }
- } else {
- i = FreeDbfList;
- FreeDbfList = i->NextDbf;
- }
- memset(i, 0x00, sizeof(xbDbList));
-
- i->DbfName = strdup(DatabaseName);
- i->dbf = d;
-
- /* insert new dbf into the list of open dbf files, sorted by dbf name */
- s = NULL;
- t = DbfList;
- while(t && strcmp(t->DbfName, DatabaseName) < 0) {
- s = t;
- t = t->NextDbf;
- }
- i->NextDbf = t;
- if (s == NULL)
- DbfList = i;
- else
- s->NextDbf = i;
-
- return 0;
-}
-/***********************************************************************/
-//! Remove dbf from dbf list.
-/*!
- Removes the specified xbDbf class instance from the list of dbf's.
-
- \param d xbDbf to be removed
-
- \returns One of the following return codes:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No Error \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbXBase::RemoveDbfFromDbfList(xbDbf *d) {
- xbDbList *i, *s;
-
- i = DbfList;
- s = NULL;
-
- while (i) {
- if(i->dbf == d) {
- /* remove it from current chain */
- if(s)
- s->NextDbf = i->NextDbf;
- else
- DbfList = i->NextDbf;
-
- /* add i to the current free chain */
- i->NextDbf = FreeDbfList;
- FreeDbfList = i;
- free(FreeDbfList->DbfName);
- FreeDbfList->DbfName = NULL;
- break;
- } else {
- s = i;
- i = i->NextDbf;
- }
- }
- return XB_NO_ERROR;
-}
-
-// FIXME: byte reverse methods are awful, compared to bitwise shifts -- willy
-
-/************************************************************************/
-//! Get a portable short value.
-/*!
- Converts a short (16 bit integer) value stored at p from a portable
- format to the machine format.
-
- \param p pointer to memory containing the portable short value
-
- \returns the short value.
-*/
-/* This routine returns a short value from a 2 byte character stream */
-xbShort xbXBase::GetShort(const char *p) {
- xbShort s, i;
- const char *sp;
- char *tp;
-
- s = 0;
- tp = (char *) &s;
- sp = p;
- if( EndianType == 'L' )
- for( i = 0; i < 2; i++ ) *tp++ = *sp++;
- else
- {
- sp++;
- for( i = 0; i < 2; i++ ) *tp++ = *sp--;
- }
- return s;
-}
-/*************************************************************************/
-//! Get a portable long value.
-/*!
- Converts a long (32 bit integer) value stored at p from a portable
- format to the machine format.
-
- \param p pointer to memory containing the portable long value
-
- \returns the long value.
-*/
-/* This routine returns a long value from a 4 byte character stream */
-xbLong xbXBase::GetLong( const char *p )
-{
- xbLong l;
- const char *sp;
- char *tp;
- xbShort i;
-
- tp = (char *) &l;
- sp = p;
- if( EndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *sp++;
- else
- {
- sp+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *sp--;
- }
- return l;
-}
-/*************************************************************************/
-//! Get a portable unsigned long value.
-/*!
- Converts an unsigned long (32 bit integer) value stored at p from a portable
- format to the machine format.
-
- \param p pointer to memory containing the portable unsigned long value
-
- \returns the unsigned long value.
-*/
-/* This routine returns a long value from a 4 byte character stream */
-xbULong xbXBase::GetULong( const char *p )
-{
- xbULong l;
- char *tp;
- xbShort i;
-
- tp = (char *) &l;
- if( EndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *p++;
- else{
- p+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *p--;
- }
- return l;
-}
-
-/************************************************************************/
-//! Get a high byte first short value.
-/*!
- Converts a short (16 bit integer) value stored at p from a high byte first
- format to the machine format.
-
- \param p pointer to memory containing the high byte first short value
-
- \returns the short value.
-*/
-/* This routine returns a short value from a 2 byte character stream */
-xbShort xbXBase::GetHBFShort(const char *p) {
- xbShort s, i;
- const char *sp;
- char *tp;
-
- s = 0;
- tp = (char *) &s;
- sp = p;
- if( EndianType == 'B' )
- for( i = 0; i < 2; i++ ) *tp++ = *sp++;
- else
- {
- sp++;
- for( i = 0; i < 2; i++ ) *tp++ = *sp--;
- }
- return s;
-}
-
-/*************************************************************************/
-//! Get a high byte first unsigned long value.
-/*!
- Converts an unsigned long (32 bit integer) value stored at p from a high byte first
- format to the machine format.
-
- \param p pointer to memory containing the high byte first unsigned long value
-
- \returns the unsigned long value.
-*/
-/* This routine returns a long value from a 4 byte character stream */
-xbULong xbXBase::GetHBFULong( const char *p )
-{
- xbULong l;
- char *tp;
- xbShort i;
-
- tp = (char *) &l;
- if( EndianType == 'B' )
- for( i = 0; i < 4; i++ ) *tp++ = *p++;
- else{
- p+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *p--;
- }
- return l;
-}
-/*************************************************************************/
-//! Get a portable double value.
-/*!
- Converts a double (64 bit floating point) value stored at p from a portable
- format to the machine format.
-
- \param p pointer to memory containing the portable double value
-
- \returns the double value.
-*/
-/* This routine returns a double value from an 8 byte character stream */
-xbDouble xbXBase::GetDouble( const char *p )
-{
- xbDouble d;
- const char *sp;
- char *tp;
- xbShort i;
-
- tp = (char *) &d;
- sp = p;
- if( EndianType == 'L' )
- for( i = 0; i < 8; i++ ) *tp++ = *sp++;
- else
- {
- sp+=7;
- for( i = 0; i < 8; i++ ) *tp++ = *sp--;
- }
-
- return d;
-}
-/*************************************************************************/
-//! Put a portable short value.
-/*!
- Converts a short (16 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- \param c pointer to memory to hold converted value
- \param s value to be converted
-*/
-/* This routine puts a short value to a 2 byte character stream */
-void xbXBase::PutShort( char * c, xbShort s )
-{
- const char *sp;
- char *tp;
- xbShort i;
-
- tp = c;
- sp = (const char *) &s;
-
- if( EndianType == 'L' )
- {
- for( i = 0; i < 2; i++ ) *tp++ = *sp++;
- }
- else /* big endian */
- {
- sp++;
- for( i = 0; i < 2; i++ ) *tp++ = *sp--;
- }
- return;
-}
-
-/*************************************************************************/
-//! Put a portable long value.
-/*!
- Converts a long (32 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- \param c pointer to memory to hold converted value
- \param l value to be converted
-*/
-/* This routine puts a long value to a 4 byte character stream */
-void xbXBase::PutLong( char * c, xbLong l )
-{
- const char *sp;
- char *tp;
- xbShort i;
-
- tp = c;
- sp = (const char *) &l;
- if( EndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *sp++;
- else
- {
- sp+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *sp--;
- }
- return;
-}
-/*************************************************************************/
-//! Put a portable unsigned short value.
-/*!
- Converts an unsigned long (16 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- \param c pointer to memory to hold converted value
- \param s value to be converted
-*/
-/* This routine puts a short value to a 2 byte character stream */
-void xbXBase::PutUShort( char * c, xbUShort s )
-{
- const char *sp;
- char *tp;
- xbShort i;
-
- tp = c;
- sp = (const char *) &s;
- if( EndianType == 'L' )
- for( i = 0; i < 2; i++ ) *tp++ = *sp++;
- else
- {
- sp++;
- for( i = 0; i < 2; i++ ) *tp++ = *sp--;
- }
- return;
-}
-/*************************************************************************/
-//! Put a portable unsigned long value.
-/*!
- Converts an unsigned long (32 bit integer) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- \param c pointer to memory to hold converted value
- \param l value to be converted
-*/
-/* This routine puts a long value to a 4 byte character stream */
-void xbXBase::PutULong( char * c, xbULong l )
-{
- const char *sp;
- char *tp;
- xbShort i;
-
- tp = c;
- sp = (const char *) &l;
- if( EndianType == 'L' )
- for( i = 0; i < 4; i++ ) *tp++ = *sp++;
- else
- {
- sp+=3;
- for( i = 0; i < 4; i++ ) *tp++ = *sp--;
- }
- return;
-}
-/*************************************************************************/
-//! Put a portable double value.
-/*!
- Converts a double (64 floating point) value from machine format to a
- portable format and stores the converted value in the memory referenced
- by c.
-
- \param c pointer to memory to hold converted value
- \param d value to be converted
-*/
-/* This routine puts a double value to an 8 byte character stream */
-void xbXBase::PutDouble( char * c, xbDouble d )
-{
- const char *sp;
- char *tp;
- xbShort i;
-
- tp = c;
- sp = (const char *) &d;
- if( EndianType == 'L' )
- for( i = 0; i < 8; i++ ) *tp++ = *sp++;
- else
- {
- sp+=7;
- for( i = 0; i < 8; i++ ) *tp++ = *sp--;
- }
- return;
-}
-/************************************************************************/
-//! Get offset of last PATH_SEPARATOR in Name.
-/*!
- Scans the specified Name for the last occurance of PATH_SEPARATOR.
-
- \param Name string to be scanned.
-
- \returns offset of last occurance of PATH_SEPARATOR
-*/
-xbShort xbXBase::DirectoryExistsInName( const char * Name )
-{
- /* returns the offset in the string of the last directory slash */
-
- xbShort Count, Mark;
- char Delim;
- const char *p;
-
- Delim = PATH_SEPARATOR;
-
- Count = Mark = 0;
- p = Name;
-
- while( *p )
- {
- Count++;
- if( *p++ == Delim ) Mark = Count;
- }
- return Mark;
-}
-
-/************************************************************************/
-//! Display description of error code.
-/*!
- Displays a text description of an XBase error code.
-
- \param ErrorCode error to be displayed
-*/
-void xbXBase::DisplayError( xbShort ErrorCode ) const
-{
- std::cout << GetErrorMessage( ErrorCode ) << std::endl;
-}
-/************************************************************************/
-//! Get description of error code.
-/*!
- Returns a pointer to string containing a text description of an
- error code.
-
- \param ErrorCode error number of description to be returned
-*/
-const char* xbXBase::GetErrorMessage( xbShort ErrorCode )
-{
- switch( ErrorCode ) {
- case 0: return "No Error";
- case -100: return "End Of File";
- case -101: return "Beginning Of File";
- case -102: return "No Memory";
- case -103: return "File Already Exists";
- case -104: return "Database or Index Open Error";
- case -105: return "Error writing to disk drive";
- case -106: return "Unknown Field Type";
- case -107: return "Database already open";
- case -108: return "Not an Xbase type database";
- case -109: return "Invalid Record Number";
- case -110: return "Invalid Option";
- case -111: return "Database not open";
- case -112: return "Disk Drive Seek Error";
- case -113: return "Disk Drive Read Error";
- case -114: return "Search Key Not Found";
- case -115: return "Search Key Found";
- case -116: return "Invalid Key";
- case -117: return "Invalid Node Link";
- case -118: return "Key Not Unique";
- case -119: return "Invalid Key Expression";
- case -120: return "DBF File Not Open";
- case -121: return "Invalid Key Type";
- case -122: return "Invalid Node No";
- case -123: return "Node Full";
- case -124: return "Invalid Field Number";
- case -125: return "Invalid Data";
- case -126: return "Not a leaf node";
- case -127: return "Lock Failed";
- case -128: return "Close Error";
- case -129: return "Invalid Schema";
- case -130: return "Invalid Name";
- case -131: return "Invalid Block Size";
- case -132: return "Invalid Block Number";
- case -133: return "Not a Memo field";
- case -134: return "No Memo Data";
- case -135: return "Expression syntax error";
- case -136: return "Parse Error";
- case -137: return "No Data";
- case -138: return "Unknown Token Type";
- case -140: return "Invalid Field";
- case -141: return "Insufficient Parms";
- case -142: return "Too Many Parms";
- case -143: return "Invalid or Undefined Function";
- case -144: return "Invalid Field Length";
- case -145: return "Harvest Node";
- case -146: return "Invalid Date";
- case -147: return "Invalid Lock Option";
- default: return "Unknown error code";
- }
-}
-/************************************************************************/
-#ifdef XB_LOCKING_ON
-
-//! File lock routine
-/*!
- Lowest level lock routine
- Locks/unlocks a database,memo or index file.
- This function assumes the file position has been correctly set
-
- \param fn file to lock/unlock
- \param LockType lock type, one of: XB_LOCK or XB_UNLOCK
- \param lockLen byte count to lock
-*/
-
-#ifdef __WIN32__
-xbShort xbXBase::LockFile( int fn, xbShort LockType, xbOffT lockLen)
-{
-
- int mode;
- int rc;
- int tries = 0;
-
- /* convert the xbase locking command into a windows locking command */
- if( LockType == XB_UNLOCK )
- mode = LK_UNLCK;
- else if( LockType == XB_LOCK || LockType == XB_LOCK_HOLD )
- mode = LK_NBLCK;
- else
- return XB_INVALID_LOCK_OPTION;
-
- do{
- rc = locking( fn, mode, lockLen );
- if( rc )
- _sleep( 1 );
- } while( rc == -1 && tries++ < GetLockRetryCount());
-
- if( rc )
- return XB_LOCK_FAILED;
-
- return 0;
-}
-
-#elif HAVE_FCNTL_H
-
-xbShort xbXBase::LockFile( int fn, xbShort LockType, xbOffT lockLen )
-{
- xbShort cmd, rc;
- xbShort tries = 0;
-
-/* convert cross platform xbase lock type to unix lock type */
- if( LockType == XB_UNLOCK )
- cmd = F_ULOCK;
- else if( LockType == XB_LOCK || LockType == XB_LOCK_HOLD )
- cmd = F_TLOCK;
- else
- return XB_INVALID_LOCK_OPTION;
-
-/* do the actual lock */
- do{
- #ifdef _LARGEFILE64_SOURCE
- rc = lockf64( fn, cmd, lockLen );
- #else
- rc = lockf( fn, cmd, lockLen );
- #endif
- if( rc == -1 && errno != EINTR ){
- tries++;
- sleep(1);
- }
- } while( rc == -1 && tries < GetLockRetryCount());
-
- if( rc )
- return XB_LOCK_FAILED;
-
- return XB_NO_ERROR;
-}
-#endif // HAVE_FCNTL
-#endif // XB_LOCKING_ON
-
-/************************************************************************/
-#ifdef XB_LOCKING_ON
-
-//! Set high level lock mode
-/*!
-
- \param nlm New lock mode
-*/
-
-xbShort xbXBase::SetLockMode( xbShort nlm )
-{
- if( nlm != XB_SINGLE_USER_MODE && nlm != XB_XBASE_LOCK_MODE &&
- nlm != XB_DBASE5_LOCK_MODE && nlm != XB_CLIPPER5_LOCK_MODE &&
- nlm != XB_FOXPRO3_LOCK_MODE )
- return XB_INVALID_LOCK_OPTION;
-
- LockMode = nlm;
- return XB_NO_ERROR;
-}
-
-#endif // XB_LOCKING_ON
-
-
-
diff --git a/xbase64/xbase64.h b/xbase64/xbase64.h
deleted file mode 100755
index 7267299..0000000
--- a/xbase64/xbase64.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* xbase64.h
-
- Xbase project source code
-
- This file contains a header file for the xbXBase class, which is the
- base class for using the Xbase DBMS library.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XB_XBASE_H__
-#define __XB_XBASE_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <string.h>
-
-#if defined(__WIN32__)
-#include "windows.h"
-
-// ripped from wxWindows
-
-// _declspec works in BC++ 5 and later, as well as VC++
-#if defined(__VISUALC__) || defined(__BORLANDC__) || defined(__GNU LesserC__)
-# ifdef XBMAKINGDLL
-# define XBDLLEXPORT __declspec( dllexport )
-# define XBDLLEXPORT_DATA(type) __declspec( dllexport ) type
-# define XBDLLEXPORT_CTORFN
-# elif defined(XBUSINGDLL)
-# define XBDLLEXPORT __declspec( dllimport )
-# define XBDLLEXPORT_DATA(type) __declspec( dllimport ) type
-# define XBDLLEXPORT_CTORFN
-# else
-# define XBDLLEXPORT
-# define XBDLLEXPORT_DATA(type) type
-# define XBDLLEXPORT_CTORFN
-# endif
-
-#else
-
-# define XBDLLEXPORT
-# define XBDLLEXPORT_DATA(type) type
-# define XBDLLEXPORT_CTORFN
-#endif
-
-#else // !Windows
-# define XBDLLEXPORT
-# define XBDLLEXPORT_DATA(type) type
-# define XBDLLEXPORT_CTORFN
-#endif // Win/!Win
-
-
-#define XB_SINGLE_USER_MODE 0
-#define XB_UNLOCK 200
-#define XB_LOCK 201
-#define XB_LOCK_HOLD 202
-
-#ifdef XB_LOCKING_ON
-
- #ifdef HAVE_SYS_LOCKING_H
- #include <sys/locking.h>
- #ifdef __MINGW32__
- #defibe locking _locking
- #endif
- #endif
-
- #ifdef HAVE_FCNTL_H
- #include <fcntl.h>
- #endif
-
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
-
- #define XB_XBASE_LOCK_MODE 200
- #define XB_DBASE5_LOCK_MODE 201
- #define XB_CLIPPER5_LOCK_MODE 202
- #define XB_FOXPRO3_LOCK_MODE 203
-
-#endif // XB_LOCKING_ON
-
-#include "xbtypes.h"
-#include "xbretcod.h"
-#include "xbdate.h"
-#include "xbstring.h"
-
-#ifndef XB_MIN
-#define XB_MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif /* XB_MIN */
-
-// 3/18/04 next macro isn't currently used in the library - GK
-//#ifndef XB_MAX
-//#define XB_MAX(a, b) (((a) < (b)) ? (b) : (a))
-//#endif /* XB_MAX */
-
-/*! \file xbase64.h
-*/
-
-class XBDLLEXPORT xbDbf;
-
-//! xbDbList struct
-/*!
-*/
-struct XBDLLEXPORT xbDbList{
- xbDbList * NextDbf;
- char * DbfName;
- xbDbf * dbf;
-};
-
-//! xbXBase class
-/*!
-*/
-class XBDLLEXPORT xbXBase {
- public:
- ~xbXBase();
- xbXBase();
- xbShort AddDbfToDbfList(xbDbf *d, const char *DatabaseName);
- xbDbf * GetDbfPtr( const char *Name );
- xbShort DirectoryExistsInName( const char *Name );
- xbShort GetEndianType() { return EndianType; }
- void DisplayError( xbShort ErrorCode ) const;
- static const char* GetErrorMessage( xbShort ErrorCode );
- xbString & GetDefaultDateFormat() { return DefaultDateFormat; }
- void SetDefaultDateFormat( const xbString & f ){ DefaultDateFormat = f; }
-
- /* next 6 routines handle both big endian and little endian machines */
- xbDouble GetDouble( const char *p );
- xbLong GetLong ( const char *p );
- xbULong GetULong ( const char *p );
- xbShort GetShort ( const char *p );
- xbULong GetHBFULong( const char *p );
- xbShort GetHBFShort ( const char *p );
-
- void PutLong ( char *p, const xbLong l );
- void PutShort ( char *p, const xbShort s );
- void PutULong ( char *p, const xbULong l );
- void PutUShort( char *p, const xbUShort s );
- void PutDouble( char *p, const xbDouble d );
-
- xbShort RemoveDbfFromDbfList( xbDbf * );
-
-#ifdef XB_LOCKING_ON
- xbShort GetLockRetryCount(){ return LockRetryCount; }
- void SetLockRetryCount( xbShort lrc ) { LockRetryCount = lrc; }
- xbShort LockFile( int fn, xbShort type, xbOffT len );
- xbShort GetLockMode() { return LockMode; }
- xbShort SetLockMode( xbShort nlm );
-#endif
-
-protected:
- xbDbList * DbfList;
- xbDbList * FreeDbfList;
- xbShort EndianType; /* B = Big Endian, L = Little Endian */
-
-private:
- xbString DefaultDateFormat;
-
-#ifdef XB_LOCKING_ON
- xbShort LockRetryCount;
- xbShort LockMode;
-#endif
-};
-
-#include "xbdbf.h"
-
-#if defined(XB_EXPRESSIONS)
-#include "xbexp.h"
-#endif
-
-#if defined(XB_INDEX_ANY)
-#include "xbindex.h"
-#include "xbmindex.h"
-#endif
-
-#ifdef XB_LOCKING_ON
-#include "xblock.h"
-#endif
-
-#ifdef XB_INDEX_NDX
-#include "xbndx.h"
-#endif
-
-#ifdef XB_INDEX_NTX
-#include "xbntx.h"
-#endif
-
-#ifdef XB_INDEX_CDX
-#include "xbcdx.h"
-#endif
-
-#if defined(XB_FILTERS) && !defined(XB_INDEX_ANY)
-#error XB_FILTERS cant be used without index support
-#elif defined(XB_FILTERS)
-#include "xbfilter.h"
-#endif
-
-#endif // __XB_XBASE_H__
-
-
-
diff --git a/xbase64/xbcdx.cpp b/xbase64/xbcdx.cpp
deleted file mode 100755
index 83a69df..0000000
--- a/xbase64/xbcdx.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#include "xbtypes.h"
-#include "xbcdx.h"
-
-xbShort xbCdx::CreateIndex(const char* filename, const char *expr,
- xbShort unique, xbShort overwrite)
-{
- return CreateIndex(filename, "NoName", expr, unique, overwrite);
-}
-
-xbShort xbCdx::CreateIndex(const char* filename, const char *tagName,
- const char *expr, xbShort unique, xbShort overwrite)
-{
- if (IsOpen()) CloseIndex();
- SetFileName(filename);
-
- indexfp=fopen(GetFileName(), "wb+");
- WriteTagHeader(tagName);
- WriteTagRoot(tagName);
- WriteIndexHeader(expr);
- WriteIndexRoot();
- return 0;
-}
-
-const char* xbCdx::GetExtWithDot(bool lower)
-{
- return lower? ".cdx": ".CDX";
-}
-
-void xbCdx::WriteTagHeader(const char* tagName)
-{
- memset(&tagHeader_, 0, sizeof(tagHeader_));
- tagHeader_.rootNode=0x400;
- tagHeader_.keyLen=strlen(tagName)+1;
- tagHeader_.features.feature=0xe0;
- tagHeader_.signature=1;
- tagHeader_.totalExprLen=1;
- tagHeader_.forExprLen=1;
- tagHeader_.keyExprLen=1;
- fwrite(&tagHeader_, sizeof(tagHeader_), 1, indexfp);
-}
-
-void xbCdx::WriteTagRoot(const char* tagName)
-{
- memset(&tagRootNode_, 0, sizeof(tagRootNode_));
- tagRootNode_.attr=3;
- tagRootNode_.keyCount=1;
- tagRootNode_.leftSibling=-1;
- tagRootNode_.rightSibling=-1;
- tagRootNode_.freeSpace=476;
- tagRootNode_.recNumberMask=0xffff;
- tagRootNode_.dupByteCounterMask=0xf;
- tagRootNode_.tailByteCounterMask=0xf;
- tagRootNode_.recBitUsing=16;
- tagRootNode_.dupBitUsing=4;
- tagRootNode_.tailBitUsing=4;
- tagRootNode_.byteCount=3;
- xbShort indexHeadOffset=0x600;
- int len=sizeof(indexHeadOffset);
- memcpy(tagRootNode_.keys, &indexHeadOffset, len);
- tagRootNode_.keys[len]=16;
- len=strlen(tagName);
- xbString tag=tagName;
- tag.toUpperCase();
- memcpy(tagRootNode_.keys+sizeof(tagRootNode_.keys)-len, tag.c_str(), len);
- fwrite(&tagRootNode_, sizeof(tagRootNode_), 1, indexfp);
-}
-
-void xbCdx::WriteIndexHeader(const char* expr)
-{
- memset(&indexHeader_, 0, sizeof(indexHeader_));
- indexHeader_.rootNode=0xa00;
- indexHeader_.keyLen=33;
- indexHeader_.features.feature=0x60;
- indexHeader_.signature=1;
- indexHeader_.totalExprLen=strlen(expr)+1;
- indexHeader_.forExprLen=1;
- indexHeader_.keyExprLen=strlen(expr)+1;
- xbString exprn=expr;
- exprn.toUpperCase();
- memcpy(indexHeader_.keyforBuffer, exprn.c_str(), indexHeader_.keyExprLen);
- fwrite(&indexHeader_, sizeof(indexHeader_), 1, indexfp);
-}
-
-void xbCdx::WriteIndexRoot()
-{
- memset(&indexRootNode_, 0, sizeof(indexRootNode_));
- indexRootNode_.attr=3;
- indexRootNode_.keyCount=0;
- indexRootNode_.leftSibling=-1;
- indexRootNode_.rightSibling=-1;
- indexRootNode_.freeSpace=488;
- indexRootNode_.recNumberMask=0x0fff;
- indexRootNode_.dupByteCounterMask=0x3f;
- indexRootNode_.tailByteCounterMask=0x3f;
- indexRootNode_.recBitUsing=12;
- indexRootNode_.dupBitUsing=6;
- indexRootNode_.tailBitUsing=6;
- indexRootNode_.byteCount=3;
- fwrite(&indexRootNode_, sizeof(indexRootNode_), 1, indexfp);
-}
-
-xbShort xbCdx::GetHeadNode()
-{
- ReadTagHeader();
- ReadIndexHeader(GetIndexTagOffset());
- return XB_NO_ERROR;
-}
-
-void xbCdx::ReadTagHeader()
-{
- _fseek(indexfp, 0, SEEK_SET);
- fread(&tagHeader_, sizeof(tagHeader_), 1, indexfp);
-}
diff --git a/xbase64/xbcdx.h b/xbase64/xbcdx.h
deleted file mode 100755
index f76a45f..0000000
--- a/xbase64/xbcdx.h
+++ /dev/null
@@ -1,150 +0,0 @@
-#ifndef cdx_h
-#define cdx_h
-
-#include "xbmindex.h"
-
-struct CdxHeader
-{
- xbLong rootNode;
- xbLong freeNode;
- xbLong reserved;
- xbShort keyLen;
- union cdxFeatures
- {
- struct Features
- {
- bool unique:1;
- int:2;
- bool hasFor:1;
- bool:1;
- bool cdxHeader:1;
- bool cdxFmt:1;
- bool cdxTagHeader:1;
- } features;
- char feature;
- } features;
- char signature;
- xbLong reserved1[5];
- char reserved2[466];
- xbShort descending;
- xbShort totalExprLen;
- xbShort forExprLen;
- xbShort reserved4;
- xbShort keyExprLen;
- char keyforBuffer[512];
-};
-
-struct CdxNode
-{
- xbShort attr;
- xbShort keyCount;
- xbLong leftSibling;
- xbLong rightSibling;
-}
-#ifdef __GNU LesserC__
- __attribute__((packed))
-#endif
-;
-
-struct CdxInnerNode: public CdxNode
-{
- char keys[500];
-}
-#ifdef __GNU LesserC__
- __attribute__((packed))
-#endif
-;
-
-struct CdxLeafNode: public CdxNode
-{
- xbShort freeSpace;
- xbLong recNumberMask;
- char dupByteCounterMask;
- char tailByteCounterMask;
- char recBitUsing;
- char dupBitUsing;
- char tailBitUsing;
- char byteCount;
- char keys[488];
-}
-#ifdef __GNU LesserC__
- __attribute__((packed))
-#endif
-;
-
-class XBDLLEXPORT xbCdx: public xbMultiIndex
-{
- public:
-// xbCdx() {} I don't like to make empty object with no protection
-// to method method call. And I don't see any need of it.
- xbCdx(xbDbf* dbf): xbMultiIndex(dbf)
- {
- memset(&indexHeader_, 0, sizeof(indexHeader_));
- memset(&tagHeader_, 0, sizeof(tagHeader_));
- }
-
- virtual ~xbCdx() {CloseIndex();}
-
- virtual xbShort CreateIndex(const char *filename, const char *expr,
- xbShort unique, xbShort overwrite);
- virtual xbShort CreateIndex(const char *filename, const char* tagname,
- const char *expr, xbShort unique, xbShort overwrite);
-
- virtual xbShort AddTag(const char* tagname, const char *expr,
- xbShort unique, xbShort overwrite) {return 0;}
-
- virtual xbLong GetTotalNodes() {return 0;}
- virtual xbULong GetCurDbfRec() {return 0;}
- virtual xbShort CreateKey( xbShort, xbShort ) {return 0;}
- virtual xbShort GetCurrentKey(char *key) {return 0;}
- virtual xbShort AddKey( xbLong ) {return 0;}
- virtual xbShort UniqueIndex() {return 0;}
- virtual xbShort DeleteKey( xbLong ) {return 0;}
- virtual xbShort KeyWasChanged() {return 0;}
- virtual xbShort FindKey( const char * ) {return 0;}
- virtual xbShort FindKey() {return 0;}
- virtual xbShort FindKey( xbDouble ) {return 0;}
- virtual xbShort GetNextKey() {return 0;}
- virtual xbShort GetLastKey() {return 0;}
- virtual xbShort GetFirstKey() {return 0;}
- virtual xbShort GetPrevKey() {return 0;}
- virtual xbShort ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0) {return 0;}
- virtual xbShort KeyExists( xbDouble ) {return 0;}
- virtual void GetExpression(char *buf, int len) {}
-#ifdef XBASE_DEBUG
- virtual void DumpHdrNode( xbShort Option ) {};
- virtual void DumpNodeRec( xbLong ) {};
- virtual void DumpNodeChain() {};
- virtual xbShort CheckIndexIntegrity( xbShort ) {return 0;};
-#endif
-
-// static xbString CreateIndexName(const xbString& dbfName);
- virtual const char* GetExtWithDot(bool lower);
- const CdxHeader& GetIndexHeader() {return indexHeader_;}
- const CdxHeader& GetTagHeader() {return tagHeader_;}
-
- protected:
- virtual xbShort GetHeadNode();
- virtual xbUShort GetKeyLen() {return 0;}
- virtual const char* GetKeyExpression() {return "";}
- virtual void FreeNodesMemory() {}
- void ReadTagHeader();
- xbLong GetIndexTagOffset() {return 0;}
- void ReadIndexHeader(xbLong) {}
-
- private:
- xbCdx(const xbCdx&);
- xbCdx& operator=(const xbCdx&);
- void WriteTagHeader(const char* tagName);
- void WriteTagRoot(const char* tagName);
- void WriteIndexHeader(const char* expr);
- void WriteIndexRoot();
-
- private:
- CdxHeader tagHeader_;
- CdxLeafNode tagRootNode_;
- CdxHeader indexHeader_;
- CdxLeafNode indexRootNode_;
-};
-
-#endif
diff --git a/xbase64/xbconfig.h b/xbase64/xbconfig.h
deleted file mode 100644
index 15a3e69..0000000
--- a/xbase64/xbconfig.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* xbase64/xbconfig.h. Generated by configure. */
-/* xbase64/xbconfig.in. Generated from configure.in by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `fseeko' function. */
-#define HAVE_FSEEKO 1
-
-/* Define to 1 if you have the `ftello' function. */
-#define HAVE_FTELLO 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `vsnprintf' function. */
-#define HAVE_VSNPRINTF 1
-
-/* Define to 1 if you have the `vsprintf' function. */
-#define HAVE_VSPRINTF 1
-
-/* Name of package */
-#define PACKAGE "xbase64"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "xdb-devel@lists.sourceforge.net"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "xbase64"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "xbase64 3.1.2"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "xbase64"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "3.1.2"
-
-#define PATH_SEPARATOR '/'
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "3.1.2"
-
-/* XB_DEBUG */
-#define XBASE_DEBUG 1
-
-#define XB_DBT_BLOCK_SIZE 512
-
-/* XB_EXPRESSIONS */
-#define XB_EXPRESSIONS 1
-
-/* XB_FILTERS */
-#define XB_FILTERS 1
-
-/* XB_INDEX_ANY */
-#define XB_INDEX_ANY 1
-
-/* XB_INDEX_NDX */
-#define XB_INDEX_NDX 1
-
-/* XB_INDEX_NTX */
-#define XB_INDEX_NTX 1
-
-/* XB_LARGEFILE_SUPPORT */
-#define XB_LARGEFILE_SUPPORT 1
-
-/* XB_LOCKING_ON */
-#define XB_LOCKING_ON 1
-
-/* XB_MEMO_FIELDS */
-#define XB_MEMO_FIELDS 1
-
-/* XB_REAL_DELETE */
-#define XB_REAL_DELETE 1
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-/* # undef _ALL_SOURCE */
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#define _FILE_OFFSET_BITS 64
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
diff --git a/xbase64/xbconfig.in b/xbase64/xbconfig.in
deleted file mode 100755
index 8c25663..0000000
--- a/xbase64/xbconfig.in
+++ /dev/null
@@ -1,130 +0,0 @@
-/* xbase64/xbconfig.in. Generated from configure.in by autoheader. */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `fseeko' function. */
-#undef HAVE_FSEEKO
-
-/* Define to 1 if you have the `ftello' function. */
-#undef HAVE_FTELLO
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the `vsnprintf' function. */
-#undef HAVE_VSNPRINTF
-
-/* Define to 1 if you have the `vsprintf' function. */
-#undef HAVE_VSPRINTF
-
-/* Name of package */
-#undef PACKAGE
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-#define PATH_SEPARATOR '/'
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Version number of package */
-#undef VERSION
-
-/* XB_DEBUG */
-#undef XBASE_DEBUG
-
-#define XB_DBT_BLOCK_SIZE 512
-
-/* XB_EXPRESSIONS */
-#undef XB_EXPRESSIONS
-
-/* XB_FILTERS */
-#undef XB_FILTERS
-
-/* XB_INDEX_ANY */
-#undef XB_INDEX_ANY
-
-/* XB_INDEX_NDX */
-#undef XB_INDEX_NDX
-
-/* XB_INDEX_NTX */
-#undef XB_INDEX_NTX
-
-/* XB_LARGEFILE_SUPPORT */
-#undef XB_LARGEFILE_SUPPORT
-
-/* XB_LOCKING_ON */
-#undef XB_LOCKING_ON
-
-/* XB_MEMO_FIELDS */
-#undef XB_MEMO_FIELDS
-
-/* XB_REAL_DELETE */
-#undef XB_REAL_DELETE
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
-
-/* Define for large files, on AIX-style hosts. */
-#undef _LARGE_FILES
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
diff --git a/xbase64/xbdate.cpp b/xbase64/xbdate.cpp
deleted file mode 100755
index fd26438..0000000
--- a/xbase64/xbdate.cpp
+++ /dev/null
@@ -1,851 +0,0 @@
-/* xbdate.cpp
-
- Xbase64 project source code
-
- These functions are used for processing dates.
- All functions assume a standard date format of CCYYMMDD
- for Century,Year,Month and Day
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbdate.h"
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-#include <xbase64/xbase64.h>
-#include <xbase64/xbdate.h>
-//#include <xbase64/retcodes.h>
-
-/*! \file xbdate.cpp
-*/
-
-int xbDate::DaysInMonths[2][13];
-int xbDate::AggregatedDaysInMonths[2][13];
-
-#define EPOCH_MIN 100
-#define EPOCH_MAX 3000
-#define DAYS_AD(year) ((year) *365L + (year) / 4 - (year) / 100 + (year) / 400)
-
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-xbDate::xbDate( const xbString & Date8 ) {
- if( DateIsValid( Date8 ))
- cDate8 = Date8;
- else
- Sysdate();
- SetDateTables();
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-xbDate::xbDate( const char * Date8 ) {
- if( DateIsValid( Date8 ))
- cDate8 = Date8;
- else
- Sysdate(); /* if invalid date, set class to sysdate */
- SetDateTables();
-}
-/***************************************************************/
-//! Short description.
-/*!
-*/
-xbDate::xbDate()
-{
- Sysdate();
- SetDateTables();
-}
-
-/***************************************************************/
-//! Destructor
-/*!
-*/
-xbDate::~xbDate()
-{
-}
-/***************************************************************/
-//! Short description.
-/*!
-*/
-void xbDate::SetDateTables() {
- if( AggregatedDaysInMonths[1][12] != 366 ){ /* first time called ? */
- AggregatedDaysInMonths[0][0] = 0;
- AggregatedDaysInMonths[0][1] = 31;
- AggregatedDaysInMonths[0][2] = 59;
- AggregatedDaysInMonths[0][3] = 90;
- AggregatedDaysInMonths[0][4] = 120;
- AggregatedDaysInMonths[0][5] = 151;
- AggregatedDaysInMonths[0][6] = 181;
- AggregatedDaysInMonths[0][7] = 212;
- AggregatedDaysInMonths[0][8] = 243;
- AggregatedDaysInMonths[0][9] = 273;
- AggregatedDaysInMonths[0][10] = 304;
- AggregatedDaysInMonths[0][11] = 334;
- AggregatedDaysInMonths[0][12] = 365;
- AggregatedDaysInMonths[1][0] = 0;
- AggregatedDaysInMonths[1][1] = 31;
- AggregatedDaysInMonths[1][2] = 60;
- AggregatedDaysInMonths[1][3] = 91;
- AggregatedDaysInMonths[1][4] = 121;
- AggregatedDaysInMonths[1][5] = 152;
- AggregatedDaysInMonths[1][6] = 182;
- AggregatedDaysInMonths[1][7] = 213;
- AggregatedDaysInMonths[1][8] = 244;
- AggregatedDaysInMonths[1][9] = 274;
- AggregatedDaysInMonths[1][10] = 305;
- AggregatedDaysInMonths[1][11] = 335;
- AggregatedDaysInMonths[1][12] = 366;
-
- DaysInMonths[0][0] = 0;
- DaysInMonths[0][1] = 31;
- DaysInMonths[0][2] = 28;
- DaysInMonths[0][3] = 31;
- DaysInMonths[0][4] = 30;
- DaysInMonths[0][5] = 31;
- DaysInMonths[0][6] = 30;
- DaysInMonths[0][7] = 31;
- DaysInMonths[0][8] = 31;
- DaysInMonths[0][9] = 30;
- DaysInMonths[0][10] = 31;
- DaysInMonths[0][11] = 30;
- DaysInMonths[0][12] = 31;
- DaysInMonths[1][0] = 0;
- DaysInMonths[1][1] = 31;
- DaysInMonths[1][2] = 29;
- DaysInMonths[1][3] = 31;
- DaysInMonths[1][4] = 30;
- DaysInMonths[1][5] = 31;
- DaysInMonths[1][6] = 30;
- DaysInMonths[1][7] = 31;
- DaysInMonths[1][8] = 31;
- DaysInMonths[1][9] = 30;
- DaysInMonths[1][10] = 31;
- DaysInMonths[1][11] = 30;
- DaysInMonths[1][12] = 31;
- }
-}
-
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this function returns century and year from a CCYYMMDD date */
-int xbDate::CenturyOf( const char * Date8 ) const
-{
- char Century[3];
- Century[0] = Date8[0];
- Century[1] = Date8[1];
- Century[2] = 0x00;
- return( atoi( Century ));
-}
-
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this function returns century and year from a CCYYMMDD date */
-int xbDate::YearOf( const char * Date8 ) const
-{
- char year[5];
- year[0] = Date8[0];
- year[1] = Date8[1];
- year[2] = Date8[2];
- year[3] = Date8[3];
- year[4] = 0x00;
- return( atoi( year ));
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this function returns the month from a CCYYMMDD date */
-int xbDate::MonthOf( const char * Date8 ) const
-{
- char month[3];
- month[0] = Date8[4];
- month[1] = Date8[5];
- month[2] = 0x00;
- return( atoi( month ));
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this function returns TRUE if a CCYYMMDD date is a leap year*/
-
-int xbDate::IsLeapYear( const char * Date8 ) const
-{
- int year;
- year = YearOf( Date8 );
- if(( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 )
- return 1;
- else
- return 0;
-}
-
-/***************************************************************/
-//! Short description.
-/*!
- \param CalcYear
-*/
-/* this function returns TRUE if a CCYYMMDD date is a leap year*/
-
-int xbDate::CalcRollingCenturyForYear( int CalcYear ) const
-{
- /* this routine calculates a century for a year - it uses
- an 80/20 rolling date window to calculate the century */
-
- xbDate d;
- int ThisYear = YearOf( d.Sysdate() );
- int ThisCentury = CenturyOf( d.Sysdate() );
-
- ThisYear -= (ThisCentury * 100);
-
- if( ThisYear < 80 && CalcYear < (ThisYear+20) )
- return ThisCentury;
-
- else if( ThisYear >= 80 &&
- CalcYear < ThisYear &&
- CalcYear >= (ThisYear-80))
- return ThisCentury;
-
- else
- return ThisCentury - 1;
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Format
- \param Date8
-*/
-/* this function returns the "day of" from a CCYYMMDD date */
-
-/* format = XB_FMT_WEEK Number of day in WEEK 0-6 ( Sun - Sat )
- format = XB_FMT_MONTH Number of day in MONTH 1-31
- format = XB_FMT_YEAR Number of day in YEAR 1-366
-*/
-
-int xbDate::DayOf( int Format, const char * Date8 ) const
-{
- char day[3];
- int iday, imonth, iyear, iday2;
-
- /* check for valid format switch */
-
- if( Format!=XB_FMT_WEEK && Format!=XB_FMT_MONTH && Format!=XB_FMT_YEAR )
- return XB_INVALID_OPTION;
-
- if( Format == XB_FMT_WEEK )
- {
- iday = DayOf( XB_FMT_MONTH, Date8 );
- imonth = MonthOf( Date8 );
- iyear = YearOf ( Date8 );
-
- /* The following formula uses Zeller's Congruence to determine
- the day of the week */
-
- if( imonth > 2 ) /* init to February */
- imonth -= 2;
- else
- {
- imonth += 10;
- iyear--;
- }
-
- iday2 = ((13 * imonth - 1) / 5) +iday + ( iyear % 100 ) +
- (( iyear % 100 ) / 4) + ((iyear /100 ) / 4 ) - 2 *
- ( iyear / 100 ) + 77 ;
-
- return( iday2 - 7 * ( iday2 / 7 ));
- }
-
- else if( Format == XB_FMT_MONTH )
- {
- day[0] = Date8[6];
- day[1] = Date8[7];
- day[2] = 0x00;
- return( atoi( day ));
- }
- else
- return(
- AggregatedDaysInMonths[IsLeapYear(Date8)][MonthOf(Date8)-1]+
- DayOf(XB_FMT_MONTH, Date8));
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-/* this method sets the class date & returns the system date */
-
-xbString& xbDate::Sysdate()
-{
- char dt[9];
- time_t timer;
- struct tm *tblock;
- timer = time( NULL );
- tblock = localtime( &timer );
- tblock->tm_year += 1900;
- tblock->tm_mon++;
- sprintf( dt,"%4d%02d%02d",tblock->tm_year,tblock->tm_mon,tblock->tm_mday );
- dt[8] = 0x00;
- cDate8 = dt;
- return cDate8;
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this function checks a date for validity - returns 1 if OK */
-
-int xbDate::DateIsValid( const char * Date8 ) const
-{
- int year, month, day;
-
- if(!isdigit( Date8[0] ) || !isdigit( Date8[1] ) || !isdigit( Date8[2] ) ||
- !isdigit( Date8[3] ) || !isdigit( Date8[4] ) || !isdigit( Date8[5] ) ||
- !isdigit( Date8[6] ) || !isdigit( Date8[7] ) )
- return 0;
-
- year = YearOf ( Date8 );
- month = MonthOf( Date8 );
- day = DayOf ( XB_FMT_MONTH, Date8 );
-
- /* check the basics */
- if( year == 0 || month < 1 || month > 12 || day < 1 || day > 31 )
- return 0;
-
- /* April, June, September and November have 30 days */
- if(( month==4 || month==6 || month==9 || month==11 )&& day > 30 )
- return 0;
-
- /* check for February with leap year */
- if( month == 2 )
- if( IsLeapYear( Date8 ))
- {
- if( day > 29 )
- return 0;
- }
- else
- {
- if( day > 28 )
- return 0;
- }
- return 1;
-}
-
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-int xbDate::SetDate( const char * Date8 )
-{
- if( DateIsValid( Date8 ))
- {
- cDate8 = Date8;
- return 1;
- }
- return 0;
-}
-
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this returns the number of days since 1/1/EPOCH_MIN */
-long xbDate::JulianDays( const char * Date8 ) const
-{
- int year = YearOf( Date8 );
- if(( year < EPOCH_MIN ) || (year >= EPOCH_MAX))
- return XB_INVALID_DATE;
-
- long days = 0;
- for (long y = EPOCH_MIN; y < year; y++ )
- days += 365 + ( ( ( y%4==0 && y%100!=0 ) || y%400==0 ) ? 1 : 0 );
-
- days += (long) DayOf( XB_FMT_YEAR, Date8 ) -1;
-
- return days;
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param days
-*/
-/* this function does the opposite of the JulianDays function */
-/* it converts a julian based date into a Date8 format */
-
-xbString& xbDate::JulToDate8( long days )
-{
- char Date8[9];
- int year, leap, month;
-
- year = EPOCH_MIN;
- leap = 0; /* EPOCH_MIN of 100 is not a leap year */
-
-/* this while loop calculates the year of the date by incrementing
- the years counter as it decrements the days counter */
-
- while( days > ( 364+leap ))
- {
- days -= 365+leap;
- year++;
- if(( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 )
- leap = 1;
- else
- leap = 0;
- }
-
-/* this for loop calculates the month and day of the date by
- comparing the number of days remaining to one of the tables */
-
- for( month = 12; month >= 1; month-- )
- if( days >= (long)AggregatedDaysInMonths[leap][month] ) {
- days -= AggregatedDaysInMonths[leap][month];
- break;
- }
-
- sprintf( Date8, "%4d%02d%02ld", year, month+1, days+1 );
-
- Date8[8] = 0x00;
- cDate8 = Date8;
- return cDate8;
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this routine returns a pointer to the day of the week(Sun-Sat)*/
-xbString& xbDate::CharDayOf( const char * Date8 )
-{
- struct tm tblock;
- char buf[25];
-
- tblock.tm_year = YearOf( Date8 ) - 1900;
- tblock.tm_mon = MonthOf( Date8 ) - 1;
- tblock.tm_mday = DayOf( XB_FMT_MONTH, Date8 );
- tblock.tm_hour = 0;
- tblock.tm_min = 0;
- tblock.tm_sec = 1;
- tblock.tm_isdst = -1;
- if( mktime( &tblock ) == -1 )
- fDate = "????";
- else
- {
- strftime( buf, 25, "%A", &tblock );
- fDate = buf;
- }
- return fDate;
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this routine returns a pointer to the month */
-
-xbString& xbDate::CharMonthOf( const char * Date8 )
-{
- struct tm tblock;
- char buf[25];
-
- tblock.tm_year = YearOf( Date8 ) - 1900;
- tblock.tm_mon = MonthOf( Date8 ) - 1;
- tblock.tm_mday = DayOf( XB_FMT_MONTH, Date8 );
- tblock.tm_hour = 0;
- tblock.tm_min = 0;
- tblock.tm_sec = 1;
- tblock.tm_isdst = -1;
- if( mktime( &tblock ) == -1 )
- fDate = "????";
- else
- {
- strftime( buf, 25, "%B", &tblock );
- fDate = buf;
- }
- return fDate;
-}
-
-/***************************************************************/
-//! Short description.
-/*!
- \param indate in the format of MM/DD/YY
-*/
-/* This function formats a date and returns a pointer to a */
-/* static buffer containing the date */
-
-xbString& xbDate::FormatCTODdate( const char * indate )
-{
- xbDate d;
- char cbuf[3];
- char odate[9];
- fDate = "";
- if( indate[0] == ' ' || indate[1] == ' ' ) // empty date
- return fDate;
-
- sprintf( cbuf, "%02d",
- d.CalcRollingCenturyForYear( atoi( indate+6 )));
- odate[0] = cbuf[0];
- odate[1] = cbuf[1];
- odate[2] = indate[6];
- odate[3] = indate[7];
- odate[4] = indate[0];
- odate[5] = indate[1];
- odate[6] = indate[3];
- odate[7] = indate[4];
- odate[8] = 0x00;
-
- fDate = odate;
- return fDate;
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Format
- \param Date8
-*/
-/* This function formats a date and returns a pointer to a */
-/* static buffer containing the date */
-
-xbString& xbDate::FormatDate( const char * Format, const char * Date8 )
-{
- const char *FmtPtr; /* format pointer */
- char *BufPtr; /* buffer pointer */
- char type;
- char cbuf[10];
- int type_ctr, i;
- char buf[50];
- xbString s;
-
- memset( buf, 0x00, 50 );
- if( strstr( Format, "YYDDD" ))
- {
- buf[0] = Date8[2];
- buf[1] = Date8[3];
- sprintf( buf+2, "%03d", DayOf( XB_FMT_YEAR, Date8 ));
- }
- else
- {
- BufPtr = buf;
- FmtPtr = Format;
- memset( cbuf, 0x00, 10 );
- while( *FmtPtr )
- {
- if( *FmtPtr != 'D' && *FmtPtr != 'M' && *FmtPtr != 'Y' )
- {
- *BufPtr = *FmtPtr;
- BufPtr++;
- FmtPtr++;
- }
- else
- {
- type = *FmtPtr;
- type_ctr = 0;
- while( *FmtPtr == type )
- {
- type_ctr++;
- FmtPtr++;
- }
- switch( type )
- {
- case 'D':
- if( type_ctr == 1 )
- {
- sprintf( cbuf, "%d", DayOf( XB_FMT_MONTH, Date8 ));
- strcat( buf, cbuf );
- BufPtr += strlen( cbuf );
- }
- else if( type_ctr == 2 )
- {
- cbuf[0] = Date8[6];
- cbuf[1] = Date8[7];
- cbuf[2] = 0x00;
- strcat( buf, cbuf );
- BufPtr += 2;
- }
- else
- {
- s = CharDayOf( Date8 );
- if( type_ctr == 3 )
- {
- strncat( buf, s.getData(), 3 );
- BufPtr += 3;
- }
- else
- {
- strcpy( cbuf, CharDayOf( Date8 ));
- for( i = 0; i < 9; i++ )
- if( cbuf[i] == 0x20 ) cbuf[i] = 0x00;
- strcat( buf, cbuf );
- BufPtr += strlen( cbuf );
- }
- }
- break;
-
- case 'M':
- if( type_ctr == 1 )
- {
- sprintf( cbuf, "%d", MonthOf( Date8 ));
- strcat( buf, cbuf );
- BufPtr += strlen( cbuf );
- }
- else if( type_ctr == 2 )
- {
- cbuf[0] = Date8[4];
- cbuf[1] = Date8[5];
- cbuf[2] = 0x00;
- strcat( buf, cbuf );
- BufPtr += 2;
- }
- else
- {
- s = CharMonthOf( Date8 );
- if( type_ctr == 3 )
- {
- strncat( buf, s.getData(), 3 );
- BufPtr += 3;
- }
- else
- {
- strcpy( cbuf, CharMonthOf( Date8 ));
- for( i = 0; i < 9; i++ )
- if( cbuf[i] == 0x20 ) cbuf[i] = 0x00;
- strcat( buf, cbuf );
- BufPtr += strlen( cbuf );
- }
- }
- break;
-
- case 'Y':
- if( type_ctr == 2 )
- {
- cbuf[0] = Date8[2];
- cbuf[1] = Date8[3];
- cbuf[2] = 0x00;
- strcat( buf, cbuf );
- BufPtr += 2;
- }
- else if( type_ctr == 4 )
- {
- cbuf[0] = Date8[0];
- cbuf[1] = Date8[1];
- cbuf[2] = Date8[2];
- cbuf[3] = Date8[3];
- cbuf[4] = 0x00;
- strcat( buf, cbuf );
- BufPtr += 4;
- }
- break;
-
- default:
- break;
- }
- }
- }
- }
- fDate = buf;
- return fDate;
-}
-/***************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-/* this routine returns the Date8 format of the last day of the
- month for the given input Date8 */
-
-xbString & xbDate::LastDayOfMonth( const char * Date8 )
-{
- char tmp[9];
- sprintf( tmp, "%4.4d%2.2d%2.2d",
- YearOf( Date8 ), MonthOf( Date8 ),
- DaysInMonths[IsLeapYear(Date8)][MonthOf(Date8)]);
- cDate8 = tmp;
- return cDate8;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-xbString &xbDate::operator+=( int count )
-{
- JulToDate8( JulianDays() + count );
- return cDate8;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-xbString &xbDate::operator-=( int count )
-{
- JulToDate8( JulianDays() - count );
- return cDate8;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-xbString &xbDate::operator++( int )
-{
- *this+=1;
- return cDate8;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-xbString &xbDate::operator--( int )
-{
- *this-=1;
- return cDate8;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-xbString &xbDate::operator+( int count )
-{
- xbDate d( GetDate() );
- d+=count;
- fDate = d.GetDate();
- return fDate;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-xbString &xbDate::operator-( int count )
-{
- xbDate d( GetDate() );
- d-=count;
- fDate = d.GetDate();
- return fDate;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-long xbDate::operator-( const xbDate & d ) const
-{
- return JulianDays() - d.JulianDays();
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-int xbDate::operator==( const xbDate & d ) const
-{
- if( JulianDays() == d.JulianDays() )
- return 1;
- else
- return 0;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-int xbDate::operator!=( const xbDate & d ) const
-{
- if( JulianDays() != d.JulianDays() )
- return 1;
- else
- return 0;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-int xbDate::operator<( const xbDate & d ) const
-{
- if( JulianDays() < d.JulianDays() )
- return 1;
- else
- return 0;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-int xbDate::operator>( const xbDate & d ) const
-{
- if( JulianDays() > d.JulianDays() )
- return 1;
- else
- return 0;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-int xbDate::operator<=( const xbDate & d ) const
-{
- if( JulianDays() <= d.JulianDays() )
- return 1;
- else
- return 0;
-}
-/**********************************************************************/
-//! Short description.
-/*!
-*/
-int xbDate::operator>=( const xbDate & d ) const
-{
- if( JulianDays() >= d.JulianDays() )
- return 1;
- else
- return 0;
-}
-/**********************************************************************/
diff --git a/xbase64/xbdate.h b/xbase64/xbdate.h
deleted file mode 100755
index 617fe50..0000000
--- a/xbase64/xbdate.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/* xbdate.h
-
- Xbase64 project source code
-
- This file contains a header file for the xbDate object, which is
- used for handling dates.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-/*! \file xbdate.h
-*/
-
-#ifndef __XB_XBDATE_H__
-#define __XB_XBDATE_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbstring.h>
-
-#define XB_FMT_WEEK 1
-#define XB_FMT_MONTH 2
-#define XB_FMT_YEAR 3
-
-//! xbDate class
-/*!
-*/
-
-class XBDLLEXPORT xbDate {
- public:
- xbDate();
- xbDate( const char * Date8 );
- xbDate( const xbString &Date8 );
- virtual ~xbDate();
-
- //! Short description.
- /*!
- */
- const xbString & GetDate() const
- { return cDate8; };
- //! Short description.
- /*!
- */
- xbString & GetDate()
- { return cDate8; };
- //! Short description.
- /*!
- */
- const xbString & GetFormattedDate() const
- { return fDate; };
- //! Short description.
- /*!
- */
- xbString & GetFormattedDate()
- { return fDate; };
-
- int SetDate( const char * Date8 );
- //! Short description.
- /*!
- */
- int SetDate( const xbString & Date8 )
- { return SetDate((const char *) Date8 ); };
-
- long JulianDays ( const char *Date8 ) const;
- //! Short description.
- /*!
- */
- long JulianDays ( const xbString & Date8 ) const
- { return JulianDays((const char *) Date8 ); };
- //! Short description.
- /*!
- */
- long JulianDays () const
- { return JulianDays((const char *) cDate8 ); };
-
- int YearOf ( const char *Date8 ) const;
- //! Short description.
- /*!
- */
- int YearOf ( const xbString & Date8 ) const
- { return YearOf((const char *) Date8 ); };
- //! Short description.
- /*!
- */
- int YearOf () const
- { return YearOf((const char *) cDate8 ); };
-
- //! Short description.
- /*!
- */
- int CenturyOf ( const char *Date8 ) const;
-
- int MonthOf ( const char *Date8 ) const;
- //! Short description.
- /*!
- */
- int MonthOf ( const xbString &Date8 ) const
- { return MonthOf((const char *) Date8 ); };
- //! Short description.
- /*!
- */
- int MonthOf () const
- { return MonthOf(( const char *) cDate8 ); };
-
- int DayOf ( int Format, const char *Date8 ) const;
- //! Short description.
- /*!
- */
- int DayOf ( int Format, const xbString &Date8 ) const
- { return DayOf( Format, (const char *) Date8 ); };
- //! Short description.
- /*!
- */
- int DayOf ( int Format ) const
- { return DayOf( Format, (const char *) cDate8 ); };
-
- int IsLeapYear ( const char *Date8 ) const;
- //! Short description.
- /*!
- */
- int IsLeapYear ( const xbString &Date8 ) const
- { return IsLeapYear((const char *) Date8 ); };
- //! Short description.
- /*!
- */
- int IsLeapYear () const
- { return IsLeapYear((const char *) cDate8 ); };
-
- //! Short description.
- /*!
- */
- int CalcRollingCenturyForYear( int ) const;
-
-
- int DateIsValid ( const char *Date8 ) const;
- //! Short description.
- /*!
- */
- int DateIsValid ( const xbString & Date8 ) const
- { return DateIsValid( (const char *) Date8 ); };
-
- xbString& LastDayOfMonth( const char *Date8 );
- //! Short description.
- /*!
- */
- xbString& LastDayOfMonth( const xbString & Date8 )
- { return LastDayOfMonth((const char *) Date8 ); };
- //! Short description.
- /*!
- */
- xbString& LastDayOfMonth()
- { return LastDayOfMonth((const char *) cDate8 ); };
-
- xbString& Sysdate ();
- xbString& JulToDate8( long );
-
- //! Short description.
- /*!
- */
- xbString& FormatCTODdate( const char * indate );
-
- //! Short description.
- /*!
- */
- xbString& FormatDate( const char *Format, const char *Date8 );
- //! Short description.
- /*!
- */
- xbString& FormatDate( const xbString &Format, const char *Date8 )
- { return FormatDate((const char *) Format, Date8 ); };
- //! Short description.
- /*!
- */
- xbString& FormatDate( const char *Format, const xbString &Date8 )
- { return FormatDate( Format, (const char *) Date8 ); };
- //! Short description.
- /*!
- */
- xbString& FormatDate( const xbString &Format, const xbString &Date8 )
- { return FormatDate((const char *) Format,(const char *) Date8 ); };
- //! Short description.
- /*!
- */
- xbString& FormatDate( const char *Format )
- { return FormatDate( (const char *) Format, (const char *) cDate8 ); };
- //! Short description.
- /*!
- */
- xbString& FormatDate( const xbString &Format )
- { return FormatDate((const char *) Format, (const char *) cDate8 ); };
-
- xbString& CharDayOf ( const char *Date8 );
- //! Short description.
- /*!
- */
- xbString& CharDayOf ( const xbString &Date8 )
- { return CharDayOf((const char *) Date8 ); };
- //! Short description.
- /*!
- */
- xbString& CharDayOf ()
- { return CharDayOf((const char *) cDate8 ); };
-
- xbString& CharMonthOf ( const char *Date8 );
- //! Short description.
- /*!
- */
- xbString& CharMonthOf ( const xbString &Date8 )
- { return CharMonthOf(( const char *) Date8 ); };
- //! Short description.
- /*!
- */
- xbString& CharMonthOf ()
- { return CharMonthOf(( const char *) cDate8 ); };
-
- xbString &operator+=( int );
- xbString &operator-=( int );
- xbString &operator++( int ); /* post increment */
- xbString &operator--( int ); /* post increment */
- xbString &operator+ ( int );
- xbString &operator- ( int );
- long operator-( const xbDate & ) const;
- int operator==( const xbDate & ) const;
- int operator!=( const xbDate & ) const;
- int operator< ( const xbDate & ) const;
- int operator> ( const xbDate & ) const;
- int operator<=( const xbDate & ) const;
- int operator>=( const xbDate & ) const;
-
- protected:
- void SetDateTables();
- xbString cDate8; /* CCYYMMDD date format */
- xbString fDate; /* other date format */
- static int AggregatedDaysInMonths[2][13];
- static int DaysInMonths[2][13];
-};
-
-#endif // __XB_XBDATE_H__
-
diff --git a/xbase64/xbdbf.cpp b/xbase64/xbdbf.cpp
deleted file mode 100755
index d3790cb..0000000
--- a/xbase64/xbdbf.cpp
+++ /dev/null
@@ -1,2671 +0,0 @@
-/* xbdbf.cpp
-
- Xbase64 project source code
-
- This file contains the basic Xbase routines for reading and writing
- Xbase .DBF files.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbdbf.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-#include <errno.h>
-
-/*! \file xbdbf.cpp
-*/
-
-/************************************************************************/
-//! Constructor
-/*!
- \param x pointer to the global xbXbase class
-*/
-xbDbf::xbDbf( xbXBase * x )
-{
- xbase = x;
- InitVars();
-}
-/************************************************************************/
-//! Destructor
-/*!
-*/
-xbDbf::~xbDbf()
-{
- CloseDatabase(true);
-}
-/************************************************************************/
-//! Initialize private data members.
-/*!
- Internal use only.
-*/
-void xbDbf::InitVars()
-{
- SetFileName(NULL);
- NoOfFields = 0;
- DbfStatus = XB_CLOSED;
- fp = NULL;
- CurRec = 0L;
- SchemaPtr = NULL;
- RecBuf = NULL;
- RecBuf2 = NULL;
- Version = 0x00;
- UpdateYY = 0x00;
- UpdateMM = 0x00;
- UpdateDD = 0x00;
- NoOfRecs = 0L;
- HeaderLen = 0x00;
- RecordLen = 0x00;
- NdxList = NULL;
- FreeIxList = NULL;
- XFV = 3; /* Xbase file version */
-
-#ifdef XB_LOCKING_ON
- xblfh = NULL; /* lock file for XB_XBASE_LOCK_MODE */
- LockMode = xbase->GetLockMode();
- TableLockCnt = 0;
- IndexLockCnt = 0;
-#ifdef XB_MEMO_FIELDS
- MemoLockCnt = 0;
-#endif
-
- AutoLock = 1;
- CurLockType = -1;
- CurLockCount = 0;
- CurLockedRecNo = 0L;
- CurRecLockType = -1;
- CurRecLockCount = 0;
- CurMemoLockType = -1;
- CurMemoLockCount = 0;
-#else
- AutoLock = 0;
-#endif
-
-#ifdef XB_MEMO_FIELDS
- MemofileName = "";
- MemoHeader.BlockSize = XB_DBT_BLOCK_SIZE;
- MemoHeader.Version = 0x03;
- mfp = NULL;
- mbb = NULL;
- CurMemoBlockNo = -1;
- mfield1 = 0;
- MStartPos = 0;
- MFieldLen = 0;
- NextFreeBlock = 0L;
- FreeBlockCnt = 0L;
- MNextBlockNo = 0L;
- MNoOfFreeBlocks = 0L;
-#endif
-
-//#ifdef XB_REAL_DELETE
- RealDelete = 0;
- FirstFreeRec = 0L;
- RealNumRecs = 0L;
-//#endif
-}
-/************************************************************************/
-//! Set dbase version for the dbf file.
-/*!
- Set dbase version. Should only be used before creating a database with
- xbDbf::CreateDatabase().
-
- \param v version, either 3 or 4.
-*/
-xbShort xbDbf::SetVersion(xbShort v) {
- if (v == 0)
- return XFV;
- else
- if(v == 3) {
- XFV = 3;
-#ifdef XB_MEMO_FIELDS
- MemoHeader.Version = 0x03;
-#endif
- return XFV;
- } else
- if (v == 4) {
- XFV = 4;
-#ifdef XB_MEMO_FIELDS
- MemoHeader.Version = 0x00;
-#endif
- return XFV;
- }
-
- return XB_INVALID_OPTION;
-}
-/************************************************************************/
-//! Write the dbf header
-/*!
- Internal use only.
-
- \param PositionOption flag that indicates whether file postition should
- be moved. non-zero if so, zero if not.
-*/
-xbShort xbDbf::WriteHeader( xbShort PositionOption )
-{
- char buf[32];
- memset(buf, 0, 32);
- if(PositionOption)
- rewind(fp);
-
- memcpy(&buf[0], &Version, 4);
- xbase->PutLong(&buf[4], NoOfRecs);
- xbase->PutShort(&buf[8], HeaderLen );
- xbase->PutShort(&buf[10], RecordLen );
-
-#ifdef XB_REAL_DELETE
- if(RealDelete){
- xbase->PutULong(&buf[12], FirstFreeRec);
- xbase->PutULong(&buf[16], RealNumRecs);
- }
-#endif
- if(fwrite(buf, 32, 1, fp) != 1)
- return XB_WRITE_ERROR;
-
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Read the dbf header.
-/*!
- Internal use only.
-
- \param PositionOption
-*/
-xbShort xbDbf::ReadHeader( xbShort PositionOption )
-{
-#if 0
- char buf[4];
- if (PositionOption)
- rewind(fp);
- if (fread(&Version, 4, 1, fp) != 1)
- xb_error(XB_READ_ERROR);
-
- if (fread(buf, 4, 1, fp ) != 1)
- xb_error(XB_READ_ERROR);
-
- NoOfRecs = xbase->GetLong( buf );
- if(fread(buf, 2, 1, fp) != 1)
- xb_error(XB_READ_ERROR);
-
- HeaderLen = xbase->GetShort( buf );
- if(fread(buf, 2, 1, fp) != 1)
- xb_error(XB_READ_ERROR);
-
- RecordLen = xbase->GetShort(buf);
-
-#ifdef XB_REAL_DELETE
- if(RealDelete)
- {
- if (fread(buf, 4, 1, fp ) != 1)
- xb_error(XB_READ_ERROR);
- FirstFreeRec = xbase->GetULong( buf );
-
- if (fread(buf, 4, 1, fp ) != 1)
- xb_error(XB_READ_ERROR);
- RealNumRecs = xbase->GetULong( buf );
- }
-#endif
-#else
- char buf[32];
-
- if(PositionOption)
- rewind(fp);
-
- if(fread(buf, 32, 1, fp) != 1)
- return XB_READ_ERROR;
-
- memcpy(&Version, buf, 4);
- NoOfRecs = xbase->GetLong(&buf[4]);
- HeaderLen = xbase->GetShort(&buf[8]);
- RecordLen = xbase->GetShort(&buf[10]);
-
-#ifdef XB_REAL_DELETE
- if(RealDelete)
- {
- FirstFreeRec = xbase->GetULong(&buf[12]);
- RealNumRecs = xbase->GetULong(&buf[16]);
- }
-#endif
-#endif
-
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Determine if file name suffix is missing
-/*!
- Internal use only.
-*/
-xbShort xbDbf::NameSuffixMissing( xbShort type, const char * name )
-{
- /* type 1 is DBF check
- type 2 is NDX check
- type 3 is MDX check
- type 4 is NTX check
-
- Returns 0 if suffix found
- 1 if suffix not found, lower case
- 2 is suffix not found, upper, case
-*/
-
- xbShort len;
-
- len = strlen( name );
- if( len <= 4 )
- if( name[len-1] >= 'A' && name[len-1] <= 'Z' )
- return 2;
- else
- return 1;
-
- if( type == 1 && name[len-4] == '.' &&
- ( name[len-3] == 'd' || name[len-3] == 'D' ) &&
- ( name[len-2] == 'b' || name[len-2] == 'B' ) &&
- ( name[len-1] == 'f' || name[len-1] == 'F' )
- )
- return 0;
-
- if( type == 2 && name[len-4] == '.' &&
- ( name[len-3] == 'n' || name[len-3] == 'N' ) &&
- ( name[len-2] == 'd' || name[len-2] == 'D' ) &&
- ( name[len-1] == 'x' || name[len-1] == 'X' )
- )
- return 0;
-
- if( type == 4 && name[len-4] == '.' &&
- ( name[len-3] == 'n' || name[len-3] == 'N' ) &&
- ( name[len-2] == 't' || name[len-2] == 'T' ) &&
- ( name[len-1] == 'x' || name[len-1] == 'X' )
- )
- return 0;
-
- if( name[len-5] >= 'A' && name[len-5] <= 'Z' )
- return 2;
- else
- return 1;
-}
-/************************************************************************/
-//! Create the dbf file.
-/*!
- This method attempts to create the DBF file with the specified
- name (TableName) and schema (xbSchema s). The OverLay switch is used to determine
- if an existing file should be overwritten or an error flagged if the
- file already exists. The record buffer is blanked (set to spaces).
-
- \param TableName name of the table
- \param s xbSchema
- \param Overlay One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>OverLay</th><th>Description</th></tr>
- <tr><td>XB_OVERLAY</td><td>Overwrite existing file if it exists</td></tr>
- <tr><td>XB_DONTOVERLAY</td><td>Report an error if file exists</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{OverLay} & \textbf{Description} \\ \hline \hline
- XB\_OVERLAY & Overwrite existing file if it exists \\ \hline
- XB\_DONTOVERLAY & Report an error if file exists \\ \hline
- \end{tabular}
- \endlatexonly
- \returns One of the following return codes:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_FILE_EXISTS</td><td>If the file exists and OverLay is XB_DONTOVERLAY</td></tr>
- <tr><td>XB_OPEN_ERROR</td><td>Couldn't open the file</td></tr> <tr><td>XB_NO_MEMORY</td><td>Memory allocation error</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Couldn't write to disk</td><tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No Error \\ \hline
- XB\_FILE\_EXISTS & If the file exists and OverLay is XB\_DONTOVERAY \\ \hline
- XB\_OPEN\_ERROR & Couldn't open the file \\ \hline
- XB\_WRITE\_ERROR & Couldn't write to disk \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::CreateDatabase( const char * TableName, xbSchema * s,
- const xbShort Overlay )
-{
- xbShort i, j, k, k2, rc; /* , count; */
-
-#ifdef XB_MEMO_FIELDS
- xbShort MemoSw = 0;
-#endif
-
- DbfStatus = XB_CLOSED;
- SetFileName( TableName );
-
- /* check if the file already exists */
- if((( fp = fopen( GetFileName(), "r" )) != NULL ) && !Overlay ){
- fclose( fp );
- return XB_FILE_EXISTS;
- }
- else if( fp ) fclose( fp );
-
- if(( fp = fopen( GetFileName(), "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-
-#ifdef XB_LOCKING_ON
- /* no buffering in multi user mode */
- setbuf( fp, NULL );
-
- /* open the lock file if XB_XBASE_LOCK_FLAVOR */
-// if( LockMode == XB_XBASE_LOCK_MODE )
-// if(( rc = OpenXbLockFile()) != XB_NO_ERROR )
-// return rc;
-#endif
-
- /* count the number of fields and check paramaters */
- i = 0;
- while( s[i].Type != 0 ){
- NoOfFields++;
-
-#ifdef XB_MEMO_FIELDS
- if(s[i].Type == 'M'){
- s[i].FieldLen = 10;
- s[i].NoOfDecs = 0;
- }
-#endif /* XB_MEMO_FIELDS */
-
- if(s[i].Type == 'D'){
- s[i].FieldLen = 8;
- s[i].NoOfDecs = 0;
- }
-
- if(s[i].Type == 'C')
- s[i].NoOfDecs = 0;
-
- RecordLen += s[i].FieldLen;
-
- if( s[i].Type != 'C' &&
- s[i].Type != 'N' &&
- s[i].Type != 'F' &&
- s[i].Type != 'D' &&
-#ifdef XB_MEMO_FIELDS
- s[i].Type != 'M' &&
-#endif /* XB_MEMO_FIELDS */
- s[i].Type != 'L' )
- {
- fclose( fp );
- InitVars();
- return XB_UNKNOWN_FIELD_TYPE;
- }
-
-#ifdef XB_MEMO_FIELDS
-// 8/18/03 types B and O dont exist yet - gkunkel
-// if( !MemoSw && ( s[i].Type=='M' || s[i].Type=='B' || s[i].Type=='O'))
- if( !MemoSw && ( s[i].Type=='M' ))
- MemoSw++;
-#endif
-
-// check for numeric fields which are too long
- if((s[i].Type == 'N' || s[i].Type == 'F') && s[i].FieldLen > 19 ){
- fclose( fp );
- InitVars();
- return XB_INVALID_FIELD_LEN;
- }
- i++;
- }
- RecordLen++; /* add one byte for 0x0D */
-
- if(( RecBuf = (char *) malloc( RecordLen )) == NULL ){
- fclose( fp );
- InitVars();
- return XB_NO_MEMORY;
- }
-
- if(( RecBuf2 = (char *) malloc( RecordLen )) == NULL ){
- free( RecBuf );
- fclose( fp );
- InitVars();
- return XB_NO_MEMORY;
- }
-
- /* BlankRecord(); */
- memset( RecBuf, 0x20, RecordLen );
- memset( RecBuf2, 0x20, RecordLen );
-
- /* set class variables */
- Version = XFV & 0x7; // file version - bit 0-2
-#ifdef XB_MEMO_FIELDS
- if(MemoSw){
- if((XFV & 0x7) == 3)
- Version |= 0x80; // memo presence - bit 7
- else
- Version = (char) 0x8b;
- }
-#endif
-
- CurRec = 0L;
- HeaderLen = 33 + NoOfFields * 32;
- xbDate d;
- UpdateYY = (d.YearOf() - 1900);
- if((XFV & 0x7) == 3)
- UpdateYY %= 100; // dBASE III seems to do this, but IV does not. DTB
-
- UpdateMM = d.MonthOf();
- UpdateDD = d.DayOf( XB_FMT_MONTH );
-
- /* write the header prolog */
- if(( rc = WriteHeader( 0 )) != XB_NO_ERROR ){
- free( RecBuf );
- free( RecBuf2 );
- fclose( fp );
- InitVars();
- return XB_WRITE_ERROR;
- }
-
- if((SchemaPtr=(xbSchemaRec *)malloc(NoOfFields*sizeof(xbSchemaRec)))==NULL){
- free( RecBuf );
- free( RecBuf2 );
- fclose( fp );
- InitVars();
- return XB_NO_MEMORY;
- }
- memset( SchemaPtr, 0x00, ( NoOfFields * sizeof(xbSchemaRec)));
-
- /* write the field information into the header */
- for( i = 0, k = 1; i < NoOfFields; i++ ){
- memset( SchemaPtr[i].FieldName, 0x00, 11 );
- strncpy( SchemaPtr[i].FieldName, s[i].FieldName, 10 );
-
- SchemaPtr[i].Type = s[i].Type;
- SchemaPtr[i].FieldLen = s[i].FieldLen;
- SchemaPtr[i].NoOfDecs = s[i].NoOfDecs;
-
- if( SchemaPtr[i].NoOfDecs > SchemaPtr[i].FieldLen ) {
- fclose( fp );
- free( SchemaPtr );
- free( RecBuf );
- free( RecBuf2 );
- InitVars();
- return XB_INVALID_SCHEMA;
- }
-
- k2 = k;
- k += SchemaPtr[i].FieldLen;
-
- if(( fwrite( &SchemaPtr[i], 1, 18, fp )) != 18 ) {
- fclose( fp );
- free( SchemaPtr );
- free( RecBuf );
- free( RecBuf2 );
- InitVars();
- return XB_WRITE_ERROR;
- }
-
- for( j = 0; j < 14; j++ ) {
- if(( fwrite( "\x00", 1, 1, fp )) != 1 ) {
- free( SchemaPtr );
- free( RecBuf );
- free( RecBuf2 );
- fclose( fp );
- InitVars();
- return XB_WRITE_ERROR;
- }
- }
- SchemaPtr[i].Address = RecBuf + k2;
- SchemaPtr[i].Address2 = RecBuf2 + k2;
- }
-
- /* write the header terminator */
- if(( fputc( XB_CHARHDR, fp )) != XB_CHARHDR ){
- fclose( fp );
- free( SchemaPtr );
- free( RecBuf );
- free( RecBuf2 );
- InitVars();
- return XB_WRITE_ERROR;
- }
-
-#ifdef XB_MEMO_FIELDS
- if( MemoSw )
- if((rc = CreateMemoFile()) != XB_NO_ERROR){
- fclose(fp);
- free(RecBuf);
- free(RecBuf2);
- InitVars();
- return rc;
- }
-#endif
-
- DbfStatus = XB_OPEN;
- return xbase->AddDbfToDbfList(this, GetFileName());
-}
-/************************************************************************/
-//! Close the dbf file.
-/*!
- This method attempts to close the DBF file which was previously
- opened with either CreateDatabase() or OpenDatabase(). Deletes any
- memory allocated. Automatically closes any open indexes associated
- with this data file.
-
- \param deleteIndexes if TRUE, the indexes (xbIndex instances) will also
- be deleted (index files will not be deleted)
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File was not open</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No Error \\ \hline
- XB\_NOT\_OPEN\_ERROR & File was not open \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::CloseDatabase( xbBool deleteIndexes )
-{
-#if defined(XB_INDEX_ANY)
- xbIxList *i, *ti;
-#endif
-
- if(DbfStatus == XB_CLOSED)
- return XB_NO_ERROR;
-
-
-#if defined(XB_INDEX_ANY)
- i = NdxList;
- while (i){
- i->index->CloseIndex();
- if(deleteIndexes)
- delete i->index;
- i = NdxList;
- }
-/* free up unused nodes */
- i = FreeIxList;
- while( i ) {
- ti = i;
- i = i->NextIx;
- free(ti);
- }
-#endif
-
- if(SchemaPtr){
- for( int j = 0; j < NoOfFields; j++ )
- if( SchemaPtr[j].fp ) delete SchemaPtr[j].fp;
- free( SchemaPtr );
- }
- if(RecBuf)
- free( RecBuf );
- if(RecBuf2)
- free( RecBuf2 );
-
-#ifdef XB_MEMO_FIELDS
- if( mbb )
- free( mbb ); /* memo block buffer */
- if( mfp )
- fclose( mfp ); /* memo file pointer */
-#endif
-
-#ifdef XB_LOCKING_ON
- if( xblfh ){
- fclose( xblfh );
- xblfh = NULL;
- }
-#endif
-
- xbase->RemoveDbfFromDbfList( this );
- if(fp)
- fclose( fp );
- InitVars();
- return XB_NO_ERROR;
-}
-/************************************************************************/
-/* options 1 = Print header only
- 2 = Field data only
- 3 = Header and Field data */
-
-//! Dump header information.
-/*!
- \param Option One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Option</th><th>Description</th></tr>
- <tr><td>1</td><td>Print header only</td></tr>
- <tr><td>2</td><td>Field data only</td></tr>
- <tr><td>3</td><td>Header and field data</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Option} & \textbf{Description} \\ \hline \hline
- 1 & Header only \\ \hline
- 2 & Field data only \\ \hline
- 3 & Header and field data \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-#ifdef XBASE_DEBUG
-xbShort xbDbf::DumpHeader( xbShort Option )
-{
- int i;
-
- if( Option < 1 || Option > 3 )
- return XB_INVALID_OPTION;
-
- if( DbfStatus == XB_CLOSED )
- return XB_NOT_OPEN;
-
- std::cout << "\nDatabase file " << GetFileName() << std::endl << std::endl;
-
- if( Option != 2 ){
- std::cout << "File header data:" << std::endl;
- if( Version == 3 )
- std::cout << "Dbase III file" << std::endl;
- else if ( Version == 83 )
- std::cout << "Dbase III file with memo fields" << std::endl << std::endl;
-
- std::cout << "Last update date = "
- << (int) UpdateMM << "/" << (int) UpdateDD << "/" << (int) UpdateYY % 100 << std::endl;
-
- std::cout << "Header length = " << HeaderLen << std::endl;
- std::cout << "Record length = " << RecordLen << std::endl;
- std::cout << "Records in file = " << NoOfRecs << std::endl << std::endl;
-#ifdef XB_REAL_DELETE
- std::cout << "First Free Rec = " << FirstFreeRec << std::endl << std::endl;
-#endif
- }
- if( Option != 1 ){
- std::cout << "Field Name Type Length Decimals" << std::endl;
- std::cout << "---------- ---- ------ --------" << std::endl;
- for( i = 0; i <NoOfFields; i++ ){
- if( SchemaPtr[i].Type == 'C' && SchemaPtr[i].NoOfDecs > 0 )
- printf( "%10s %1c %4d %4d\n", SchemaPtr[i].FieldName,
- SchemaPtr[i].Type, SchemaPtr[i].FieldLen, 0 );
- else
- printf( "%10s %1c %4d %4d\n", SchemaPtr[i].FieldName,
- SchemaPtr[i].Type, SchemaPtr[i].FieldLen, SchemaPtr[i].NoOfDecs );
- }
- }
- std::cout << std::endl;
- return XB_NO_ERROR;
-}
-#endif
-/************************************************************************/
-//! Open the DBF file.
-/*!
- This method attempts to open the DBF file with the specified
- name (TableName). This method does not position to any particular
- record in the file. The record buffer is blanked (set to spaces).
-
- \param TableName Name of table to open
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_OPEN_ERROR</td><td>Couldn't open file</td></tr>
- <tr><td>XB_NO_MEMORY</td><td>Memory allocation error</td></tr>
- <tr><td>XB_NOT_XBASE</td><td>Not an DBF file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_OPEN\_ERROR & Couldn't open file \\ \hline
- XB\_NO\_MEMORY & Memory allocation error \\ \hline
- XB\_NOT\_XBASE & Not an DBF file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::OpenDatabase( const char * TableName )
-{
- xbShort i, j, rc;
- char buf[33];
- char *p;
-
-#ifdef XB_MEMO_FIELDS
- xbShort MemoSw = 0;
-#endif
-
- /* verify the file is not already open */
- if( DbfStatus != XB_CLOSED )
- return XB_ALREADY_OPEN;
-
- /* copy the file name to the class variable */
- SetFileName( TableName );
-
- /* open the file */
- if(( fp = fopen(GetFileName(), "r+b")) == NULL ){
- //
- // Try to open read only if failed to open read/write
- //
- if(( fp = fopen(GetFileName(), "rb")) == NULL )
- return XB_OPEN_ERROR;
- }
-
-#ifdef XB_LOCKING_ON
- /* no buffering in multi user mode - may not see what others have updated */
- setbuf( fp, NULL );
-
- /* open the lock file if XB_XBASE_LOCK_MODE */
-// if( LockMode == XB_XBASE_LOCK_MODE )
-// if(( rc = OpenXbLockFile()) != XB_NO_ERROR )
-// return rc;
-#endif
-
-#ifdef XB_LOCKING_ON
-// if( AutoLock )
-// if(( rc = LockDatabase( XB_LOCK, 0L )) != XB_NO_ERROR)
-// return rc;
-#endif
-
- /* copy the header into memory */
- if(( rc = ReadHeader( 1 )) != XB_NO_ERROR ){
- InitVars();
- return rc;
- }
-
- /* check the version */
- if( Version == 3 || Version == (char)0x83 ){ /* dBASE III+ */
- XFV = 3;
-#ifdef XB_MEMO_FIELDS
- MemoHeader.Version = 0x03;
-#endif
- }
- else if( Version == 4 || Version == (char)0x8B ){ /* dBASE IV */
- XFV = 4;
-#ifdef XB_MEMO_FIELDS
- MemoHeader.Version = 0x00;
-#endif
- }
- else if( Version == (char)0xf5 ){ /* FoxPro */
- XFV = 4;
-#ifdef XB_MEMO_FIELDS
- MemoHeader.Version = 0x00;
-#endif
- }
- else if( Version == (char)0x30 ){ /* Visual Foxpro */
- XFV = 4;
-#ifdef XB_MEMO_FIELDS
- MemoHeader.Version = 0x00;
-#endif
- } else {
- InitVars();
- return XB_NOT_XBASE;
- }
-
- // it would seem that dBASE III+ generates an UpdateYY value
- // of 0 for 2000 and dBASE IV uses 100, so I have removed the
- // check for UpdateYY being 0 (which might be valid). DTB
-
- // Not all flavors of database tools use these fields
- // Found a month set to 0 in valid dbf file
- // Commented out this check 2/11/06 - GAK
-
- // if( UpdateMM == 0 || UpdateDD == 0 ){
- // InitVars();
- // return XB_NOT_XBASE;
- // }
-
- /* calculate the number of fields */
- if( Version == (char)0x30 ) {
- NoOfFields = ( HeaderLen - 296 ) / 32 ;
- } else {
- NoOfFields = ( HeaderLen - 33 ) / 32;
- }
-
- if(( RecBuf = (char *) malloc( RecordLen )) == NULL ) {
- fclose( fp );
- InitVars();
- return XB_NO_MEMORY;
- }
- if(( RecBuf2 = (char *) malloc( RecordLen )) == NULL ) {
- fclose( fp );
- free( RecBuf );
- InitVars();
- return XB_NO_MEMORY;
- }
-
- if((SchemaPtr=(xbSchemaRec *)malloc(NoOfFields*sizeof(xbSchemaRec)))==NULL){
- free( RecBuf );
- free( RecBuf2 );
- fclose( fp );
- InitVars();
- return XB_NO_MEMORY;
- }
- memset( SchemaPtr, 0x00, ( NoOfFields * sizeof(xbSchemaRec)));
-
- /* copy field info into memory */
- for( i = 0, j = 1; i < NoOfFields; i++ ){
- _fseek( fp,((xbOffT)i*32+32), 0 );
- fread( &buf, 1, 32, fp );
- p = buf;
- strncpy( SchemaPtr[i].FieldName, p, 10 );
- p += 11;
- SchemaPtr[i].Type = *p++;
-
- SchemaPtr[i].Address = RecBuf + j;
- SchemaPtr[i].Address2 = RecBuf2 + j;
-
- SchemaPtr[i].FieldLen = *( p + 4 );
- SchemaPtr[i].NoOfDecs = *( p + 5 );
-
- if( SchemaPtr[i].Type == 'C' && SchemaPtr[i].NoOfDecs > 0 ){
- SchemaPtr[i].LongFieldLen = xbase->GetShort( p + 4 );
- j += SchemaPtr[i].LongFieldLen;
- }
- else
- j += SchemaPtr[i].FieldLen;
-#ifdef XB_MEMO_FIELDS
- if( !MemoSw && (SchemaPtr[i].Type == 'M' ||
- SchemaPtr[i].Type == 'B' || SchemaPtr[i].Type == 'O' ))
- MemoSw++;
-#endif
- }
- CurRec = 0L;
- BlankRecord();
- DbfStatus = XB_OPEN;
-
-#ifdef XB_MEMO_FIELDS
- if( MemoSw ) /* does this table have memo fields ? */
- if(( rc = OpenMemoFile()) != XB_NO_ERROR ){
- free( RecBuf );
- free( RecBuf2 );
- free( SchemaPtr );
- fclose( fp );
- InitVars();
- return rc;
- }
-#endif
-
-#ifdef XB_LOCKING_ON
-// if( AutoLock )
-// LockDatabase( XB_UNLOCK, 0L );
-#endif /* XB_LOCKING_ON */
-
- return xbase->AddDbfToDbfList( this, GetFileName() );
-}
-/************************************************************************/
-//! Blank the record buffer.
-/*!
- Sets the record to spaces.
-*/
-xbShort xbDbf::BlankRecord()
-{
- if( DbfStatus == XB_CLOSED )
- return XB_NOT_OPEN;
-
- if( DbfStatus != XB_UPDATED ){
- DbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, RecordLen );
- }
-
- memset( RecBuf, 0x20, RecordLen );
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Append the current record to the data file
-/*!
- This method attempts to append the contents of the current record buffer
- to the end of the DBF file and updates the file date and number of
- records in the file. Also updates any open indices associated with
- this data file.
-
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::AppendRecord()
-{
- xbShort rc;
- xbULong nextRecNo;
-
-#if defined(XB_INDEX_ANY)
- xbIxList *i;
-#endif
-
-/* lock the database */
-#ifdef XB_LOCKING_ON
-// if( AutoLock )
-// if(( rc = LockDatabase( XB_LOCK, 0L )) != XB_NO_ERROR)
-// return rc;
-
- rc = ReadHeader(1);
-
-// if(AutoLock)
-// LockDatabase( XB_UNLOCK, 0L );
-
- if( rc )
- return rc;
-
-#endif
-
-/* lock any indexes */
-#if defined(XB_INDEX_ANY)
-#ifdef XB_LOCKING_ON
- i = NdxList;
- while( i && AutoLock ){
-// if(( rc = i->index->LockIndex( XB_LOCK )) != XB_NO_ERROR )
-// return rc;
- i = i->NextIx;
- }
-#endif /* XB_LOCKING_ON */
-#endif
-
-// if there are no duplicates, and no records set the CurRec to the
-// last record + 1. This is for EXP::RECNO()
-
-/* check for any duplicate keys */
-#if defined(XB_INDEX_ANY)
- i = NdxList;
- while( i ){
- if( i->index->UniqueIndex() ){
- i->index->CreateKey( 0, 0 );
- if( i->index->FindKey() == XB_FOUND )
- return XB_KEY_NOT_UNIQUE;
- }
- i = i->NextIx;
- }
-#endif
-
-#ifdef XB_REAL_DELETE
- if(RealDelete && FirstFreeRec)
- nextRecNo = FirstFreeRec;
- else
- nextRecNo = NoOfRecs + 1;
-#else
- nextRecNo = NoOfRecs + 1;
-#endif
-
- CurRec = NoOfRecs + 1;
-
-#if defined(XB_INDEX_ANY)
-/* update the indexes */
- i = NdxList;
- while( i ){
- if( !i->index->UniqueIndex() ) /* if we didn't prepare the key */
- if(( rc = i->index->CreateKey( 0, 0 )) != XB_NO_ERROR ) /* then do it before the add */
- return rc;
- if(( rc = i->index->AddKey(nextRecNo)) != XB_NO_ERROR )
- return rc;
- i->index->TouchIndex();
- i = i->NextIx;
- }
-#endif /* XB_INDEX_ANY */
-
-#ifdef XB_REAL_DELETE
- char buf[4];
-
- if(RealDelete && FirstFreeRec){
- /*
- ** Grab the next free rec no and put it in FirstFreeRec
- */
- if(_fseek(fp, (HeaderLen+(((xbOffT)FirstFreeRec-1)*RecordLen)+1), 0) != 0)
- return XB_SEEK_ERROR;
-
- if(fread(buf, 4, 1, fp) != 1)
- return XB_READ_ERROR;
-
- FirstFreeRec = xbase->GetULong(buf);
- }
-
- /*
- ** Okay, seek and write the record out
- */
- if(_fseek(fp, (HeaderLen+(((xbOffT)nextRecNo-1)*RecordLen)), 0) != 0)
- return XB_SEEK_ERROR;
-
- if(fwrite( RecBuf, RecordLen, 1, fp) != 1)
- return XB_WRITE_ERROR;
-
- /*
- ** If we just appended the record to the file, then write the EOF char
- */
- if(nextRecNo == NoOfRecs + 1){
- if( fputc( XB_CHAREOF, fp ) != XB_CHAREOF )
- return XB_WRITE_ERROR;
- }
-#else
- /* write the last record */
- if( _fseek( fp,(HeaderLen+((xbOffT)NoOfRecs*RecordLen)), 0 ) != 0 )
- return XB_SEEK_ERROR;
-
- if( fwrite( RecBuf, RecordLen, 1, fp ) != 1 )
- return XB_WRITE_ERROR;
-
- /* write the end of file marker */
- if( fputc( XB_CHAREOF, fp ) != XB_CHAREOF )
- return XB_WRITE_ERROR;
-#endif
-
- /* calculate the latest header information */
- xbDate d;
- UpdateYY = d.YearOf() - 1900;
- if(XFV == 3)
- UpdateYY %= 100; // dBASE III seems to do this, IV does not. DTB
- UpdateMM = d.MonthOf();
- UpdateDD = d.DayOf( XB_FMT_MONTH );
-#ifndef XB_REAL_DELETE
- NoOfRecs++;
-#else
- if(RealDelete){
- if(nextRecNo == NoOfRecs + 1)
- NoOfRecs++;
- RealNumRecs++;
- }
- else
- NoOfRecs++;
-#endif
- CurRec = nextRecNo;
-
- /* rewrite the header record */
- if(( rc = WriteHeader( 1 )) != XB_NO_ERROR )
- return rc;
-
-#ifdef XB_LOCKING_ON
-// if( AutoLock )
-// LockDatabase( XB_UNLOCK, 0L );
-
-#if defined(XB_INDEX_ANY)
- i = NdxList;
- while( i && AutoLock ){
-// i->index->LockIndex( XB_UNLOCK );
- i = i->NextIx;
- }
-#endif /* XB_INDEX_ANY */
-#endif /* XB_LOCKING_ON */
-
- DbfStatus = XB_OPEN;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Get a record from the data file
-/*!
- This method attempts to retrieve the record specified by RecNo from the
- data file into the record buffer.
-
- \param RecNo Record number to retrieve
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_NOT\_OPEN & File is not open \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::GetRecord( xbULong RecNo )
-{
- xbShort rc;
- if( DbfStatus == XB_CLOSED )
- return XB_NOT_OPEN;
-
-#ifdef XB_LOCKING_ON
-// if( AutoLock )
-// if(( rc = LockDatabase( XB_LOCK, RecNo )) != 0 ) return rc;
-
- rc = ReadHeader(1);
-
-// if(AutoLock)
-// LockDatabase( XB_UNLOCK, RecNo );
-
- if( rc )
- return rc;
-
-#endif
-
- if( RecNo > NoOfRecs || RecNo == 0L )
- return XB_INVALID_RECORD;
-
- if( _fseek( fp, (HeaderLen+(((xbOffT)RecNo-1L)*RecordLen)), SEEK_SET )){
-#ifdef XB_LOCKING_ON
-// LockDatabase( XB_UNLOCK, RecNo );
-#endif
- return XB_SEEK_ERROR;
- }
-
- if( fread( RecBuf, RecordLen, 1, fp ) != 1 ){
-#ifdef XB_LOCKING_ON
-// LockDatabase( XB_UNLOCK, RecNo );
-#endif
- return XB_READ_ERROR;
- }
-
-#ifdef XB_LOCKING_ON
-// if( AutoLock )
-// LockDatabase( XB_LOCK, RecNo );
-#endif
-
- DbfStatus = XB_OPEN;
- CurRec = RecNo;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Get the first physical record in the data file
-/*!
- Attempts to retrieve the first physical record from the data file into
- the record buffer.
-
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_NOT\_OPEN & File is not open \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- XB\_SEEK\_ERROR & Error seeking file \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::GetFirstRecord()
-{
- xbShort rc;
- if( NoOfRecs == 0 )
- return XB_INVALID_RECORD;
-
- rc = GetRecord( 1L );
-#ifdef XB_REAL_DELETE
- if(!rc && RealDelete && RecordDeleted())
- rc = GetNextRecord();
-#endif
-
- return rc;
-}
-/************************************************************************/
-//! Get the last phyiscal record in the data file
-/*!
- Attempts to retrieve the last physical record from the data file into
- the record buffer.
-
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_EOF</td><td>At end of file</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_EOF & At end of file \\ \hline
- XB\_NOT\_OPEN & File is not open \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- XB\_SEEK\_ERROR & Error seeking file \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::GetLastRecord()
-{
- xbShort rc;
- if( NoOfRecs == 0 )
- return XB_INVALID_RECORD;
-
- rc = GetRecord( NoOfRecs );
-#ifdef XB_REAL_DELETE
- if(!rc && RealDelete && RecordDeleted())
- rc = GetPrevRecord();
-#endif
-
- return rc;
-}
-/************************************************************************/
-//! Get the next physical record in the data file
-/*!
- Attempts to retrieve the next physical record from the data file into
- the record buffer.
-
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_EOF</td><td>At end of file</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_EOF & At end of file \\ \hline
- XB\_NOT\_OPEN & File is not open \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- XB\_SEEK\_ERROR & Error seeking file \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::GetNextRecord()
-{
- xbShort rc;
- if( NoOfRecs == 0 )
- return XB_INVALID_RECORD;
- else if( CurRec >= NoOfRecs )
- return XB_EOF;
-
- rc = GetRecord( ++CurRec );
-
-#ifdef XB_REAL_DELETE
- while(!rc && RealDelete && RecordDeleted())
- rc = GetRecord(++CurRec);
-#endif
-
- return rc;
-}
-/************************************************************************/
-//! Get the previous physical record in the data file
-/*!
- Attempts to retrieve the previous physical record from the data file into
- the record buffer.
-
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_BOF</td><td>At beginning of file</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_BOF & At beginning of file \\ \hline
- XB\_NOT\_OPEN & File is not open \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- XB\_SEEK\_ERROR & Error seeking file \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::GetPrevRecord()
-{
- xbShort rc;
- if( NoOfRecs == 0 )
- return XB_INVALID_RECORD;
- else if( CurRec <= 1L )
- return XB_EOF;
-
- rc = GetRecord( --CurRec );
-
-#ifdef XB_REAL_DELETE
- while(!rc && RealDelete && RecordDeleted())
- rc = GetRecord(--CurRec);
-#endif
-
- return rc;
-}
-/************************************************************************/
-//! Dump record
-/*!
- Dump the contents of the specified record to stdout.
-
- \param RecNo Record number of record to be dumped.
- \returns An error code (same as GetRecord()).
-*/
-xbShort xbDbf::DumpRecord( xbULong RecNo )
-{
- int i, rc;
- char buf[4096];
-
- if( RecNo == 0 || RecNo > NoOfRecs )
- return XB_INVALID_RECORD;
-
- rc = GetRecord( RecNo );
- if( rc != XB_NO_ERROR )
- return rc;
-
- std::cout << "\nREC NUMBER " << RecNo << "\n";
-
- if( RecordDeleted() )
- std::cout << "\nRecord deleted...\n";
-
- for( i = 0; i < NoOfFields; i++ ){
-#ifdef XB_MEMO_FIELDS
- if(SchemaPtr[i].Type == 'M'){
- if( MemoFieldExists( i )){
- std::cout << SchemaPtr[i].Type << " " << SchemaPtr[i].FieldName
- << " len = " << GetMemoFieldLen( i ) << std::endl;
- memset( buf, 0x00, 4095 );
- rc = GetMemoField(i, 4095, buf, 0);
- if(rc != XB_NO_ERROR)
- return rc;
- } else {
- buf[0] = 0x00;
- }
- }
- else
- GetField( i, buf );
- std::cout << SchemaPtr[i].Type << " " << SchemaPtr[i].FieldName << " = '" << buf << "'\n";
-#else
- GetField( i, buf );
- std::cout << SchemaPtr[i].FieldName << " = '" << buf << "'\n";
-#endif
- }
- std::cout << std::endl;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Write the current record buffer to the current record in the data file.
-/*!
- Attempts to write the contents of the record buffer to the current
- record in the data file. Updates any open indexes.
-
- \sa PutRecord(xbULong RecNo)
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_NOT\_OPEN & File is not open \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- XB\_SEEK\_ERROR & Error seeking file \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-
-/************************************************************************/
-xbShort xbDbf::PutRecord() {
- return PutRecord(CurRec);
-}
-
-//! Write the current record buffer to the specified record in the data file.
-/*!
- Attempts to write the contents of the record buffer to the record specified
- by RecNo. Updates any open indexes.
-
- \param RecNo Record number to which data should be written
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Couldn't lock file</td></tr>
- <tr><td>XB_NOT_OPEN</td><td>File is not open</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Error writing to file</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_LOCK\_FAILED & Couldn't lock file \\ \hline
- XB\_NOT\_OPEN & File is not open \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- XB\_SEEK\_ERROR & Error seeking file \\ \hline
- XB\_WRITE\_ERROR & Error writing to file \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::PutRecord(xbULong RecNo)
-{
- xbShort rc;
-
-#if defined(XB_INDEX_ANY)
- xbIxList *i;
-#endif
-
- if( DbfStatus == XB_CLOSED )
- return XB_NOT_OPEN;
-
-/* lock the database */
-#ifdef XB_LOCKING_ON
- if( AutoLock ){
-// if(( rc = LockDatabase( XB_LOCK, RecNo )) != XB_NO_ERROR )
-// return rc;
-// if(( rc = LockDatabase( XB_LOCK, 0L )) != XB_NO_ERROR ){
-// LockDatabase( XB_UNLOCK, RecNo );
-// return rc;
-// }
-
- if((rc = ReadHeader(1)) != XB_NO_ERROR){
-// if(AutoLock){
-// LockDatabase( XB_UNLOCK, RecNo );
-// LockDatabase( XB_UNLOCK, 0L );
-// }
- return rc;
- }
- }
-#endif
-
- if( RecNo > NoOfRecs || RecNo == 0L )
- return XB_INVALID_RECORD;
-
-/* lock the indexes */
-#if defined(XB_INDEX_ANY)
-#ifdef XB_LOCKING_ON
- i = NdxList;
- while( i && AutoLock ){
-// if(( rc = i->index->LockIndex( XB_LOCK )) != XB_NO_ERROR )
-// return rc;
- i = i->NextIx;
- }
-#endif /* XB_LOCKING_ON */
-#endif
-
-#if defined(XB_INDEX_ANY)
- /* for any unique indexes that were updated, verify no unique keys exist */
- i = NdxList;
- while( i ){
- if( i->index->UniqueIndex() ){
- if(( i->KeyUpdated = i->index->KeyWasChanged()) == 1 ){
- i->index->CreateKey(0, 0);
- if( i->index->FindKey() == XB_FOUND && i->index->GetCurDbfRec() != RecNo)
- return XB_KEY_NOT_UNIQUE;
- }
- }
- i = i->NextIx;
- }
-#endif
-
-#if defined(XB_INDEX_ANY)
- /* loop through deleting old index keys and adding new index keys */
- i = NdxList;
- while( i ){
- if( !i->index->UniqueIndex() )
- i->KeyUpdated = i->index->KeyWasChanged();
- if( i->KeyUpdated ){
- i->index->CreateKey( 1, 0 ); /* load key buf w/ old values */
- if((rc = i->index->DeleteKey( CurRec )) != XB_NO_ERROR){
-#ifdef XB_LOCKING_ON
-// if( AutoLock ){
-// LockDatabase( XB_UNLOCK, RecNo );
-// LockDatabase( XB_UNLOCK, 0L );
-// }
-#if defined(XB_INDEX_ANY)
- i = NdxList;
- while( i && AutoLock ){
-// i->index->LockIndex( XB_UNLOCK );
- i = i->NextIx;
- }
-#endif /* XB_INDEX_ANY */
-#endif /* XB_LOCKING_ON */
- return rc;
- }
-
- i->index->CreateKey( 0, 0 );
- if(( rc = i->index->AddKey(CurRec)) != XB_NO_ERROR ){
-#ifdef XB_LOCKING_ON
-// if( AutoLock ){
-// LockDatabase( XB_UNLOCK, RecNo );
-// LockDatabase( XB_UNLOCK, 0L );
-// }
-#if defined(XB_INDEX_ANY)
- i = NdxList;
- while( i && AutoLock ){
-// i->index->LockIndex( XB_UNLOCK );
- i = i->NextIx;
- }
-#endif /* XB_INDEX_ANY */
-#endif /* XB_LOCKING_ON */
- return rc;
- }
- i->index->TouchIndex();
- }
- i = i->NextIx;
- }
-#endif /* XB_INDEX_ANY */
-
- if( _fseek( fp, (HeaderLen+(((xbOffT)RecNo-1L)*RecordLen)),0 ))
- return XB_SEEK_ERROR;
-
- if( fwrite( RecBuf, RecordLen, 1, fp ) != 1 )
- return XB_WRITE_ERROR;
-
- /* calculate the latest header information */
- xbDate d;
- UpdateYY = d.YearOf() - 1900;
- if(XFV == 3)
- UpdateYY %= 100; // dBASE III seems to do this, IV does not. DTB
- UpdateMM = d.MonthOf();
- UpdateDD = d.DayOf( XB_FMT_MONTH );
-
- /* rewrite the header record */
- if(( rc = WriteHeader( 1 )) != XB_NO_ERROR )
- return rc;
-
-#ifdef XB_LOCKING_ON
-// if( AutoLock ){
-// LockDatabase( XB_UNLOCK, RecNo );
-// LockDatabase( XB_UNLOCK, 0L );
-// }
-
-#if defined(XB_INDEX_ANY)
- i = NdxList;
- while( i && AutoLock ){
-// i->index->LockIndex( XB_UNLOCK );
- i = i->NextIx;
- }
-#endif /* XB_INDEX_ANY */
-#endif /* XB_LOCKING_ON */
-
- CurRec = RecNo;
- DbfStatus = XB_OPEN;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Delete the current record
-/*!
- Marks the current record as deleted or if "real" deletes are turned
- on (xbDbf::RealDeleteOn()) will delete the record and add it to the
- free record list. Normal dBase behavior is to simply mark the record
- as deleted; the record will actually be deleted when the the DBF file
- "packed" (xbDbf::PackDatabase()). If "real" deletes are not on, a
- record may be undeleted using xbDbf::UndeleteRecord().
-
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::DeleteRecord()
-{
- xbULong newCurRec = 0;
- xbShort rc = XB_NO_ERROR;
-
-#if defined(XB_INDEX_ANY)
- xbIxList *i;
-#endif
-
- if(!RecBuf)
- return XB_INVALID_RECORD;
-
- if(CurRec < 1 || CurRec > NoOfRecs)
- return XB_INVALID_RECORD;
-
-/* lock the database */
-#ifdef XB_LOCKING_ON
-
- if( AutoLock ){
-/*
- if(( rc = LockDatabase( XB_LOCK, CurRec )) != XB_NO_ERROR )
- return rc;
- if(( rc = LockDatabase( XB_LOCK, 0L )) != XB_NO_ERROR ){
- LockDatabase( XB_UNLOCK, CurRec );
- return rc;
- }
- */
- if((rc = ReadHeader(1)) != XB_NO_ERROR){
-// if(AutoLock){
-// LockDatabase( XB_UNLOCK, CurRec );
-// LockDatabase( XB_UNLOCK, 0L );
-// }
- return rc;
- }
- }
-#endif
-
-/* lock the indexes */
-#if defined(XB_INDEX_ANY) && defined(XB_LOCKING_ON) && defined(XB_REAL_DELETE)
- i = NdxList;
- while( i && AutoLock ){
-// if(( rc = i->index->LockIndex( XB_LOCK )) != XB_NO_ERROR )
-// return rc;
- i = i->NextIx;
- }
-#endif
-
-/* remove keys from indexes */
-#if defined(XB_REAL_DELETE) && defined(XB_INDEX_ANY)
-
- if(RealDelete){
- i = NdxList;
- while(i){
- i->index->CreateKey(0, 0); /* load key buf */
- if(i->index->GetCurDbfRec() == (xbULong)CurRec){
- i->index->DeleteKey(CurRec);
- newCurRec = i->index->GetCurDbfRec();
- }
- else
- i->index->DeleteKey(CurRec);
- i->index->TouchIndex();
- i = i->NextIx;
- }
- }
-
-#endif
-
- RecBuf[0] = 0x2a;
-
-
-#ifdef XB_REAL_DELETE
- if(RealDelete){
-#ifdef XB_MEMO_FIELDS
- //
- // Delete memo data for memo fields.
- //
- for(int f = 0; f < NoOfFields; f++ )
- if(GetFieldType(f) == 'M' && MemoFieldExists(f))
- UpdateMemoData(f, 0, 0, XB_LOCK);
-#endif
- xbase->PutULong(&RecBuf[1], FirstFreeRec);
- FirstFreeRec = CurRec;
- RealNumRecs--;
- WriteHeader(1);
- }
-#endif
-
- if(!RealDelete){
- if( DbfStatus != XB_UPDATED ){
- DbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, RecordLen );
- }
- rc = PutRecord( CurRec );
- }
- else
- {
- if(_fseek( fp, (HeaderLen+(((xbOffT)CurRec-1L)*RecordLen)), 0))
- return XB_SEEK_ERROR;
- if(fwrite( RecBuf, RecordLen, 1, fp ) != 1 )
- return XB_WRITE_ERROR;
-
- //
- // Attempt to read in the record for the current location
- // in the active index.
- //
- CurRec = newCurRec;
- if(CurRec)
- rc = GetRecord(CurRec);
- else
- BlankRecord();
- }
-
-#ifdef XB_LOCKING_ON
-// if(AutoLock){
-// LockDatabase( XB_UNLOCK, CurRec );
-// LockDatabase( XB_UNLOCK, 0L );
-// }
-
-#if defined(XB_INDEX_ANY) && defined(XB_REAL_DELETE)
- i = NdxList;
- while( i && AutoLock ){
-// i->index->LockIndex( XB_UNLOCK );
- i = i->NextIx;
- }
-#endif /* XB_INDEX_ANY */
-#endif /* XB_LOCKING_ON */
-
- return rc;
-}
-/************************************************************************/
-//! Undelete the current record
-/*!
- Marks the currect record as not deleted (i.e. removes the flag indicating
- the record is deleted). This method may not be used (and will return
- an error code) if "real" deletes are on.
-
- \returns One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_INVALID_RECORD</td><td>Invalid record number</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No error \\ \hline
- XB\_INVALID\_RECORD & Invalid record number \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::UndeleteRecord()
-{
- xbShort rc;
-
-#ifdef XB_REAL_DELETE
- if(RealDelete)
- return XB_INVALID_RECORD;
-#endif
- if( RecBuf ){
- if( DbfStatus != XB_UPDATED ){
- DbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, RecordLen );
- }
-
- RecBuf[0] = 0x20;
- if(( rc = PutRecord( CurRec )) != 0 )
- return rc;
- }
- else
- return XB_INVALID_RECORD;
-
- return 0;
-}
-/************************************************************************/
-//! Determine if current record is deleted
-/*!
- \returns TRUE (1) if the current record is marked as deleted or FALSE
- (0) if not.
-*/
-xbShort xbDbf::RecordDeleted()
-{
- if( RecBuf && RecBuf[0] == 0x2a )
- return 1;
- else
- return 0;
-}
-/************************************************************************/
-//! Create a unique file name
-/*!
-*/
-xbShort xbDbf::CreateUniqueDbfName( xbString & sDbfn, xbString & sDbtn )
-{
- xbShort dnf; /* directory in name flag */
- xbShort unique = 0;
- xbLong l = 1;
- char dbfn[13];
- char dbtn[13];
-
- dnf = xbase->DirectoryExistsInName( GetFileName() );
- sprintf( dbfn, "xb%06d.dbf", l );
- sprintf( dbtn, "xb%06d.dbt", l++ );
-
- if( dnf ){
- sDbfn.assign( GetFileName(), 0, dnf );
- sDbfn += dbfn;
- sDbtn.assign( GetFileName(), 0, dnf );
- sDbtn += dbtn;
- } else {
- sDbfn = dbfn;
- sDbtn = dbtn;
- }
-
- while( !unique ){
- if( access( sDbfn.getData(), 0 ) == -1 &&
- access( sDbtn.getData(), 0 ) == -1 )
- unique++;
- else{
- sprintf( dbfn, "xb%06d.dbf", l );
- sprintf( dbtn, "xb%06d.dbt", l++ );
-
- if( dnf ){
- sDbfn.assign( GetFileName(), 0, dnf );
- sDbfn += dbfn;
- sDbtn.assign( GetFileName(), 0, dnf );
- sDbtn += dbtn;
- } else {
- sDbfn = dbfn;
- sDbtn = dbtn;
- }
- }
- }
- return 0;
-}
-
-/************************************************************************/
-//! Pack data file
-/*!
-*/
-xbShort xbDbf::PackDatafiles(void (*statusFunc)(xbLong itemNum, xbLong numItems))
-{
- xbShort rc, i;
- FILE *t;
- xbLong l;
- char *target, *source;
- xbString TempDbfName;
- xbString TempDbtName;
- char * Buf = 0;
-
-#ifdef XB_MEMO_FIELDS
- char tbuf[4];
-#endif
-
-#ifdef XB_MEMO_FIELDS
- xbLong len, BufSize;
- xbShort MemoFields;
-#endif /* XB_MEMO_FIELDS */
-
- xbDbf Temp( xbase );
- CreateUniqueDbfName( TempDbfName, TempDbtName );
-
- if(( t = fopen( TempDbfName, "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-
- /* copy file header */
- if(( rc = _fseek( fp, 0, SEEK_SET )) != 0 )
- return XB_SEEK_ERROR;
-
- for( i = 0; i < HeaderLen; i++ )
- fputc( fgetc( fp ), t );
- fputc( 0x1a, t );
-
- if( fclose( t ) != 0 )
- return XB_CLOSE_ERROR;
-
-#ifdef XB_MEMO_FIELDS
- if(( MemoFields = MemoFieldsPresent()) > 0 ){
-
- if((t = fopen( TempDbtName, "w+b" )) == NULL)
- return XB_OPEN_ERROR;
-
- l = 1L;
- memset( tbuf, 0x00, 4 );
- xbase->PutLong( tbuf, l );
-
- if((fwrite(&tbuf, 4, 1, t)) != 1)
- return XB_WRITE_ERROR;
-
- if( MemoHeader.Version == 0x03 ){
- for( i = 0; i < 12; i++ ) fputc( 0x00, t );
- fputc( 0x03, t );
- for( i = 0; i < 495; i++ ) fputc( 0x00, t );
- } else {
- for( i = 0; i < 4; i++ ) fputc( 0x00, t );
- if ((fwrite(&MemoHeader.FileName, 8, 1, t)) != 1)
- return XB_WRITE_ERROR;
- for( i = 0; i < 4; i++ ) fputc( 0x00, t );
- memset( tbuf, 0x00, 2 );
- xbase->PutShort( tbuf, MemoHeader.BlockSize );
- if ((fwrite(&tbuf, 2, 1, t)) != 1)
- return XB_WRITE_ERROR;
-
- for( i = 22; i < MemoHeader.BlockSize; i++ ) fputc( 0x00, t );
- }
-
- if( fclose( t ) != 0 )
- return XB_CLOSE_ERROR;
- }
-#endif /* XB_MEMO_FIELDS */
-
- /* reopen as database */
- if(( rc = Temp.OpenDatabase( TempDbfName )) != XB_NO_ERROR )
- return rc;
-
-#ifdef XB_REAL_DELETE
- if(RealDelete)
- Temp.RealDeleteOn();
- Temp.FirstFreeRec = 0;
- Temp.RealNumRecs = 0;
-#endif
- Temp.ResetNoOfRecs();
- Temp.WriteHeader(2); // flush NoOfRecs=0 to disk
- target = Temp.GetRecordBuf();
- source = GetRecordBuf();
-
- for( l = 1; l <= PhysicalNoOfRecords(); l++ ){
- if(statusFunc && (l == 1 || !(l % 100) || l == PhysicalNoOfRecords()))
- statusFunc(l, PhysicalNoOfRecords());
-
- if(( rc = GetRecord( l )) != XB_NO_ERROR )
- return rc;
-
- if( !RecordDeleted() ){
- memcpy( target, source, GetRecordLen());
-
-#ifdef XB_MEMO_FIELDS
- BufSize = 0L;
-// Buf = NULL; Already set to 0, this statement flags as memory leak
-
- for( i = 0; i < NoOfFields; i++ ){
- if( GetFieldType( i ) == 'M' && MemoFieldExists( i )){
- Temp.PutLongField(i, 0L);
- len = GetMemoFieldLen( i );
- if( len > BufSize ){
- if( Buf )
- free( Buf );
- if((Buf = (char *)malloc(len)) == NULL)
- return XB_NO_MEMORY;
- BufSize = len;
- }
- GetMemoField( i, len, Buf, -1 );
- Temp.UpdateMemoData( i, len, Buf, -1 );
- }
- }
-#endif
- if(( rc = Temp.AppendRecord()) != XB_NO_ERROR ){
- if(Buf) free(Buf);
- return rc;
- }
- }
- }
- if( Buf ) free( Buf );
- Temp.CloseDatabase();
-
- if(fclose(fp) != 0)
- return XB_CLOSE_ERROR;
-
- if(remove(GetFileName()) != 0)
- return XB_WRITE_ERROR;
-
- if(rename(TempDbfName, GetFileName()) != 0)
- return XB_WRITE_ERROR;
-
-#ifdef XB_MEMO_FIELDS
- if( MemoFields ){
- if(fclose(mfp) != 0)
- return XB_CLOSE_ERROR;
-
- if(remove(MemofileName) != 0)
- return XB_WRITE_ERROR;
- if( rename( TempDbtName, MemofileName ) != 0 )
- return XB_WRITE_ERROR;
- if(( mfp = fopen( MemofileName, "r+b" )) == NULL )
- return XB_OPEN_ERROR;
- if(( rc = GetDbtHeader(1)) != 0 ){
- fclose( mfp );
- return rc;
- }
-#ifdef XB_LOCKING_ON
- /* no buffering in multi user mode */
- setbuf( mfp, NULL );
-#endif
- }
-
-#endif /* XB_MEMO_FIELDS */
-
- if(( fp = fopen( GetFileName(), "r+b" )) == NULL )
- return XB_OPEN_ERROR;
-
-#ifdef XB_LOCKING_ON
- /* no buffering in multi user mode */
- setbuf( fp, NULL );
-#endif
-
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Pack the database
-/*!
- This method removes all records marked for deletion from an Xbase (.DBF)
- file, reindexes any open index files, and also reorganizes any memo fields
- stored in a .DBT memo file.
-
- \param packStatusFunc status function
- \param indexStatusFunc index status function
-
- \param LockWaitOption One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>LockWaitOption</th><th>Description</th></tr>
- <tr><td>F_SETLK</td><td>Return immediately if the DBF file cannot be locked</td></tr>
- <tr><td>XB_LOCK</td><td>Wait for lock on DBF file to succeed</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{LockWaitOption} & \textbf{Description} \\ \hline \hline
- F\_SETLK & Return immediately if DBF file cannot be locked \\ \hline
- F\_SETLKW & Wait for lock on DBF file to succeed \\ \hline
- \end{tabular}
- \endlatexonly
-
- \returns One of the following return codes:
- \htmlonly
- <p>
- <table border=2><tr><th>Return Code</th><th>Description</th></tr>
- <tr><td>XB_NO_ERROR</td><td>No error</td></tr>
- <tr><td>XB_CLOSE_ERROR</td><td>Unable to close intermediate work file</td></tr>
- <tr><td>XB_OPEN_ERROR</td><td>Could not open file</td></tr>
- <tr><td>XB_NO_MEMORY</td><td>Memory allocation error</td></tr>
- <tr><td>XB_WRITE_ERROR</td><td>Couldn't write to disk</td></tr>
- <tr><td>XB_SEEK_ERROR</td><td>Error seeking file</td></tr>
- <tr><td>XB_LOCK_FAILED</td><td>Unable to lock file or index</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Return Code} & \textbf{Description} \\ \hline \hline
- XB\_NO\_ERROR & No Error \\ \hline
- XB\_CLOSE\_ERROR & Unable to close intermediate work file \\ \hline
- XB\_OPEN\_ERROR & Couldn't open the file \\ \hline
- XB\_NO\_MEMORY & Memory allocation error \\ \hline
- XB\_WRITE\_ERROR & Couldn't write to disk \\ \hline
- XB\_SEEK\_ERROR & Error seeking file \\ \hline
- XB\_LOCK\_FAILED & Unable to lock file or index \\ \hline
- \end{tabular}
- \endlatexonly
-*/
-xbShort xbDbf::PackDatabase(xbShort LockWaitOption,
- void (*packStatusFunc)(xbLong itemNum, xbLong numItems),
- void (*indexStatusFunc)(xbLong itemNum, xbLong numItems))
-{
- xbShort rc;
-
- /* lock all open files and indexes */
-// if(( rc = ExclusiveLock( LockWaitOption )) != XB_NO_ERROR ) return rc;
-
- if(( rc = PackDatafiles(packStatusFunc)) != XB_NO_ERROR ){
-// ExclusiveUnlock();
- return rc;
- }
-
- /* refresh file header */
- if(( rc = ReadHeader(1)) != XB_NO_ERROR )
- return rc;
-
- if(( rc = RebuildAllIndices(indexStatusFunc)) != XB_NO_ERROR )
- return rc;
-
-// ExclusiveUnlock();
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Copy DBF structure
-/*!
-*/
-xbShort xbDbf::CopyDbfStructure(const char *NewFileName, xbShort Overlay) {
-
- xbShort rc, i;
- xbString ndfn; /* new dbf file name */
- char ch;
-
-#ifdef XB_MEMO_FIELDS
- char buf[9];
- xbShort ct, NameLen;
- xbString MemoName;
-#endif
- FILE *t;
-
- /* build the new file name */
- rc = NameSuffixMissing( 1, NewFileName );
- ndfn = NewFileName;
- if( rc == 1 )
- ndfn += ".dbf";
- else if( rc == 2 )
- ndfn += ".DBF";
-
- /* check if the file exists and Overlay is on */
- if(((t = fopen( ndfn, "r" )) != NULL ) && !Overlay) {
- fclose(t);
- return XB_FILE_EXISTS;
- }
-
- /* open new file */
- if((t = fopen(ndfn, "w+b")) == NULL)
- return XB_OPEN_ERROR;
-
- /* copy the file header */
- if(( rc = _fseek( fp, 0, SEEK_SET )) != 0 )
- return XB_SEEK_ERROR;
-
- fputc( fgetc( fp ), t );
-
- /* do the date */
- xbDate d;
- ch = d.YearOf() - 1900;
- if(XFV == 3)
- ch %= 100; // dBASE III+ does this, dBASE IV does not.
- fputc( ch, t );
- ch = d.MonthOf();
- fputc( ch, t );
- ch = d.DayOf( XB_FMT_MONTH );
- fputc( ch, t );
-
- /* record count */
- for( i = 0; i < 4; i++ ) fputc( 0x00, t );
-
- if((rc = _fseek(fp, 7, SEEK_CUR)) != 0) {
- fclose( t );
- return XB_SEEK_ERROR;
- }
- for( i = 0; i < 4; i++ )
- fputc( fgetc( fp ), t );
-
- for( i = 0; i < 17; i++ )
- fputc( 0x00, t );
-
- if((rc = _fseek( fp, 17, SEEK_CUR )) != 0) {
- fclose( t );
- return XB_SEEK_ERROR;
- }
-
- for( i = 29; i < HeaderLen; i++ )
- fputc( fgetc( fp ), t );
-
- fputc( 0x1a, t );
- fclose( t );
-
-#ifdef XB_MEMO_FIELDS
- if( MemoFieldsPresent()){
- MemoName = ndfn;
-
- NameLen = MemoName.len();
- NameLen--;
- if( MemoName.getCharacter( NameLen ) == 'F' )
- MemoName.putAt(NameLen, 'T');
- else
- MemoName.putAt(NameLen, 't');
-
- if(( t = fopen( MemoName, "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-
- memset( buf, 0x00, 4 );
- xbase->PutLong( buf, 1L );
- if(( fwrite( &buf, 4, 1, t )) != 1 ){
- fclose( t );
- return XB_WRITE_ERROR;
- }
- if( MemoHeader.Version == 0x03 ){
- for( i = 0; i < 12; i++ ) fputc( 0x00, t );
- fputc( 0x03, t );
- for( i = 0; i < 495; i++ ) fputc( 0x00, t );
- }
- else
- {
- for( i = 0; i < 4; i++ ) fputc( 0x00, t ); // put 4 bytes 0x00
- memset( buf, 0x00, 9 );
- NameLen = ndfn.len();
- for( i = 0, ct = 0; i < NameLen; i++ )
- if( ndfn.getCharacter( i ) == PATH_SEPARATOR ){
- ct = i;
- ct++;
- }
-
- for( i = 0; i < 8 && ndfn[i+ct] != '.'; i++ )
- buf[i] = ndfn[i+ct];
-
- fwrite( &buf, 8, 1, t );
- for( i = 0; i < 4; i++ ) fputc( 0x00, t );
- memset( buf, 0x00, 2 );
- xbase->PutShort( buf, MemoHeader.BlockSize );
- if(( fwrite( &buf, 2, 1, t )) != 1 ){
- fclose(t);
- return XB_WRITE_ERROR;
- }
- for( i = 22; i < MemoHeader.BlockSize; i++ ) fputc( 0x00, t );
- }
- }
- fclose( t );
-#endif // XB_MEMO_FIELDS
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Add index to list
-/*!
- Adds the specified index to the list of indexes maintained by the
- dbf.
-
- \param n index to add
- \param IndexName name of index
-*/
-#if defined(XB_INDEX_ANY)
-xbShort xbDbf::AddIndexToIxList(xbIndex * n, const char *IndexName)
-{
- xbIxList *i, *s, *t;
-
- if( !FreeIxList ){
- if((i = (xbIxList *) malloc(sizeof(xbIxList))) == NULL)
- return XB_NO_MEMORY;
- }
- else
- {
- i = FreeIxList;
- FreeIxList = i->NextIx;
- }
- memset(i, 0x00, sizeof(xbIxList));
-
- i->IxName = IndexName;
- i->index = n;
-
- s = NULL;
- t = NdxList;
- while( t && strcmp( t->IxName, IndexName ) < 0 ){
- s = t;
- t = t->NextIx;
- }
- i->NextIx = t;
- if( s == NULL )
- NdxList = i;
- else
- s->NextIx = i;
- return 0;
-}
-#endif
-/************************************************************************/
-//! Rebuild all index files
-/*!
-*/
-xbShort xbDbf::RebuildAllIndices(void (*statusFunc)(xbLong itemNum, xbLong numItems))
-{
-#if defined(XB_INDEX_ANY)
- xbShort rc;
- xbIxList *n;
-
- n = NdxList;
- while( n ){
- if(( rc = n->index->ReIndex(statusFunc)) != XB_NO_ERROR ){
-// ExclusiveUnlock();
- return rc;
- }
- n = n->NextIx;
- }
-#endif
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Delete all records
-/*!
-*/
-xbShort xbDbf::DeleteAll( xbShort Option )
-{
- xbShort rc;
-
- if(( NoOfRecords()) == 0 )
- return XB_NO_ERROR;
- if(( rc = GetFirstRecord()) != XB_NO_ERROR )
- return rc;
-
- if( Option == 0 ){ /* delete all option */
- while( 1 ){
- if( !RecordDeleted())
- if(( rc = DeleteRecord()) != XB_NO_ERROR )
- return rc;
- if(( rc = GetNextRecord()) != XB_NO_ERROR )
- break;
- }
- }
- else /* undelete all option */
- {
- while( 1 ){
- if( RecordDeleted())
- if(( rc = UndeleteRecord()) != XB_NO_ERROR )
- return rc;
- if(( rc = GetNextRecord()) != XB_NO_ERROR )
- break;
- }
- }
- if( rc == XB_EOF )
- return XB_NO_ERROR;
- else
- return rc;
-}
-/************************************************************************/
-//! Delete all records and pack data file
-/*!
-*/
-xbShort xbDbf::Zap( xbShort WaitOption )
-{
- xbShort rc;
- xbString TempDbfName, TempDbtName;
-
- CreateUniqueDbfName( TempDbfName, TempDbtName );
- if(( rc = CopyDbfStructure( TempDbfName, 1 )) != XB_NO_ERROR) {
- return rc;
- }
-
- if( fp ){
- fclose( fp );
- fp = 0;
- }
-
- if(( rc = remove( GetFileName() )) != 0 )
- return XB_WRITE_ERROR;
-
- if(( rc = rename( TempDbfName, GetFileName() )) != 0 )
- return XB_WRITE_ERROR;
-
- if((fp = fopen( GetFileName(), "r+b" )) == NULL)
- return XB_OPEN_ERROR;
-
-#ifdef XB_LOCKING_ON
- setbuf( fp, NULL );
-#endif
- ReadHeader( 1 );
-
-#ifdef XB_MEMO_FIELDS
- if( MemoFieldsPresent() ){
- fclose( mfp );
-
- if(( rc = remove( MemofileName )) != 0 )
- return XB_WRITE_ERROR;
-
- if(( rc = rename( TempDbtName, MemofileName )) != 0 )
- return XB_WRITE_ERROR;
-
- if(( mfp = fopen( MemofileName, "r+b" )) == NULL)
- return XB_OPEN_ERROR;
-
- }
-#endif // XB_MEMO_FIELDS
-
- if(( rc = RebuildAllIndices()) != XB_NO_ERROR )
- return rc;
-
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Remove an index from the list
-/*!
-*/
-#if defined(XB_INDEX_ANY)
-xbShort xbDbf::RemoveIndexFromIxList(xbIndex * n) {
- xbIxList *i, *s;
-
- i = NdxList;
- s = NULL;
- while( i ){
- if( i->index == n ){
- /* remove it from current chain */
- if( s )
- s->NextIx = i->NextIx;
- else
- NdxList = i->NextIx;
-
- /* add i to the current free chain */
- i->NextIx = FreeIxList;
- FreeIxList = i;
- FreeIxList->IxName = (const char *)NULL;
- FreeIxList->index = NULL;
- break;
- }
- else
- {
- s = i;
- i = i->NextIx;
- }
- }
- return XB_NO_ERROR;
-}
-#endif
-
-/************************************************************************/
-//! Gets the number of records in the data file
-/*!
-*/
-xbLong xbDbf::NoOfRecords()
-{
- xbLong numRecs;
-
-/* lock the database */
-#ifdef XB_LOCKING_ON
- xbShort rc;
-
- if( AutoLock ){
-// if(( rc = LockDatabase( XB_LOCK, 0L )) != XB_NO_ERROR )
-// return rc;
-
- if((rc = ReadHeader(1)) != XB_NO_ERROR){
-// if(AutoLock)
-// LockDatabase( XB_UNLOCK, 0L );
- return rc;
- }
- }
-#endif
-
-#ifndef XB_REAL_DELETE
- numRecs = NoOfRecs;
-#else
- numRecs = RealDelete ? RealNumRecs : NoOfRecs;
-#endif
-
-#ifdef XB_LOCKING_ON
-// if(AutoLock)
-// LockDatabase( XB_UNLOCK, 0L );
-#endif
-
- return numRecs;
-}
-/************************************************************************/
-//! Get the physical number of records in the data file
-/*!
-*/
-xbLong xbDbf::PhysicalNoOfRecords()
-{
- xbShort rc;
-
-/* lock the database */
-#ifdef XB_LOCKING_ON
-// if( AutoLock )
-// if(( rc = LockDatabase( XB_LOCK, 0L )) != XB_NO_ERROR )
-// return rc;
-#endif
-
- rc = ReadHeader(1);
-
-#ifdef XB_LOCKING_ON
-// if(AutoLock)
-// if(( rc = LockDatabase( XB_UNLOCK, 0L )) != XB_NO_ERROR )
-// return rc;
-#endif
-
- if( rc )
- return rc;
-
- return NoOfRecs;
-}
-
-/************************************************************************/
-#if defined(XB_INDEX_ANY)
-//! Get the number of currently open indexes for data file
-/*!
-*/
-xbShort xbDbf::IndexCount()
-{
- xbShort count;
- xbIxList *i;
-
- for(count = 0, i = NdxList; i; i = i->NextIx, count++) ;
-
- return count;
-}
-/************************************************************************/
-//! Get a specific index
-/*!
-*/
-xbIndex * xbDbf::GetIndex(xbShort indexNum)
-{
- xbIxList *i;
-
- i = NdxList;
- while(indexNum && i){
- indexNum--;
- i = i->NextIx;
- }
-
- if(i)
- return i->index;
-
- return 0;
-}
-
-#endif // XB_INDEX_ANY
-/************************************************************************/
-void xbDbf::Flush()
-{
- if(fp)
- fflush(fp);
-
-#ifdef XB_MEMO_FIELDS
- if(mfp)
- fflush(mfp);
-#endif
-
-#if defined(XB_INDEX_ANY)
- xbIxList
- *i;
-
- i = NdxList;
- while(i) {
- i->index->Flush();
- i = i->NextIx;
- }
-#endif
-}
-/************************************************************************/
-#ifdef XB_LOCKING_ON
-xbShort xbDbf::SetLockMode( xbShort nlm )
-{
-/*
- xbShort rc;
- if( LockMode != XB_XBASE_LOCK_MODE &&
- nlm == XB_XBASE_LOCK_MODE &&
- !xblfh ){
- rc = OpenXbLockFile();
- if( rc )
- return rc;
- }
-*/
- LockMode = nlm;
- return XB_NO_ERROR;
-}
-#endif
-/************************************************************************/
-const char * xbDbf::GetExtWithDot( bool lower )
-{
- return lower ? ".dbf" : ".DBF";
-}
diff --git a/xbase64/xbdbf.h b/xbase64/xbdbf.h
deleted file mode 100755
index ce28e9a..0000000
--- a/xbase64/xbdbf.h
+++ /dev/null
@@ -1,533 +0,0 @@
-/* xbdbf.h
-
- Xbase64 project source code
-
- This file contains the Class definition for a xbDBF object.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XB_DBF_H__
-#define __XB_DBF_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbtypes.h>
-#include <xbase64/xbdate.h>
-#include <xbase64/xbfile.h>
-
-#include <iostream>
-#include <stdio.h>
-
-/*! \file xbdbf.h
-*/
-
-#if defined(XB_INDEX_ANY)
- class XBDLLEXPORT xbIndex;
- class XBDLLEXPORT xbNdx;
- class XBDLLEXPORT xbNtx;
-#endif
-
-/*****************************/
-/* Field Types */
-
-#define XB_CHAR_FLD 'C'
-#define XB_LOGICAL_FLD 'L'
-#define XB_NUMERIC_FLD 'N'
-#define XB_DATE_FLD 'D'
-#define XB_MEMO_FLD 'M'
-#define XB_FLOAT_FLD 'F'
-
-/*****************************/
-/* File Status Codes */
-
-#define XB_CLOSED 0
-#define XB_OPEN 1
-#define XB_UPDATED 2
-
-/*****************************/
-/* Other defines */
-
-#define XB_OVERLAY 1
-#define XB_DONTOVERLAY 0
-
-#define XB_CHAREOF '\x1A' /* end of DBF */
-#define XB_CHARHDR '\x0D' /* header terminator */
-
-//! Used to define the fields in a database (DBF file).
-/*!
- Generally one would define an xbSchema array to be passed
- to xbDbf::CreateDatabase() to define the fields in the database.
-
- For example, one might create a declaration as follows:
-
- \code
- xbSchema MyRecord[] =
- {
- { "FIRSTNAME", XB_CHAR_FLD, 15, 0 },
- { "LASTNAME", XB_CHAR_FLD, 20, 0 },
- { "BIRTHDATE", XB_DATE_FLD, 8, 0 },
- { "AMOUNT", XB_NUMERIC_FLD, 9, 2 },
- { "SWITCH", XB_LOGICAL_FLD, 1, 0 },
- { "FLOAT1", XB_FLOAT_FLD, 9, 2 },
- { "FLOAT2", XB_FLOAT_FLD, 9, 1 },
- { "FLOAT3", XB_FLOAT_FLD, 9, 2 },
- { "FLOAT4", XB_FLOAT_FLD, 9, 3 },
- { "MEMO1", XB_MEMO_FLD, 10, 0 },
- { "ZIPCODE", XB_NUMERIC_FLD, 5, 0 },
- { "",0,0,0 }
- };
- \endcode
-
- Note that the last xbSchema in an array must be a "null" entry like the
- one above:
-
- \code
- { "",0,0,0 }
- \endcode
-
- To indicate the end of the array.
-*/
-struct XBDLLEXPORT xbSchema {
- char FieldName[11];
- char Type;
-// xbUShort FieldLen; /* does not work */
-// xbUShort NoOfDecs; /* does not work */
- unsigned char FieldLen; /* fields are stored as one byte on record*/
- unsigned char NoOfDecs;
-};
-
-//! Defines a field in an XBase file header (DBF file header)
-/*!
- This structure is only used internally by the xbDbf class.
-*/
-struct XBDLLEXPORT xbSchemaRec {
- char FieldName[11];
- char Type; /* field type */
- char *Address; /* pointer to field in record buffer 1 */
-// xbUShort FieldLen; /* does not work */
-// xbUShort NoOfDecs; /* does not work */
- unsigned char FieldLen; /* fields are stored as one byte on record */
- unsigned char NoOfDecs;
- char *Address2; /* pointer to field in record buffer 2 */
- char *fp; /* pointer to null terminated buffer for field */
- /* see method GetString */
- xbShort LongFieldLen; /* to handle long field lengths */
-};
-
-//! xbIxList struct
-/*!
- Internal use only.
-*/
-struct XBDLLEXPORT xbIxList {
- xbIxList * NextIx;
- xbString IxName;
-#if defined(XB_INDEX_ANY)
- xbIndex * index;
- xbShort Unique;
- xbShort KeyUpdated;
-#endif
-};
-
-//! xbMH struct
-/*!
- Internal use only.
-*/
-
-#ifdef XB_MEMO_FIELDS
-struct XBDLLEXPORT xbMH{ /* memo header */
- xbLong NextBlock; /* pointer to next block to write */
- char FileName[8]; /* name of dbt file */
- char Version; /* not sure */
- xbShort BlockSize; /* memo file block size */
-};
-#endif
-
-//! xbDbf class
-/*!
- The xbDbf class encapsulates an xbase DBF database file. It includes
- all dbf access, field access, and locking methods.
-*/
-class XBDLLEXPORT xbDbf : protected xbFile{
-
-public:
- xbDbf( xbXBase * );
- virtual ~xbDbf();
-
- xbXBase *xbase; /* linkage to main base class */
-
-/* datafile methods */
-#if defined(XB_INDEX_ANY)
- xbShort AddIndexToIxList(xbIndex *, const char *IndexName);
- xbShort RemoveIndexFromIxList( xbIndex * );
-#endif
- xbShort AppendRecord();
- xbShort BlankRecord();
- xbShort CloseDatabase( xbBool deleteIndexes = 0 );
- xbShort CopyDbfStructure( const char *, xbShort );
- xbShort CreateDatabase( const char * Name, xbSchema *, xbShort Overlay );
- //! Delete all records
- /*!
- */
- xbShort DeleteAllRecords() { return DeleteAll(0); }
- xbShort DeleteRecord();
-#ifdef XBASE_DEBUG
- xbShort DumpHeader( xbShort );
-#endif
- xbShort DumpRecord( xbULong );
- //! Return number of fields
- /*!
- */
- xbLong FieldCount() { return NoOfFields; }
- //! Return Dbf name
- /*!
- */
- const xbString& GetDbfName() { return GetFileName(); }
- //! Return status
- /*!
- */
- xbShort GetDbfStatus() { return DbfStatus; }
- xbShort GetFirstRecord();
- xbShort GetLastRecord();
- xbShort GetNextRecord();
- xbShort GetPrevRecord();
- //! Return current record number
- /*!
- */
- xbLong GetCurRecNo() { return CurRec; }
- xbShort GetRecord( xbULong );
- //! Return a pointer to the record buffer
- /*!
- */
- char * GetRecordBuf() { return RecBuf; }
- //! Return record length
- /*!
- */
- xbShort GetRecordLen() { return RecordLen; }
- xbShort NameSuffixMissing( xbShort, const char * );
- xbLong GetRecCnt() { return NoOfRecords(); }
- xbLong NoOfRecords();
- xbLong PhysicalNoOfRecords();
- xbShort OpenDatabase( const char * );
- xbShort PackDatabase(xbShort LockWaitOption,
- void (*packStatusFunc)(xbLong itemNum, xbLong numItems) = 0,
- void (*indexStatusFunc)(xbLong itemNum, xbLong numItems) = 0);
- xbShort PutRecord(); // Put record to current position
- xbShort PutRecord(xbULong);
- xbShort RebuildAllIndices(
- void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
- xbShort RecordDeleted();
- //! Set number of records to zero????
- /*!
- */
- void ResetNoOfRecs() { NoOfRecs = 0L; }
- xbShort SetVersion( xbShort );
- //! Undelete all records
- /*!
- */
- xbShort UndeleteAllRecords() { return DeleteAll(1); }
- xbShort UndeleteRecord();
- xbShort Zap( xbShort );
-
-/* field methods */
- const char *GetField(xbShort FieldNo) const; // Using internal static buffer
- const char *GetField(const char *Name) const;
- xbShort GetField( xbShort FieldNo, char *Buf) const;
- xbShort GetRawField( xbShort FieldNo, char *Buf) const;
- xbShort GetField( xbShort FieldNo, char *Buf, xbShort RecBufSw) const;
- xbShort GetField( const char *Name, char *Buf) const;
- xbShort GetRawField(const char *Name, char *Buf) const;
- xbShort GetField( const char *Name, char *Buf, xbShort RecBufSw) const;
- xbShort GetField(xbShort FieldNo, xbString&, xbShort RecBufSw ) const;
- xbShort GetFieldDecimal( xbShort );
- xbShort GetFieldLen( xbShort );
- char * GetFieldName( xbShort );
- xbShort GetFieldNo( const char * FieldName ) const;
- char GetFieldType( xbShort FieldNo ) const;
- xbShort GetLogicalField( xbShort FieldNo );
- xbShort GetLogicalField( const char * FieldName );
- char * GetStringField( xbShort FieldNo );
- char * GetStringField( const char * FieldName );
- xbShort PutField( xbShort, const char * );
- xbShort PutRawField( xbShort FieldNo, const char *buf );
- xbShort PutField( const char *Name, const char *buf);
- xbShort PutRawField( const char *Name, const char *buf );
- xbShort ValidLogicalData( const char * );
- xbShort ValidNumericData( const char * );
-
- xbLong GetLongField( const char *FieldName) const;
- xbLong GetLongField( const xbShort FieldNo) const;
- xbShort PutLongField( const xbShort, const xbLong );
- xbShort PutLongField( const char *, const xbLong);
-
- xbFloat GetFloatField( const char * FieldName );
- xbFloat GetFloatField( xbShort FieldNo );
- xbShort PutFloatField( const char *, const xbFloat);
- xbShort PutFloatField( const xbShort, const xbFloat);
-
- xbDouble GetDoubleField( const char *);
- xbDouble GetDoubleField( xbShort, xbShort RecBufSw = 0);
- xbShort PutDoubleField( const char *, xbDouble);
- xbShort PutDoubleField( const xbShort, xbDouble);
-
-#ifdef XB_LOCKING_ON
- xbShort GetLockMode() { return LockMode; }
- xbShort SetLockMode( xbShort );
-// xbShort OpenXbLockFile();
-// xbShort GetTableLockCnt() { return TableLockCnt; }
-// xbShort LockIndex( xbShort LockType ); /* for XB_XBASE_LOCK_MODE */
- int GetDbfFileNo() { return fileno( fp ); }
- int GetMemoFileNo() { return fileno( mfp ); }
-
-#ifdef XB_MEMO_FIELDS
-// xbShort GetMemoLockCnt() { return MemoLockCnt; }
-#endif
-
-/*
- xbShort LockTable( xbShort LockType );
- xbShort LockXbaseTable( xbShort LockType );
- xbShort LockClipperTable( xbShort LockType );
- xbShort LockFoxproTable( xbShort LockType );
- xbShort LockDbaseTable( xbShort LockType );
-
- xbShort LockRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
- xbShort LockXbaseRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
- xbShort LockClipperRecord(
- xbShort LockType, xbULong RecNo, xbULong RecCnt );
- xbShort LockFoxproRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
- xbShort LockDbaseRecord( xbShort LockType, xbULong RecNo, xbULong RecCnt );
-
- xbShort LockDatabase( xbShort, xbShort, xbULong );
- xbShort ExclusiveLock( xbShort );
- xbShort ExclusiveUnlock();
- xbShort LockDatabase( xbShort cmd, xbULong recNo ) { return 0; }
-*/
-
-#ifndef HAVE_FCNTL
- xbShort UnixToDosLockCommand( xbShort WaitOption,
- xbShort LockType ) const;
-#endif
-
-#else
- xbShort LockDatabase( xbShort, xbShort, xbLong )
- { return XB_NO_ERROR; }
- xbShort ExclusiveLock( xbShort ) { return XB_NO_ERROR; };
- xbShort ExclusiveUnlock() { return XB_NO_ERROR; };
-#endif
-
- //! Turn autolock on
- /*!
- */
- void AutoLockOn() { AutoLock = 1; }
- //! Turn autolock off
- /*!
- */
- void AutoLockOff() { AutoLock = 0; }
- //! Return whether or not autolocking is on or off
- /*!
- */
- xbShort GetAutoLock() { return AutoLock; }
-
-#ifdef XB_MEMO_FIELDS
- xbShort GetMemoField( xbShort FieldNo, xbLong len,
- char * Buf, xbShort LockOption );
- xbLong GetMemoFieldLen( xbShort FieldNo );
- xbShort GetFPTField( xbShort FieldNo, xbLong len,
- char * Buf, xbShort LockOption );
- xbLong GetFPTFieldLen( xbShort FieldNo );
- xbShort UpdateMemoData( xbShort FieldNo, xbLong len,
- const char * Buf, xbShort LockOption );
- xbShort MemoFieldExists( xbShort FieldNo ) const;
- xbShort LockMemoFile( xbShort WaitOption, xbShort LockType );
-
- xbShort MemoFieldsPresent() const;
- xbLong CalcLastDataBlock();
- xbShort FindBlockSetInChain( xbLong BlocksNeeded, xbLong
- LastDataBlock, xbLong & Location, xbLong &PreviousNode );
- xbShort GetBlockSetFromChain( xbLong BlocksNeeded, xbLong
- Location, xbLong PreviousNode );
- xbString & GetDbtName() { return MemofileName; }
-
-#ifdef XBASE_DEBUG
- xbShort DumpMemoFreeChain();
- void DumpMemoHeader() const;
- void DumpMemoBlock() const;
-#endif
-#endif
-
- //! Turn on "real" deletes
- /*!
- This should be done before creating a database (with
- xbDbf::CreateDatatabase()) and thereafter before opening
- a database with xbDbfCreateDatabase().
-
- You cannot "turn on" real deletes once a database has been created
- and records added.
- */
- void RealDeleteOn() { RealDelete = 1; if(fp) ReadHeader(1); }
- /*! Turn off "real" deletes
- */
- void RealDeleteOff() { RealDelete = 0; if(fp) ReadHeader(1); }
- //! Return whether "real" deletes are on or off
- /*!
- Use this to determine if "real deletes" are being used with
-the database.
- */
- xbShort GetRealDelete() { return RealDelete; }
-
-#if defined(XB_INDEX_ANY)
- xbShort IndexCount();
- xbIndex *GetIndex(xbShort indexNum);
-#endif
-
- void Flush();
- virtual const char* GetExtWithDot( bool lower );
-
- private:
-
- xbShort DeleteAll( xbShort );
- void InitVars();
- xbShort PackDatafiles(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
- xbShort ReadHeader( xbShort );
- xbShort WriteHeader( xbShort );
-
-#ifdef XB_MEMO_FIELDS
- xbShort AddMemoData( xbShort FieldNo, xbLong Len, const char * Buf );
- xbShort CreateMemoFile();
- xbShort DeleteMemoField( xbShort FieldNo );
- xbShort GetDbtHeader( xbShort Option );
- xbShort GetMemoBlockSize() { return MemoHeader.BlockSize; }
- xbShort OpenMemoFile();
- xbShort OpenFPTFile();
- xbShort PutMemoData( xbLong StartBlock, xbLong BlocksNeeded,
- xbLong Len, const char * Buf );
- xbShort ReadMemoBlock( xbLong BlockNo, xbShort Option);
- xbShort SetMemoBlockSize( xbShort );
- xbShort UpdateHeadNextNode() const;
- xbShort WriteMemoBlock( xbLong BlockNo, xbShort Option );
- xbShort IsType3Dbt() const { return( Version==(char)0x83 ? 1:0 ); }
- xbShort IsType4Dbt() const
- {return (( Version==(char)0x8B || Version==(char)0x8E ) ? 1:0 );}
- xbShort CreateUniqueDbfName( xbString &, xbString & );
-#endif
-
-
-// xbString DatabaseName;
- xbShort XFV; /* xBASE file version */
- xbShort NoOfFields;
- char DbfStatus; /* 0 = closed
- 1 = open
- 2 = updates pending */
- FILE *fp; /* file pointer */
- xbSchemaRec *SchemaPtr; /* Pointer to field data */
- char *RecBuf; /* Pointer to record buffer */
- char *RecBuf2; /* Pointer to original rec buf */
-
-#ifdef XB_MEMO_FIELDS
- xbString MemofileName; /* memo file name */
- FILE *mfp; /* memo file pointer */
- void *mbb; /* memo block buffer */
- xbMH MemoHeader; /* memo header structure */
- xbShort mfield1; /* memo block field one FF */
- xbShort MStartPos; /* memo start pos of data */
- xbLong MFieldLen; /* memo length of data */
- xbLong NextFreeBlock; /* next free block in free chain */
- xbLong FreeBlockCnt; /* count of free blocks this set */
- xbLong MNextBlockNo; /* free block chain */
- xbLong MNoOfFreeBlocks; /* free block chain */
- xbLong CurMemoBlockNo; /* Current block no loaded */
-#endif
-
-/* Next seven variables are read directly off the database header */
-/* Don't change the order of the following seven items */
- char Version;
- char UpdateYY;
- char UpdateMM;
- char UpdateDD;
-// xbLong NoOfRecs;
-// xbShort HeaderLen;
-// xbShort RecordLen;
-
- xbULong NoOfRecs;
- xbUShort HeaderLen;
- xbUShort RecordLen;
-
-//#ifdef XB_REAL_DELETE
- xbULong FirstFreeRec;
- xbULong RealNumRecs;
-//#endif
-
-// xbIxList * MdxList;
- xbIxList * NdxList;
- xbIxList * FreeIxList;
- xbULong CurRec; /* Current record or zero */
- xbShort AutoLock; /* Auto update option 0 = off */
-
-//#ifdef XB_REAL_DELETE
- xbShort RealDelete; /* real delete option 0 = off */
-//#endif
-
-#ifdef XB_LOCKING_ON
- FILE *xblfh; /* xbase lock file pointer for xbase locking */
- xbShort LockMode; /* lock mode for this table */
- xbString lfn; /* xbase lock file name for xbase locking */
- xbShort TableLockCnt; /* number of table locks */
- xbShort IndexLockCnt; /* no of index locks XB_XBASE_LOCK_MODE only */
-
-#ifdef XB_MEMO_FIELDS
- xbShort MemoLockCnt; /* number of memo file locks */
-#endif
-
- /* old locking stuff */
- xbShort CurLockType; /* current type of file lock */
- xbShort CurLockCount; /* number of current file locks */
- xbULong CurLockedRecNo; /* currently locked record no */
- xbShort CurRecLockType; /* current type of rec lock held (F_RDLOCK or F_WRLCK) */
- xbShort CurRecLockCount; /* number of current record locks */
- xbShort CurMemoLockType; /* current type of memo lock */
- xbShort CurMemoLockCount; /* number of current memo locks */
-#endif
-
-};
-#endif // __XB_DBF_H__
-
-
diff --git a/xbase64/xbexp.cpp b/xbase64/xbexp.cpp
deleted file mode 100755
index a3e1fa5..0000000
--- a/xbase64/xbexp.cpp
+++ /dev/null
@@ -1,1323 +0,0 @@
-/* xbexp.cpp
-
- Xbase64 project source code
-
- This file contains logic for handling Xbase expressions.
-
- Copyright (C) 1997,2003,2004 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbexp.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-#ifdef XB_EXPRESSIONS
-#include <ctype.h>
-#include <string.h>
-
-//#include <xbase64/xbexcept.h>
-
-
-/*! \file xbexp.cpp
-*/
-
-// set the default date format
-//xbString xbExpn::DefaultDateFormat = "MM/DD/YY";
-
-/************************************************************************/
-/* putting this part in EXP did not work */
-
-/* No of parms
-
- value meaning
-
- 0 0
- 1 1
- 2 2
- 100 0 or more
- 101 1 or more
- 102 2 or more
-
-
- Return Type
- N Numeric
- C Char or string
- 1 Varies, if sibling 1 is C, set to C, otherwise N
-
-
-*/
-
-
-
-
-
-
-static xbFuncDtl FuncList[] =
-{
- /* Func # of Return
- Name parms Type */
- { "ABS", 1, 'N' },
- { "ASC", 1, 'N' },
- { "AT", 2, 'N' },
- { "CDOW", 1, 'C' },
- { "CHR", 1, 'C' },
- { "CMONTH", 1, 'C' },
- { "CTOD", 1, 'C' },
- { "DATE", 0, 'C' },
- { "DAY", 1, 'N' },
- { "DESCEND", 1, '1' },
- { "DOW", 1, 'N' },
- { "DTOC", 1, 'C' },
- { "DTOS", 1, 'C' },
- { "EXP", 1, 'N' },
- { "IIF", 3, 'C' },
- { "INT", 1, 'N' },
- { "ISALPHA", 1, 'L' },
- { "ISLOWER", 1, 'L' },
- { "ISUPPER", 1, 'L' },
- { "LEFT", 2, 'C' },
- { "LEN", 1, 'N' },
- { "LOG", 1, 'N' },
- { "LOWER", 1, 'C' },
- { "LTRIM", 1, 'C' },
- { "MAX", 2, 'N' },
- { "MIN", 2, 'N' },
- { "MONTH", 1, 'N' },
- { "RECNO", 0, 'N' },
- { "REPLICATE", 2, 'C' },
- { "RIGHT", 2, 'C' },
- { "RTRIM", 1, 'C' },
- { "SPACE", 1, 'C' },
- { "SQRT", 1, 'N' },
- { "STR", 101, 'C' },
- { "STRZERO", 1, 'C' },
- { "SUBSTR", 3, 'C' },
- { "TRIM", 1, 'C' },
- { "UPPER", 1, 'C' },
- { "VAL", 1, 'N' },
- { "YEAR", 1, 'N' },
- { 0, 0, 0 },
-};
-
-/*************************************************************************/
-//! xbExpn Constructor
-/*!
-*/
-xbExpn::xbExpn( xbXBase * x )
-{
- xbase = x;
- TokenType = 0;
- Tree = 0;
- TokenLen = 0;
- OpLen1 = 0;
- OpLen2 = 0;
- OpDataLen1 = 0;
- OpDataLen2 = 0;
- Op1 = 0;
- Op2 = 0;
- First = 0;
- Last = 0;
- StackDepth = 0;
- XbaseFuncList = FuncList;
- memset( WorkBuf, 0x00, WorkBufMaxLen+1 );
-}
-/*************************************************************************/
-//! xbExpn Destructor
-/*!
-*/
-xbExpn::~xbExpn()
-{
- InitStack();
-
- delete Tree;
-
- if(Op1)
- free(Op1);
-
- if(Op2)
- free(Op2);
-
-}
-
-/*************************************************************************/
-//! Get information on a function.
-/*!
- Returns the information specifed (Option) for the specified function.
-
- \param Function name of function to get information about
- \param Option One of the following:
- \htmlonly
- <p>
- <table border=2><tr><th>Option</th><th>Description</th></tr>
- <tr><td>1</td><td>Return minimum number of parms</td></tr>
- <tr><td>2</td><td>Return function result type</td></tr>
- <tr><td>?</td><td>Return 0 if valid function</td></tr>
- </table>
- \endhtmlonly
- \latexonly
- \\
- \\
- \begin{tabular}{|l|l|} \hline
- \textbf{Option} & \textbf{Description} \\ \hline \hline
- 1 & Return minimum number of parms \\ \hline
- 2 & Return function result type \\ \hline
- ? & Return 0 if valid function \\ \hline
- \end{tabular}
- \endlatexonly
-
- \returns requested information or -1 on failure.
-*/
-xbShort xbExpn::GetFuncInfo( const char * Function, xbShort Option )
-{
-/* Option =
- 1 - return minimum number of needed parms
- 2 - return function result type
- ? - return 0 if valid function
-*/
- xbFuncDtl * f;
- xbShort i, len;
- const char *s;
-
- if(( Option<1 )||( Option>2 ))
- return XB_INVALID_OPTION;
-
- s = Function;
- len = 0;
- while( *s && *s != '(' ) { s++; len++; }
-
- f = XbaseFuncList;
- i = 0;
- while( f[i].FuncName ){
- if( strncmp( f[i].FuncName, Function, len ) == 0 )
- return( (Option==1) ? f[i].ParmCnt : f[i].ReturnType );
- i++;
- }
- return -1;
-}
-
-/*************************************************************************/
-//! IsWhiteSpace
-/*!
-*/
-xbShort xbExpn::IsWhiteSpace( char c )
-{
- return(( c == 0x20 )? 1 : 0 );
-}
-
-/*************************************************************************/
-//! GetNextToken
-/*!
-*/
-xbShort xbExpn::GetNextToken( const char * s, xbShort MaxLen )
-{
- /* TreeResultType Settings
- Token Action/
- Was Type Result
- Unv N N
- Unv C C
- Unv Function Table Lookup
- Unv Field Field Type
- Not L Any Logical L
- */
-
- xbShort Wctr, Wtype, Wsw, EmptyCtr, MaxCtr, MaxCtrSave;
- const char *sp, *np, *pp; /* save, next and previous pointer */
-
- LogicalType = 0;
- TokenType = 0;
- TokenLen = 0;
- EmptyCtr = 0;
- MaxCtr = 0;
-
- if( !s || ! *s )
- return XB_NO_DATA;
-
- /* go past any initial white space */
- while( s && *s && IsWhiteSpace( *s )){
- s++;
- MaxCtr++;
- if (MaxCtr >= MaxLen)
- return XB_NO_ERROR;
- }
-
-/* 1 - check for parens */
-/* '(', if found go to corresponding ')', if no ')', return -1 */
- if( *s == '(' || *s == '{' ){
- if( *s == '{' ) Wtype = 0; else Wtype = 1;
- Wctr = 1;
- s++;
-
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
-
- while( s && *s ){
- if(( *s == ')' && Wtype == 1 ) || (*s == '}' && Wtype == 0 )){
- Wctr--;
- if( Wctr == 0 ){
- if( EmptyCtr != 0 ) {
- TokenType = 'E';
- PreviousType = 'E';
- } else
- return XB_PARSE_ERROR;
-
- TokenLen += 2;
- return XB_NO_ERROR;
- }
- }
- else if(( *s == '(' && Wtype == 1 ) || (*s == '{' && Wtype == 0 )){
- Wctr++;
- EmptyCtr++;
- } else if( *s != ' ' )
- EmptyCtr++;
-
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
- }
- return XB_PARSE_ERROR;
- }
-
-
-/* 2 - Check for Constants */
-/* check for "'" or """, if no corresponding quote return -1 */
- if( *s == '"' || *s == '\'' ){
- if( *s == '"' ) Wtype = 0; else Wtype = 1;
- TokenType = 'C'; /* set to constant */
- PreviousType = 'C';
- s++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_NO_ERROR;
- while( s && *s ){
- if(( *s == '"' && Wtype == 0 ) || (*s == '\'' && Wtype == 1 ))
- return XB_NO_ERROR;
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_NO_ERROR;
- }
- return XB_PARSE_ERROR;
- }
-
-
-/* 3 - check for .T. .F. .TRUE. or .FALSE. */
- if( s && *s && *s == '.' ){
- if(( strncmp( s, ".T.", 3 ) == 0 ) || ( strncmp( s, ".F.", 3 ) == 0 )){
- TokenLen = 3;
- TokenType = 'C'; /* constant */
- PreviousType = 'C';
- LogicalType = 1;
- return XB_NO_ERROR;
- } else if( strncmp( s, ".TRUE.", 6 ) == 0 ){
- TokenLen = 6;
- TokenType = 'C'; /* constant */
- PreviousType = 'C';
- LogicalType = 1;
- return XB_NO_ERROR;
- } else if( strncmp( s, ".FALSE.", 7 ) == 0 ){
- TokenLen = 7;
- TokenType = 'C'; /* constant */
- PreviousType = 'C';
- LogicalType = 1;
- return XB_NO_ERROR;
- }
- }
-
-/* 4 - check for positive, negative or decimal number constants */
- if(( *s == '-' && ( PreviousType == 'O' || PreviousType == 0 )) ||
- ( *s == '+' && ( PreviousType == 'O' || PreviousType == 0 )) ||
- *s == '.' || isdigit( *s )){
- sp = s;
- MaxCtrSave = MaxCtr;
- Wsw = Wctr = 0;
- if( *s == '.' ){
- Wctr++;
- s++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
-
- if( s && *s && isdigit( *s ))
- TokenLen++;
- else
- Wsw++;
- } else if( *s == '-' ){
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
-
- /* go past any white space between sign and number */
- while( s && *s && IsWhiteSpace( *s )){
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
- }
- }
-
- if( isdigit( *s ) || (*s == '.' && !Wsw )){
- while(s && *s && ((*s == '.' && Wctr < 2 ) || isdigit(*s)) && !Wsw ){
- if( *s == '.' ) {
- Wctr++;
- if( Wctr > 1 ) break;
- s++;
-
- MaxCtr++;
- if( MaxCtr >= MaxLen ){
- TokenType = 'N';
- PreviousType = 'N';
- return XB_NO_ERROR;
- }
-
- if( s && *s && isdigit( *s ))
- TokenLen++;
- else
- Wsw++;
- } else {
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen ) {
- TokenType = 'N';
- PreviousType = 'N';
- return XB_NO_ERROR;
- }
- }
- }
- TokenType = 'N'; /* constant */
- PreviousType = 'N';
- return XB_NO_ERROR;
- } else {
- s = sp;
- MaxCtr = MaxCtrSave;
- }
- }
-
-/* 5 - Check for operators */
- if( *s == '+' || *s == '-' || *s == '/' || *s == '^'){
- TokenLen = 1;
- TokenType = 'O';
- PreviousType = 'O';
- return XB_NO_ERROR;
- }
- if(*s == '=' || *s == '$' || *s == '#' ){
- LogicalType = 1;
- TokenLen = 1;
- TokenType = 'O';
- PreviousType = 'O';
- return XB_NO_ERROR;
- }
- if( strncmp( s, "!=", 2 ) == 0 ){
- LogicalType = 1;
- TokenLen = 2;
- TokenType = 'O';
- PreviousType = 'O';
- return XB_NO_ERROR;
- }
- if( *s == '*' ){
- s++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
-
- TokenType = 'O';
- PreviousType = 'O';
- if( *s == '*' ){
- TokenLen = 2;
- return XB_NO_ERROR;
- } else {
- TokenLen = 1;
- return XB_NO_ERROR;
- }
- }
- if( *s == '<' || *s == '>' ) {
- s++;
-
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
-
- LogicalType = 1; // added 3/25/00 dtb
- TokenType = 'O';
- PreviousType = 'O';
- if( *s == '<' || *s == '>' || *s == '=' ){
- TokenLen = 2;
- return XB_NO_ERROR;
- } else {
- TokenLen = 1;
- return XB_NO_ERROR;
- }
- }
-
-/* check for .NOT. .OR. .AND. */
-
- if( s && *s && *s == '.' ){
- if( strncmp( s, ".NOT.", 5 ) == 0 ){
- TokenLen = 5;
- TokenType = 'O'; /* constant */
- PreviousType = 'O';
- LogicalType = 1;
- return XB_NO_ERROR;
- } else if( strncmp( s, ".AND.", 5 ) == 0 ){
- TokenLen = 5;
- TokenType = 'O'; /* constant */
- PreviousType = 'O';
- LogicalType = 1;
- return XB_NO_ERROR;
- } else if( strncmp( s, ".OR.", 4 ) == 0 ){
- TokenLen = 4;
- TokenType = 'O'; /* constant */
- PreviousType = 'O';
- LogicalType = 1;
- return XB_NO_ERROR;
- }
- }
-
- /* If get this far, must be function or database field */
- while( s && *s ){
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen ) {
- TokenType = 'D';
- PreviousType = 'D';
- return XB_NO_ERROR;
- }
-
- if( s && *s && *s == '(' ) {
- /* look for corresponding ) */
- Wctr = 1;
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
-
- while( s && *s ) {
- if( *s == ')' ) {
- Wctr--;
- if( !Wctr ) {
- TokenType = 'F'; /* function */
- PreviousType = 'F';
- TokenLen++;
- return XB_NO_ERROR;
- }
- }
- if( *s == '(' ) Wctr++;
- s++;
- TokenLen++;
- MaxCtr++;
- if( MaxCtr >= MaxLen )
- return XB_PARSE_ERROR;
- }
- return XB_PARSE_ERROR;
- } else {
- np = s + 1;
- pp = s - 1;
- if( !s || !*s || (IsSeparator( *s ) &&
- !(*s == '-' && *np == '>' ) && !(*s == '>' && *pp == '-' ))) {
- if( TokenLen > 0 ){
- TokenType = 'D'; /* database field */
- PreviousType = 'D';
- return XB_NO_ERROR;
- }
- }
- }
- }
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! IsSeparator
-/*!
-*/
-char xbExpn::IsSeparator( char c )
-{
- if( c == '-' || c == '+' || c == '*' || c == '/' || c == '$' ||
- c == ' ' || c == '#' || c == '<' || c == '>' || c == '^' ||
- c == '=' || c == '.' || c == '!' /* || c == ')' */ )
- return c;
- else
- return 0;
-}
-
-/*************************************************************************/
-//! GetExpNode
-/*!
-*/
-/*
-xbExpNode * xbExpn::GetExpNode(xbShort Len) {
- xbExpNode * Temp;
-
- Temp = new xbExpNode;
- if( Temp && Len > 0 )
- Temp->ResultLen = Len;
- return Temp;
-}
-*/
-/*************************************************************************/
-//! LoadExpNode
-/*!
-*/
-xbExpNode * xbExpn::LoadExpNode(
- const char *ENodeText, /* pointer to text data */
- const char EType, /* Operand type */
- const xbShort ELen, /* length of node text data */
- const xbShort BufLen ) /* length needed in the buffer*/
-{
-// xbExpNode * CurNode;
-// if(( CurNode = GetExpNode(BufLen)) == NULL ) return NULL;
-
- xbExpNode * CurNode = new xbExpNode;
- if( !CurNode )
- return NULL;
- CurNode->ResultLen = BufLen;
-
- CurNode->NodeText = strdup( ENodeText );
- CurNode->Type = EType;
- CurNode->Len = ELen;
- CurNode->InTree = 1;
- CurNode->ResultLen = BufLen;
- return CurNode;
-}
-
-/*************************************************************************/
-//! BuildExpressionTree
-/*!
-*/
-xbShort xbExpn::BuildExpressionTree( const char * Expression,
- xbShort MaxTokenLen, xbDbf * d )
-{
- /* previous node is the node to insert under */
- xbExpNode * CurNode = 0;
- xbExpNode * PreviousNode;
- xbShort rc, FieldNo=0, BufLen;
- xbShort TokenLenCtr;
- char c;
- const char *p;
- char TempField[11];
- char TableName[31];
- xbDbf * TempDbf=0;
- int LocTokenLen;
-
- if( Tree ) {
- delete Tree;
- Tree = NULL;
- }
-
- p = Expression;
- PreviousNode = NULL;
- PreviousType = TokenLenCtr = 0;
-
- while( IsWhiteSpace( *p )) {
- p++;
- TokenLenCtr++;
- if(TokenLenCtr >= MaxTokenLen)
- return XB_NO_ERROR;
- }
-
- rc = GetNextToken( p, MaxTokenLen-TokenLenCtr );
- LocTokenLen = TokenLen;
- if( rc != XB_NO_DATA && rc != XB_NO_ERROR )
- return rc;
-
- while( rc == 0 ){
- if( TokenType == 'D' && d ){
- if( TokenLen > 30 )
- strncpy( TableName, p, 30 );
- else
- strncpy( TableName, p, TokenLen );
-
- memset( TempField, 0x00, 11 );
-
- if( strstr( p, "->" ) != NULL ) {
- if(( TempDbf = d->xbase->GetDbfPtr( TableName )) == NULL )
- return XB_INVALID_FIELD;
- xbShort tlen = 0;
- while( TableName[tlen] != '-' && TableName[tlen+1] != '>' )
- tlen++;
- tlen = TokenLen - tlen - 2; // length of field name
- const char * fp = strstr( p, "->" );
- fp += 2; // ptr to beginning of field name
- strncpy( TempField, fp, tlen );
- } else {
- TempDbf = d;
- if( TokenLen > 10 )
- return XB_INVALID_FIELD;
- strncpy( TempField, p, TokenLen );
- }
- if(( FieldNo = TempDbf->GetFieldNo( TempField )) == -1 )
- return XB_INVALID_FIELD;
- BufLen = TempDbf->GetFieldLen( FieldNo ) + 1;
- }
- else if( TokenType == 'C' || TokenType == 'N' )
- BufLen = TokenLen + 1;
- else
- BufLen = 0;
-
- if( TokenType == 'C' ) p++; /* go past first ' */
-
- if( TokenType != 'O' ){
- if( !Tree ) { /* create root node with this token */
- CurNode = LoadExpNode( p, TokenType, TokenLen, BufLen );
- Tree = CurNode;
- } else { /* put as child 2 of previous node */
- CurNode = LoadExpNode( p, TokenType, TokenLen, BufLen );
- PreviousNode->Sibling2 = CurNode;
- CurNode->Node = PreviousNode;
- }
-
- if( TokenType == 'E' ){
- if((rc=ReduceComplexExpression(p,TokenLen,CurNode,d))!=0)
- return rc;
- if(PreviousNode)
- CurNode = PreviousNode->Sibling2;
- else
- CurNode = Tree;
- } else if( TokenType == 'F' ){
- if(( rc = ReduceFunction( p, CurNode, d)) != 0 )
- return rc;
-
- xbShort parmCnt = GetFuncInfo( p, 1 );
- if( (parmCnt == 1 || parmCnt == 101 ) && !CurNode->Sibling1 ||
- (parmCnt == 2 || parmCnt == 201 ) && !CurNode->Sibling2 ||
- (parmCnt == 3 ) && !CurNode->Sibling3 )
- return XB_INSUFFICIENT_PARMS;
- else if( parmCnt == 0 && CurNode->Sibling1 )
- return XB_TOO_MANY_PARMS;
- else if( parmCnt == 1 && CurNode->Sibling2 )
- return XB_TOO_MANY_PARMS;
- else if( parmCnt == 2 && CurNode->Sibling3 )
- return XB_TOO_MANY_PARMS;
-
- CurNode->ExpressionType = GetFuncInfo( p, 2 );
- if( CurNode->ExpressionType == '1' ){
- if( CurNode->Sibling1 )
- if( CurNode->Sibling1->ExpressionType == 'C' )
- CurNode->ExpressionType = 'C';
- else
- CurNode->ExpressionType = 'N';
- else
- return XB_INSUFFICIENT_PARMS;
- }
-
- CurNode->dbf = d;
- }
- else if( TokenType == 'D' && d ) {
- CurNode->DataLen = BufLen - 1;
- CurNode->FieldNo = FieldNo;
- CurNode->dbf = TempDbf;
- c = TempDbf->GetFieldType( FieldNo );
- if( c == 'C' || c == 'M' ) CurNode->ExpressionType = 'C';
- else if( c == 'L' ) CurNode->ExpressionType = 'L';
- else if( c == 'N' || c == 'F' ) CurNode->ExpressionType = 'N';
- else if( c == 'D' ) CurNode->ExpressionType = 'D';
- } else if( TokenType == 'C' || TokenType == 'N' ) {
- CurNode->DataLen = CurNode->Len;
- CurNode->StringResult = CurNode->NodeText;
- CurNode->StringResult.resize( CurNode->DataLen+1 );
- if( TokenType == 'N' ) {
- CurNode->DoubResult = strtod( CurNode->StringResult, 0 );
- CurNode->ExpressionType = 'N';
- } else
- CurNode->ExpressionType = 'C';
- }
- }
- else /* it is an operator */
- {
- if(!Tree){
- if(*p == '-'){
- CurNode = LoadExpNode( p, TokenType, TokenLen, 0 );
- CurNode->ExpressionType = 'C';
- } else
- return XB_EXP_SYNTAX_ERROR;
- } else {
- if( Tree->Type != 'O' ){
- CurNode = LoadExpNode( p, TokenType, TokenLen, 0 );
- Tree->Node = CurNode; /* link the new parent to old tree */
- CurNode->Sibling1 = Tree; /* connect the sibling */
- Tree = CurNode; /* root in tree */
- } else {
- PreviousNode = CurNode->Node;
- CurNode = LoadExpNode( p, TokenType, TokenLen, 0 );
- while( PreviousNode &&
- (( OperatorWeight( PreviousNode->NodeText, TokenLen ) == 0 ) ||
- ( OperatorWeight( CurNode->NodeText, TokenLen ) <=
- OperatorWeight( PreviousNode->NodeText, TokenLen ))))
- PreviousNode = PreviousNode->Node;
-
- if( PreviousNode ) {
- CurNode->Node = PreviousNode;
- CurNode->Sibling1 = PreviousNode->Sibling2;
- PreviousNode->Sibling2 = CurNode;
- CurNode->Sibling1->Node = CurNode;
- } else { /* insert at root */
- CurNode->Sibling1 = Tree;
- Tree = CurNode;
- CurNode->Sibling1->Node = CurNode;
- }
- }
- if( LogicalType )
- CurNode->ExpressionType = 'L';
- }
- }
- PreviousNode = CurNode;
-// p += CurNode->Len; // 2/20/04 - not sure when this was updated - gk
- p += LocTokenLen;
-
-// if( TokenType == 'C' ) { gk - 2/20/04 func("fff") + 4 didn't work
- if( TokenType == 'C' && CurNode->Type != 'F' ){
- p++; /* go past last ' */
- TokenLenCtr+=2; /* add the quotes */
- }
-
-// TokenLenCtr += CurNode->Len; // 2/20/04 - not sure when this was updated - gk
- TokenLenCtr += LocTokenLen;
- if( TokenLenCtr >= MaxTokenLen )
- return XB_NO_ERROR;
- if( p && *p && TokenType == 'E' ) {
- p++;
- TokenLenCtr++;
- }
-
- while( IsWhiteSpace( *p )) {
- p++;
- TokenLenCtr++;
- if( TokenLenCtr >= MaxTokenLen )
- return XB_NO_ERROR;
- }
- rc = GetNextToken( p, MaxTokenLen-TokenLenCtr );
- LocTokenLen = TokenLen;
- if( rc != XB_NO_DATA && rc != XB_NO_ERROR )
- return rc;
- }
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! GetExpressionResultType
-/*!
-*/
-char xbExpn::GetExpressionResultType( xbExpNode * e ) {
- xbExpNode * Temp = 0;
- if( e )
- Temp = e;
- else if( !Temp )
- Temp = Tree;
- else
- return 0;
-
- if( e->Type == 'O' &&
- ( *e->NodeText == '<' || *e->NodeText == '>' || *e->NodeText == '=' ||
- *e->NodeText == '#' || *e->NodeText == '$' ||
- strncmp( e->NodeText, "!=", 2 ) == 0 ))
- return 'L';
-
- /* go down to second lowest level */
- while( Temp && Temp->Sibling1 && Temp->Sibling1->Sibling1 )
- Temp = Temp->Sibling1;
-
- /* if subtracting dates, return numeric type */
- if( Temp->Type == 'O' && *Temp->NodeText == '-' &&
- Temp->Sibling1 && Temp->Sibling2 &&
- Temp->Sibling1->ExpressionType == 'D' &&
- Temp->Sibling2->ExpressionType == 'D' )
- return 'N';
-
- /* else return the type of the lowest left node */
- while( Temp && !Temp->ExpressionType && Temp->Sibling1 )
- Temp = Temp->Sibling1;
- return Temp->ExpressionType;
-}
-/*************************************************************************/
-//! GetExpressionHandle
-/*!
-*/
-xbExpNode * xbExpn::GetExpressionHandle() {
- xbExpNode * e;
- e = Tree;
- Tree = NULL;
- return e;
-}
-/*************************************************************************/
-//! OperatorWeight
-/*! This function determines the priority of an operator
-*/
-xbShort xbExpn::OperatorWeight( const char * Oper, xbShort len )
-{
- /* operator precendence
-
- not all are implemented yet, but the structure is here
-
- 10 .AND. .OR. .NOT. (not really an operator)
- 9 > or < (includes <= or >=)
- 6 unary plus or minus (+,-)
- 5 prefix increment and/or decrement (++,--)
- 4 exponentiation ** or ^
- 3 multiplication,division or modulus (*,/,%)
- 2 Addition, subtraction (+,-)
- 1 Postfix increment and/or decrement (++,--)
- */
-
- if( len < 1 || len > 5 ) return 0;
-
-
- if( Oper[0] == '>' || Oper[0] == '<' )
- return 13;
-
- if( strncmp( Oper, ".AND.", 5 ) == 0 ||
- strncmp( Oper, ".OR.", 4 ) == 0 ||
- strncmp( Oper, ".NOT.", 5 ))
- return 10;
-
- if( strncmp( Oper, "**", 2 ) == 0 || Oper[0] == '^' )
- return 4;
-
- if( Oper[0] == '*' || Oper[0] == '/' || Oper[0] == '%' )
- return 3;
-
- if( Oper[0] == '+' || Oper[0] == '-' )
- return 1;
-
- return 0;
-}
-/*************************************************************************/
-//! ReduceComplexExpression
-/*!
-*/
-xbShort xbExpn::ReduceComplexExpression(const char *NextToken, xbShort Len,
- xbExpNode *cn, xbDbf *d) {
- const char *p;
- xbShort rc;
- xbExpNode * SaveTree;
-
- SaveTree = Tree;
- Tree = NULL;
-
- p = NextToken;
- p++;
-
- if(( rc = BuildExpressionTree( p, Len-2, d )) != XB_NO_ERROR )
- return rc;
-
- if(cn->Node) { /* then this is the base tree */
- cn->Node->Sibling2 = Tree;
- Tree->Node = cn->Node;
- delete cn;
- Tree = SaveTree;
- } else
- delete cn;
-
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! GetFunctionTokenLen
-/*!
-*/
-xbShort xbExpn::GetFunctionTokenLen( const char * s )
-{
- xbShort cnt, LeftParenCtr;
- const char *p;
-
- cnt = LeftParenCtr = 0;
- p = s;
-
- while( p && ( *p != ',' || ( *p == ',' && LeftParenCtr > 0 )) &&
- !( LeftParenCtr == 0 && *p == ')')) {
- if( *p == '(' )
- LeftParenCtr++;
- else if( *p == ')' )
- LeftParenCtr--;
- p++;
- cnt++;
- }
- return cnt;
-}
-/*************************************************************************/
-//! ReduceFunction
-/*!
-*/
-xbShort xbExpn::ReduceFunction(const char *NextToken, xbExpNode *cn, xbDbf *d)
-{
- const char *p;
- xbShort rc;
- xbShort FuncTokenLen;
- xbExpNode * SaveTree;
-
- p = strchr( NextToken, '(' );
- if (!p)
- return XB_PARSE_ERROR;
-
- p++;
- while( IsWhiteSpace( *p )) p++;
- if (*p == ')')
- return XB_NO_ERROR;
-
- /* do function paramater 1 */
- FuncTokenLen = GetFunctionTokenLen( p );
- SaveTree = Tree;
- Tree = NULL;
- if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR )
- return rc;
- cn->Sibling1 = Tree;
- Tree->Node = cn;
- Tree = SaveTree;
-
- /* do function paramater 2 */
-
- p += FuncTokenLen;
- while( IsWhiteSpace( *p )) p++;
- if(*p == ')')
- return XB_NO_ERROR;
- if( *p != ',' )
- return XB_PARSE_ERROR;
-
- p++;
- while( IsWhiteSpace( *p )) p++;
- FuncTokenLen = GetFunctionTokenLen( p );
- SaveTree = Tree;
- Tree = NULL;
- if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR )
- return rc;
-
- cn->Sibling2 = Tree;
- Tree->Node = cn;
- Tree = SaveTree;
-
- /* do function paramater 3 */
- p += FuncTokenLen;
- while( IsWhiteSpace( *p )) p++;
- if (*p == ')')
- return XB_NO_ERROR;
- if( *p != ',' )
- return XB_PARSE_ERROR;
-
- p++;
- while( IsWhiteSpace( *p )) p++;
- FuncTokenLen = GetFunctionTokenLen( p );
- SaveTree = Tree;
- Tree = NULL;
- if(( rc = BuildExpressionTree( p, FuncTokenLen, d )) != XB_NO_ERROR )
- return rc;
-
- cn->Sibling3 = Tree;
- Tree->Node = cn;
- Tree = SaveTree;
-
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! ParseExpression
-/*!
-*/
-xbShort xbExpn::ParseExpression(const char *exp, xbDbf *d) {
- return BuildExpressionTree(exp, strlen(exp), d);
-}
-/*************************************************************************/
-//! ProcessExpression
-/*!
-*/
-xbShort xbExpn::ProcessExpression(const char *e, xbDbf *d) {
- xbShort rc;
- if(( rc = BuildExpressionTree( e, strlen( e ), d )) != XB_NO_ERROR )
- return rc;
- if(( rc = ProcessExpression( Tree )) != XB_NO_ERROR )
- return rc;
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-#ifdef XBASE_DEBUG
-//! DumpExpressionTree
-/*!
-*/
-void xbExpn::DumpExpressionTree( xbExpNode * E, xbShort printOption )
-{
- if( !E ) E = Tree;
- if( !E ) return;
- DumpExpNode( E, printOption );
-
- if( E->Sibling1 ) DumpExpressionTree( E->Sibling1, printOption );
- if( E->Sibling2 ) DumpExpressionTree( E->Sibling2, printOption );
- if( E->Sibling3 ) DumpExpressionTree( E->Sibling3, printOption );
- return;
-}
-/*************************************************************************/
-//! DumpExpNode
-/*!
-*/
-void xbExpn::DumpExpNode(xbExpNode *e, xbShort printOption)
-{
- xbString ntext;
-
- ntext = e->NodeText;
- ntext.resize( e->Len + 1 );
-
- if( printOption ){
- FILE * dmp;
- if(( dmp = fopen( "xbase64.log", "a" )) == NULL )
- return;
-
- fprintf( dmp, "******* Exp Node *******\n" );
- fprintf( dmp, "Exp Node Address = %x\n", e );
- fprintf( dmp, "Node Text = %s\n", ntext.getData());
- fprintf( dmp, "Type = %c\n", e->Type );
- fprintf( dmp, "Len = %d\n", e->Len );
- fprintf( dmp, "InTree = %d\n", e->InTree );
- fprintf( dmp, "Field No = %d\n", e->FieldNo );
- fprintf( dmp, "ExpressionType = %c\n", e->ExpressionType );
- fprintf( dmp, "StringResult = %s\n", e->StringResult.getData());
- fprintf( dmp, "DoubResult = %d\n", e->DoubResult );
- fprintf( dmp, "IntResult = %d\n", e->IntResult );
- fprintf( dmp, "ResultLen = %d\n", e->ResultLen );
- fprintf( dmp, "DataLen = %x\n", e->DataLen );
-
- if( e->Node )
- fprintf( dmp, "Parent = %x\n", e->Node );
- if( e->Sibling1 )
- fprintf( dmp, "Sibling 1 = %x\n", e->Sibling1 );
- if( e->Sibling2 )
- fprintf( dmp, "Sibling 2 = %x\n", e->Sibling2 );
- if( e->Sibling3 )
- fprintf( dmp, "Sibling 3 = %x\n", e->Sibling3 );
- fprintf( dmp, "\n" );
- fclose( dmp );
- }
- else
- {
- std::cout << "****** Exp Node ******";
- std::cout << "Exp Node Address = " << e << std::endl;
- std::cout << "Node Text = " << ntext << std::endl;
- std::cout << "Type = " << e->Type << std::endl;
- std::cout << "Len = " << e->Len << std::endl;
- std::cout << "InTree = " << e->InTree << std::endl;
- std::cout << "Field No = " << e->FieldNo << std::endl;
- std::cout << "ExpressionType = " << e->ExpressionType << std::endl;
- std::cout << "StringResult = " << e->StringResult << std::endl;
- std::cout << "DoubResult = " << e->DoubResult << std::endl;
- std::cout << "IntResult = " << e->IntResult << std::endl;
- std::cout << "ResultLen = " << e->ResultLen << std::endl;
- std::cout << "DataLen = " << e->DataLen << std::endl;
- if( e->Node )
- std::cout << "Parent = " << e->Node << std::endl;
- if( e->Sibling1 )
- std::cout << "Sibling 1 = " << e->Sibling1 << std::endl;
- if( e->Sibling2 )
- std::cout << "Sibling 2 = " << e->Sibling2 << std::endl;
- if( e->Sibling3 )
- std::cout << "Sibling3 = " << e->Sibling3 << std::endl;
- }
- return;
-}
-#endif
-
-/*************************************************************************/
-//! xbExpNode()
-/*!
-*/
-xbExpNode::xbExpNode() :
- NodeText(0),
- Type(0),
- Len(0),
- InTree(0),
- Node(0),
- Sibling1(0),
- Sibling2(0),
- Sibling3(0),
- DataLen(0),
- ResultLen(0),
- DoubResult(0),
- IntResult(0),
- dbf(0),
- FieldNo(-1),
- ExpressionType(0)
-{
-}
-/*************************************************************************/
-//! ~xbExpNode()
-/*!
-*/
-xbExpNode::~xbExpNode()
-{
- if(NodeText)
- free(NodeText);
-
- if(Sibling1)
- delete Sibling1;
-
- if(Sibling2)
- delete Sibling2;
-
- if(Sibling3)
- delete Sibling3;
-}
-/*************************************************************************/
-//! Constructor.
-/*!
-*/
-xbStackElement::xbStackElement()
-{
- Next = 0;
- Previous = 0;
- NodePtr = 0;
-}
-/*************************************************************************/
-//! Destructor.
-/*!
-*/
-xbStackElement::~xbStackElement()
-{
-}
-/*************************************************************************/
-
-//! Destructor.
-/*!
-*/
-
-/*************************************************************************/
-//! Short description.
-/*!
-*/
-void xbExpn::InitStack()
-{
- xbStackElement *next;
-
- while(First){
- next = First->Next;
-
- if( First->NodePtr->InTree == 0 )
- delete First->NodePtr;
-
- delete First;
- First = next;
- }
-
- Last = 0;
- StackDepth = 0;
- return;
-}
-/*************************************************************************/
-//! Push a value onto the stack.
-/*!
- \param p
-*/
-xbShort xbExpn::Push( xbExpNode *p )
-{
- xbStackElement *Temp = new xbStackElement;
-
- if(!Temp)
- return XB_NO_MEMORY;
-
- Temp->NodePtr = p;
-
- if( !First ){
- First = Temp;
- Last = Temp;
- StackDepth = 1;
- } else {
- Last->Next = Temp;
- Temp->Previous = Last;
- Last = Temp;
- StackDepth++;
- }
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! Pop the top value from the stack.
-/*!
-*/
-xbExpNode * xbExpn::Pop()
-{
- xbExpNode *p;
- xbStackElement *Save;
-
- if( StackDepth == 0 )
- return 0;
- else {
- p = Last->NodePtr;
- if( StackDepth == 1 ){
- delete First;
- First = 0;
- Last = 0;
- } else { /* number of items in Stack must be > 1 */
- Last->Previous->Next = 0;
- Save = Last;
- Last = Last->Previous;
- delete Save;
- }
- StackDepth--;
- return p;
- }
-}
-/*************************************************************************/
-//! Short description.
-/*!
-*/
-#ifdef XBASE_DEBUG
-void xbExpn::DumpStack()
-{
- xbStackElement * e;
- if( StackDepth == 0 ){
- std::cout << "\nStack is empty...";
- return;
- }
-
- std::cout << "\nThere are " << StackDepth << " entries.";
- std::cout << "\nFirst = " << First << " Last = " << Last;
-
- e = First;
- while( e ){
- std::cout << "\n*****************************";
- std::cout << "\nThis = " << e;
- std::cout << "\nNext = " << e->Next;
- std::cout << "\nPrevious = " << e->Previous;
- std::cout << "\nNode Ptr = " << e->NodePtr;
- e = e->Next;
- }
- return;
-}
-#endif // XB_EXPRESSIONS
-#endif
-/*************************************************************************/
diff --git a/xbase64/xbexp.h b/xbase64/xbexp.h
deleted file mode 100755
index ec769a9..0000000
--- a/xbase64/xbexp.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/* xbexp.h
-
- Xbase64 project source code
-
- This file contains a header file for the EXP object, which is
- used for expression processing.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XB_EXP_H__
-#define __XB_EXP_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#include <xbase64/xbase64.h>
-
-#ifdef XB_EXPRESSIONS /* compile if expression logic on */
-#include <xbase64/xbtypes.h>
-
-/*! \file xbexp.h
-*/
-
-#undef ABS
-#undef MIN
-#undef MAX
-
-class XBDLLEXPORT xbDbf;
-
-/************************************************************************/
-//! xbFuncDtl struct
-/*! This structure defines function information
-*/
-
-struct XBDLLEXPORT xbFuncDtl {
- const char * FuncName; /* function name */
- xbShort ParmCnt; /* no of parms it needs */
- char ReturnType; /* return type of function */
- void (*ExpFuncPtr)(); /* pointer to function routine */
-};
-
-/************************************************************************/
-//! xbExpNode struct
-/*! This class defines a node within a tree of nodes, each token
- in an expression gets placed onto its own node
-*/
-
-class XBDLLEXPORT xbExpNode {
- public:
- xbExpNode();
- virtual ~xbExpNode();
-
- public:
- char * NodeText; /* expression text */
- char Type; /* same as TokenType below */
- xbShort Len; /* length of expression text */
- xbShort InTree; /* this node in the tree? 1=yes */
- xbExpNode * Node; /* pointer to parent */
- xbExpNode * Sibling1; /* pointer to sibling 1 */
- xbExpNode * Sibling2; /* pointer to sibling 2 */
- xbExpNode * Sibling3; /* pointe/r to sibling 3 */
- xbShort DataLen; /* length of data in result buffer */
- xbShort ResultLen; /* length of result buffer */
- xbString StringResult; /* string result */
- xbDouble DoubResult; /* Numeric Result */
- xbShort IntResult; /* logical result */
- xbDbf * dbf; /* pointer to datafile */
- xbShort FieldNo; /* field no if DBF field */
- char ExpressionType; /* used in head node C,N,L or D */
-};
-/************************************************************************/
-//! xbStackElement class
-/*!
-*/
-
-class XBDLLEXPORT xbStackElement
-{
- public:
- xbStackElement();
- ~xbStackElement();
-
- friend class xbExpn;
-
- private:
- xbStackElement *Previous;
- xbStackElement *Next;
- xbExpNode *NodePtr;
-};
-/************************************************************************/
-//! xbExpn class
-/*! This class is used for processing expressions
-*/
-
-/* Expression handler */
-
-class XBDLLEXPORT xbExpn{
- public:
- xbExpn( xbXBase * );
- virtual ~xbExpn();
-
- xbShort GetNextToken( const char *s, xbShort MaxLen );
- xbShort ProcessExpression( xbExpNode *n, xbShort );
- xbShort ProcessExpression( xbShort opt )
- { return ProcessExpression( Tree, opt ); }
-
- xbExpNode * GetTree() { return Tree; }
- void SetTreeToNull() { Tree = NULL; }
- xbExpNode * GetFirstTreeNode( xbExpNode * );
- xbExpNode * GetFirstTreeNode()
- { return GetFirstTreeNode( Tree ); }
- xbShort ProcessExpression( const char *exp, xbDbf * d );
- xbShort ParseExpression( const char *exp, xbDbf * d );
- xbExpNode * GetExpressionHandle();
- char GetExpressionResultType( xbExpNode * );
- char GetExpressionResultType()
- { return GetExpressionResultType( Tree ); }
- char * GetCharResult();
- xbString & GetStringResult();
- xbDouble GetDoubleResult();
- xbLong GetIntResult();
- xbShort ProcessExpression( xbExpNode * );
- xbShort ProcessExpression() { return ProcessExpression( Tree ); }
- xbShort BuildExpressionTree( const char * Expression, xbShort MaxTokenLen,
- xbDbf *d );
-
- /* stack functions */
- void InitStack();
- xbExpNode * Pop();
- xbShort Push(xbExpNode *);
- xbShort GetStackDepth() { return StackDepth; }
- void DumpStack();
- const char * GetValidFuncName( xbShort funcNo )
- { return XbaseFuncList[funcNo].FuncName; }
-
-#ifdef XBASE_DEBUG
- void DumpExpressionTree( xbShort printOption )
- { DumpExpressionTree( Tree, printOption ); }
- void DumpExpressionTree( xbExpNode *, xbShort printOption );
- void DumpExpNode( xbExpNode *, xbShort printOption );
-#endif
-
- /* expression methods */
- xbDouble ABS( xbDouble );
- xbLong ASC( const char * );
- xbLong AT( const char *, const char * );
- char * CDOW( const char * );
- char * CHR( xbLong );
- char * CMONTH( const char * );
- char * CTOD( const char * );
- char * DATE();
- xbLong DAY( const char * );
- char * DESCEND( const char * );
- xbLong DESCEND( const xbDate & );
- xbDouble DESCEND( xbDouble );
- xbLong DOW( const char * );
- char * DTOC( const char * );
- char * DTOS( const char * );
- xbDouble EXP( xbDouble );
- char * IIF( xbShort, const char *, const char * );
- xbLong INT( xbDouble );
- xbLong ISALPHA( const char * );
- xbLong ISLOWER( const char * );
- xbLong ISUPPER( const char * );
- char * LEFT( const char *, xbShort );
- xbLong LEN( const char * );
- xbDouble LOG( xbDouble );
- char * LOWER( const char * );
- char * LTRIM( const char * );
- xbDouble MAX( xbDouble, xbDouble );
- xbLong MONTH( const char * ); /* MONTH() */
- xbDouble MIN( xbDouble, xbDouble );
- xbLong RECNO( xbDbf * );
- char * REPLICATE( const char *, xbShort );
- char * RIGHT( const char *, xbShort );
- char * RTRIM( const char * );
- char * SPACE( xbShort );
- xbDouble SQRT( xbDouble );
- char * STR( const char * );
- char * STR( const char *, xbShort );
- char * STR( const char *, xbShort, xbShort );
- char * STR( xbDouble );
- char * STR( xbDouble, xbShort );
- char * STR(xbDouble, xbUShort length, xbShort numDecimals );
- char * STRZERO( const char * );
- char * STRZERO( const char *, xbShort );
- char * STRZERO( const char *, xbShort, xbShort );
- char * STRZERO( xbDouble );
- char * STRZERO( xbDouble, xbShort );
- char * STRZERO( xbDouble, xbShort, xbShort );
- char * SUBSTR( const char *, xbShort, xbShort );
- char * TRIM( const char * );
- char * UPPER( const char * );
- xbLong VAL( const char * );
- xbLong YEAR( const char * );
-
- protected:
- xbShort IsWhiteSpace( char );
- char IsSeparator( char );
- xbExpNode * LoadExpNode( const char * ENodeText, const char EType,
- const xbShort ELen, const xbShort BufLen );
- xbShort OperatorWeight( const char *Oper, xbShort len );
- xbShort ReduceComplexExpression( const char * NextToken, xbShort Len,
- xbExpNode * cn, xbDbf *d );
- xbShort GetFunctionTokenLen( const char *s );
- xbShort ReduceFunction( const char *NextToken, xbExpNode *cn, xbDbf *d );
- xbExpNode * GetNextTreeNode( xbExpNode * );
- xbShort ProcessOperator( xbShort );
- xbShort ProcessFunction( char * );
- xbShort ValidOperation( char *, char, char );
- char GetOperandType( xbExpNode * );
- xbShort AlphaOperation( char * );
- xbShort NumericOperation( char * );
- xbShort GetFuncInfo( const char *Function, xbShort Option );
- xbDouble GetDoub( xbExpNode * );
- xbLong GetInt( xbExpNode * );
-
- private:
- xbXBase *xbase;
- xbFuncDtl *XbaseFuncList; /* pointer to list of Xbase functions */
- xbExpNode *Tree; /* pointer to tree of parsed nodes */
- xbShort LogicalType; /* set to 1 for logical type nodes */
- char TokenType; /* E - Expression, not in simplest form */
- /* C - Constant */
- /* N - Numeric Constant */
- /* O - Operator */
- /* F - Function */
- /* D - Database Field */
- /* s - character string result */
- /* l - logical or short int result */
- /* d - double result */
- char PreviousType; /* used to see if "-" follows operator */
- char * Op1; /* pointer to operand 1 */
- char * Op2; /* pointer to operand 2 */
- xbDouble Opd1; /* double result 1 */
- xbDouble Opd2; /* double result 2 */
- xbShort OpLen1; /* length of memory allocated to operand 1 */
- xbShort OpLen2; /* length of memory allocated to operand 2 */
- xbShort OpDataLen1; /* length of data in op1 */
- xbShort OpDataLen2; /* length of data in op2 */
- char OpType1; /* type of operand 1 */
- char OpType2; /* type of operand 2 */
- xbShort TokenLen; /* length of token */
-
-// static xbString DefaultDateFormat; /*default date format for DTOC func*/
- enum { WorkBufMaxLen = 200 };
- char WorkBuf[WorkBufMaxLen+1];
-
- /* stack variables */
- xbShort StackDepth;
- xbStackElement *First;
- xbStackElement *Last;
-};
-
-#endif // XB_EXPRESSIONS
-#endif // __XB_EXP_H__
-
-
diff --git a/xbase64/xbexpfnc.cpp b/xbase64/xbexpfnc.cpp
deleted file mode 100755
index 91b6074..0000000
--- a/xbase64/xbexpfnc.cpp
+++ /dev/null
@@ -1,1092 +0,0 @@
-/* xbexpfnc.cpp
-
- Xbase64 project source code
-
- This file contains logic for handling Xbase expressions.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-#ifdef XB_EXPRESSIONS
-
-#include <ctype.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <xbase64/xbexp.h>
-//#include <xbase64/xbexcept.h>
-
-
-/*! \file xbexpfnc.cpp
-*/
-
-/*************************************************************************/
-//! Short description.
-/*!
- \param Func
-*/
-xbShort xbExpn::ProcessFunction( char * Func )
-{
-/* 1 - pop function from stack
- 2 - verify function name and get no of parms needed
- 3 - verify no of parms >= remainder of stack
- 4 - pop parms off stack
- 5 - execute function
- 6 - push result back on stack
-*/
-
-
- char *buf = 0;
- xbExpNode *p1, *p2, *p3, *WorkNode, *FuncNode;
- xbShort ParmsNeeded,len;
- char ptype = 0; /* process type s=string, l=logical, d=double */
- xbDouble DoubResult = 0;
- xbLong IntResult = 0;
- FuncNode = (xbExpNode *) Pop();
-
- ParmsNeeded = GetFuncInfo( Func, 1 );
-
- if( ParmsNeeded == -1 ) {
- return XB_INVALID_FUNCTION;
- }
- else {
- ParmsNeeded = 0;
- if( FuncNode->Sibling1 ) ParmsNeeded++;
- if( FuncNode->Sibling2 ) ParmsNeeded++;
- if( FuncNode->Sibling3 ) ParmsNeeded++;
- }
-
- if( ParmsNeeded > GetStackDepth())
- return XB_INSUFFICIENT_PARMS;
-
- p1 = p2 = p3 = NULL;
- if( ParmsNeeded > 2 ) p3 = (xbExpNode *) Pop();
- if( ParmsNeeded > 1 ) p2 = (xbExpNode *) Pop();
- if( ParmsNeeded > 0 ) p1 = (xbExpNode *) Pop();
- memset( WorkBuf, 0x00, WorkBufMaxLen+1);
-
- if( strncmp( Func, "ABS", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = ABS( GetDoub( p1 ));
- }
- else if( strncmp( Func, "ASC", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = ASC( p1->StringResult );
- }
- else if( strncmp( Func, "AT", 2 ) == 0 ) {
- ptype = 'd';
- DoubResult = AT( p1->StringResult, p2->StringResult );
- }
- else if( strncmp( Func, "CDOW", 4 ) == 0 ) {
- ptype = 's';
- buf = CDOW( p1->StringResult );
- }
- else if( strncmp( Func, "CHR", 3 ) == 0 ) {
- ptype = 's';
- buf = CHR( GetInt( p1 ));
- }
- else if( strncmp( Func, "CMONTH", 6 ) == 0 ) {
- ptype = 's';
- buf = CMONTH( p1->StringResult );
- }
- else if( strncmp( Func, "CTOD", 4 ) == 0 ) {
- ptype = 's';
- buf = CTOD( p1->StringResult );
- }
- else if( strncmp( Func, "DATE", 4 ) == 0 ) {
- ptype = 's';
- buf = DATE();
- }
- else if( strncmp( Func, "DAY", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = DAY( p1->StringResult );
- }
- else if( strncmp( Func, "DESCEND", 7 ) == 0 && p1->ExpressionType == 'C' ) {
- ptype = 's';
- buf = DESCEND( p1->StringResult.c_str() );
- }
- else if( strncmp( Func, "DESCEND", 7 ) == 0 && p1->ExpressionType == 'N' ) {
- ptype = 'd';
- DoubResult = DESCEND( GetDoub( p1 ));
- }
- else if( strncmp( Func, "DESCEND", 7 ) == 0 && p1->ExpressionType == 'D' ) {
- xbDate d( p1->StringResult );
- ptype = 'd';
- DoubResult = DESCEND( d );
- }
- else if( strncmp( Func, "DOW", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = DOW( p1->StringResult );
- }
- else if( strncmp( Func, "DTOC", 4 ) == 0 ) {
- ptype = 's';
- buf = DTOC( p1->StringResult );
- }
- else if( strncmp( Func, "DTOS", 4 ) == 0 ) {
- ptype = 's';
- buf = DTOS( p1->StringResult );
- }
- else if( strncmp( Func, "EXP", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = EXP( GetDoub( p1 ));
- }
- else if( strncmp( Func, "IIF", 3 ) == 0 ){
- ptype = 's';
- buf = IIF( p1->IntResult, p2->StringResult, p3->StringResult );
- }
- else if( strncmp( Func, "INT", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = INT( GetDoub( p1 ));
- }
- else if( strncmp( Func, "ISALPHA", 7 ) == 0 ) {
- ptype = 'l';
- IntResult = ISALPHA( p1->StringResult );
- }
- else if( strncmp( Func, "ISLOWER", 7 ) == 0 ) {
- ptype = 'l';
- IntResult = ISLOWER( p1->StringResult );
- }
- else if( strncmp( Func, "ISUPPER", 7 ) == 0 ) {
- ptype = 'l';
- IntResult = ISUPPER( p1->StringResult );
- }
- else if( strncmp( Func, "LEN", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = LEN( p1->StringResult );
- }
- else if( strncmp( Func, "LEFT", 4 ) == 0 ) {
- ptype = 's';
- buf = LEFT( p1->StringResult, INT( p2->DoubResult ));
- }
- else if( strncmp( Func, "LTRIM", 5 ) == 0 ) {
- ptype = 's';
- buf = LTRIM( p1->StringResult );
- }
- else if( strncmp( Func, "LOG", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = LOG( GetDoub( p1 ));
- }
- else if( strncmp( Func, "LOWER", 5 ) == 0 ) {
- ptype = 's';
- buf = LOWER( p1->StringResult );
- }
- else if( strncmp( Func, "MAX", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = MAX( GetDoub( p1 ), GetDoub( p2 ));
- }
- else if( strncmp( Func, "MIN", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = MIN( GetDoub( p1 ), GetDoub( p2 ));
- }
- else if( strncmp( Func, "MONTH", 5 ) == 0 ) {
- ptype = 'd';
- DoubResult = MONTH( p1->StringResult );
- }
-
- else if( strncmp( Func, "RECNO", 5 ) == 0 )
- {
- ptype = 'd';
- DoubResult = RECNO( FuncNode->dbf );
- }
-
- else if( strncmp( Func, "REPLICATE", 9 ) == 0 ) {
- ptype = 's';
- buf = REPLICATE( p1->StringResult, GetInt( p2 ));
- }
- else if( strncmp( Func, "RIGHT", 5 ) == 0 ) {
- ptype = 's';
- buf = RIGHT( p1->StringResult, GetInt( p2 ));
- }
- else if( strncmp( Func, "RTRIM", 5 ) == 0 ) {
- ptype = 's';
- buf = RTRIM( p1->StringResult );
- }
- else if( strncmp( Func, "SPACE", 5 ) == 0 ) {
- ptype = 's';
- buf = SPACE( INT( GetDoub( p1 )));
- }
- else if( strncmp( Func, "SQRT", 4 ) == 0 ) {
- ptype = 'd';
- DoubResult = SQRT( GetDoub( p1 ));
- }
- else if( strncmp( Func, "STRZERO", 7 ) == 0 && ParmsNeeded == 1 ) {
- ptype = 's';
- buf = STRZERO( p1->StringResult );
- }
- else if( strncmp( Func, "STRZERO", 7 ) == 0 && ParmsNeeded == 2 ) {
- ptype = 's';
- buf = STRZERO( p1->StringResult, GetInt( p2 ));
- }
- else if( strncmp( Func, "STRZERO", 7 ) == 0 && ParmsNeeded == 3 ) {
- ptype = 's';
- buf = STRZERO( p1->StringResult, GetInt( p2 ), GetInt( p3 ));
- }
-
- else if( strncmp( Func, "STR", 3 ) == 0 && p3 ) {
- ptype = 's';
- if(p1->ExpressionType == 'N')
- buf = STR( p1->DoubResult, GetInt( p2 ), GetInt( p3 ));
- else
- buf = STR( p1->StringResult, GetInt( p2 ), GetInt( p3 ));
- }
-
- else if( strncmp( Func, "STR", 3 ) == 0 && p2 ) {
- ptype = 's';
- buf = STR( p1->StringResult, GetInt( p2 ));
- }
-
- else if( strncmp( Func, "STR", 3 ) == 0 && p1 ) {
- ptype = 's';
- buf = STR( p1->StringResult );
- }
-
- else if( strncmp( Func, "SUBSTR", 6 ) == 0 ) {
- ptype = 's';
- buf = SUBSTR( p1->StringResult, GetInt( p2 ), GetInt( p3 ));
- }
- else if( strncmp( Func, "TRIM", 4 ) == 0 ) {
- ptype = 's';
- buf = TRIM( p1->StringResult );
- }
- else if( strncmp( Func, "UPPER", 5 ) == 0 ) {
- ptype = 's';
- buf = UPPER( p1->StringResult );
- }
- else if( strncmp( Func, "VAL", 3 ) == 0 ) {
- ptype = 'd';
- DoubResult = VAL( p1->StringResult );
- }
- else if( strncmp( Func, "YEAR", 4 ) == 0 ) {
- ptype = 'd';
- DoubResult = YEAR( p1->StringResult );
- }
- if( p1 && !p1->InTree ) delete p1;
- if( p2 && !p2->InTree ) delete p2;
- if( p3 && !p3->InTree ) delete p3;
- if( !FuncNode->InTree ) delete FuncNode;
- if( buf ){
- len = strlen( buf );
- WorkNode = new xbExpNode;
- if( !WorkNode )
- return XB_NO_MEMORY;
- WorkNode->ResultLen = len + 1;
-
- } else {
- len = 0;
- WorkNode = new xbExpNode;
- if( !WorkNode )
- return XB_NO_MEMORY;
- WorkNode->ResultLen = 0;
- }
-
- switch( ptype ){
- case 's': /* string or char result */
- WorkNode->DataLen = len;
- WorkNode->ExpressionType = 'C';
- WorkNode->Type = 's';
- WorkNode->StringResult = buf;
- break;
- case 'd': /* numeric result */
- WorkNode->DataLen = 0;
- WorkNode->ExpressionType = 'N';
- WorkNode->Type = 'd';
- WorkNode->DoubResult = DoubResult;
- break;
- case 'l': /* logical result */
- WorkNode->DataLen = 0;
- WorkNode->ExpressionType = 'L';
- WorkNode->Type = 'l';
- WorkNode->IntResult = IntResult;
- break;
- default:
- std::cout << "\nInternal error. " << ptype;
- break;
- }
- Push(WorkNode);
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! Short description.
-/*!
-*/
-xbString & xbExpn::GetStringResult()
-{
- xbString *s = 0;
- xbExpNode *e;
- if( GetStackDepth() < 1 ) return *s;
- e = (xbExpNode *) Pop();
- s = &e->StringResult;
- Push(e);
- return *s;
-}
-/*************************************************************************/
-//! Short description.
-/*!
-*/
-xbLong xbExpn::GetIntResult()
-{
- xbLong l;
- xbExpNode * e;
- if( GetStackDepth() < 1 ) return 0L;
- e = (xbExpNode *) Pop();
- l = e->IntResult;
- Push(e);
- return l;
-}
-/*************************************************************************/
-//! Short description.
-/*!
-*/
-xbDouble xbExpn::GetDoubleResult()
-{
- xbDouble d;
- xbExpNode * e;
- if( GetStackDepth() < 1 ) return (xbDouble) 0;
- e = (xbExpNode *) Pop();
- d = e->DoubResult;
- Push(e);
- return d;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param p
-*/
-xbDouble xbExpn::GetDoub( xbExpNode * p )
-{
- if( p->Type == 'd' )
- return p->DoubResult;
- else if( p->Type == 'N' || p->Type == 's' )
- return( strtod( p->StringResult, NULL ));
- else if( p->Type == 'D' )
- return( p->dbf->GetDoubleField( p->FieldNo ));
- else
- return 0;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param p
-*/
-xbLong xbExpn::GetInt( xbExpNode *p )
-{
- if( p->Type == 'l' || p->Type == 'i' )
- return p->IntResult;
- else if( p->Type == 'N' || p->Type == 's' )
- return atoi( p->StringResult );
- else if( p->Type == 'D' )
- return p->dbf->GetLongField( p->FieldNo );
- else
- return 0L;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbDouble xbExpn::ABS( xbDouble d )
-{
- if( d < (xbDouble) 0 )
- return d * -1;
- else
- return d;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-xbLong xbExpn::ASC( const char * String )
-{
- return *String;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param s1
- \param s2
-*/
-xbLong xbExpn::AT( const char * s1, const char *s2 )
-{
- /* looks for s1 in s2 */
- xbLong cnt;
- const char *p;
- if( strlen( s1 ) > strlen( s2 )) return 0;
- if(( p = strstr( s2, s1 )) == NULL )
- return 0;
- cnt = 1;
- while( s2++ != p ) cnt++;
- return cnt;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-char * xbExpn::CDOW( const char * Date8 )
-{
- static char buf[10];
- xbDate d;
- xbShort len,i;
- strcpy( buf, d.FormatDate( "DDDD", Date8 ));
- len = strlen( buf );
- for( i = len; i < 9; i++ ) buf[i] = 0x20;
- buf[9] = 0x00;
- return buf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param l
-*/
-char * xbExpn::CHR( xbLong l )
-{
- static char buf[2];
- xbShort i;
- i = (xbShort) l;
- buf[0] = i;
- buf[1] = 0x00;
- return buf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-char * xbExpn::CMONTH( const char * Date8 )
-{
- static char buf[10];
- xbShort len,i;
- xbDate d;
- strcpy( buf, d.FormatDate( "MMMM", Date8 ));
- len = strlen( buf );
- for( i = len; i < 9; i++ ) buf[i] = 0x20;
- buf[9] = 0x00;
- return buf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param indate
-*/
-char * xbExpn::CTOD( const char * indate )
-{
- xbDate d;
- strcpy( WorkBuf, d.FormatCTODdate( indate ));
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-xbLong xbExpn::DAY( const char * Date8 )
-{
- xbDate d;
- return d.DayOf( XB_FMT_MONTH, Date8 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param date
-*/
-xbLong xbExpn::DESCEND( const xbDate & date )
-{
- return 2415021 + date.JulianDays( "29991231" ) - date.JulianDays();
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param num
-*/
-xbDouble xbExpn::DESCEND( xbDouble d )
-{
- return d * -1;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param str
-*/
-char * xbExpn::DESCEND( const char * str )
-{
- xbShort i;
- xbShort len = strlen( str );
-
- for( i = 0; i < len; i++ )
- WorkBuf[i] = 255 - str[i];
- WorkBuf[i] = 0x00;
-
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-xbLong xbExpn::DOW( const char * Date8 )
-{
- xbDate d;
- return d.DayOf( XB_FMT_WEEK, Date8 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-char * xbExpn::DTOC( const char * Date8 )
-{
- xbDate d;
- strcpy( WorkBuf, d.FormatDate( xbase->GetDefaultDateFormat(), Date8 ));
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-char * xbExpn::DTOS( const char * Date8 )
-{
- xbDate d;
- strcpy( WorkBuf, d.FormatDate( "YYYYMMDD", Date8 ));
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbDouble xbExpn::EXP( xbDouble d )
-{
- return exp( d );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param ifCondition
- \param trueRslt
- \param falseRslt
-*/
-char * xbExpn::IIF( xbShort ifCondition,
- const char * trueRslt, const char * falseRslt )
-{
- if( ifCondition )
- strcpy( WorkBuf, trueRslt );
- else
- strcpy( WorkBuf, falseRslt );
-
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbLong xbExpn::INT( xbDouble d )
-{
- return (xbLong) d;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-xbLong xbExpn::ISALPHA( const char * String )
-{
- if( isalpha(*String) ) return 1;
- else return 0;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-xbLong xbExpn::ISLOWER( const char * String )
-{
- if( islower(*String) ) return 1;
- else return 0;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-xbLong xbExpn::ISUPPER( const char * String )
-{
- if( isupper(*String) ) return 1;
- else return 0;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-xbLong xbExpn::LEN( const char * String )
-{
- xbLong len;
- len = strlen( String );
- len--;
- while( len >= 0 && String[len] == 0x20 ) len--;
- return ++len;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \param Len
-*/
-char * xbExpn::LEFT( const char * String, xbShort Len )
-{
- xbShort i;
- for( i = 0; i < Len && i < 100; i++ )
- WorkBuf[i] = String[i];
- WorkBuf[i] = 0x00;
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-/* This method removes any leading spaces from String */
-char * xbExpn::LTRIM( const char *String) {
- WorkBuf[0] = 0x00;
- if (!String)
- return WorkBuf;
-
- xbShort i;
- i = 0;
- while( *String && *String == 0x20 ) String++;
- while( *String && i < WorkBufMaxLen ){
- WorkBuf[i++] = *String;
- String++;
- }
- WorkBuf[i] = 0x00;
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbDouble xbExpn::LOG( xbDouble d )
-{
- return log( d );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-char *xbExpn::LOWER( const char *String )
-{
- WorkBuf[0] = 0x00;
- if (!String)
- return WorkBuf;
- xbShort i = 0;
- while( *String && i < WorkBufMaxLen) {
- WorkBuf[i++] = tolower( *String );
- String++;
- }
- WorkBuf[i] = 0x00;
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d1
- \param d2
-*/
-xbDouble xbExpn::MAX( xbDouble d1, xbDouble d2 )
-{
- if( d1 > d2 )
- return d1;
- else
- return d2;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d1
- \param d2
-*/
-xbDouble xbExpn::MIN( xbDouble d1, xbDouble d2 )
-{
- if( d1 < d2 )
- return d1;
- else
- return d2;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-xbLong xbExpn::MONTH( const char * Date8 )
-{
- xbDate d;
- return d.MonthOf( Date8 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbLong xbExpn::RECNO( xbDbf * d ) {
- return d->GetCurRecNo();
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \param Cnt
-*/
-char * xbExpn::REPLICATE( const char * String, xbShort Cnt )
-{
- xbShort len, i;
- len = strlen( String );
- if(( len * Cnt ) > 100 ) return NULL;
- memset( WorkBuf, 0x00, len+1 );
- for( i = 0; i < Cnt; i++ )
- strcat( WorkBuf, String );
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \paran cnt
-*/
-char * xbExpn::RIGHT( const char * String, xbShort cnt )
-{
- xbShort len;
- strcpy( WorkBuf, String );
- len = strlen( String );
- if( len < cnt ) return WorkBuf;
- len = LEN( String );
- if( len < cnt ) return WorkBuf;
- strcpy( WorkBuf, String + len - cnt );
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-char * xbExpn::RTRIM( const char * String )
-{
- return TRIM( String );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Cnt
-*/
-char * xbExpn::SPACE( xbShort Cnt )
-{
- if( Cnt > 100 ) return NULL;
- memset( WorkBuf, 0x20, Cnt );
- WorkBuf[Cnt] = 0x00;
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbDouble xbExpn::SQRT( xbDouble d )
-{
- return sqrt( d );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
- \param length
- \param numDecimals
-*/
-char * xbExpn::STR(xbDouble d, xbUShort length, xbShort numDecimals) {
- // sanity check for length arg
- if (length > WorkBufMaxLen)
- {
- // maybe should generate an error here instead ?
- length = WorkBufMaxLen;
- }
-
- // check the length required
- sprintf(WorkBuf, "%.*f", numDecimals, d);
-
- if ((xbUShort) strlen(WorkBuf) > length) {
- memset(WorkBuf, '*', length);
- WorkBuf[length] = 0x00;
- } else
- sprintf( WorkBuf, "%*.*f", length, numDecimals, d );
-
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
- \param length
-*/
-char * xbExpn::STR( xbDouble d, xbShort length )
-{
- return STR( d, length, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-char * xbExpn::STR( xbDouble d )
-{
- return STR( d, 10, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \param length
- \param
-*/
-char * xbExpn::STR( const char * String, xbShort length, xbShort dec )
-{
- xbShort len, i;
- double d;
- d = strtod( String, NULL );
- return STR( d, length, dec );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \param length
-*/
-char * xbExpn::STR( const char *String, xbShort length )
-{
- return STR( String, length, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-char * xbExpn::STR( const char * String )
-{
- return STR( String, 10, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
- \param length
- \param
-*/
-char * xbExpn::STRZERO( xbDouble d, xbShort length, xbShort )
-{
- xbShort len,i;
- sprintf(WorkBuf, "%*.*g", length, length, d);
-// gcvt( d, length, WorkBuf );
- len = strlen( WorkBuf );
- if( len > length )
- strcpy( WorkBuf, "**********" );
- else if( len < length )
- {
- for( i = len; i < length; i++ )
- WorkBuf[i] = 0x30;
- WorkBuf[i] = 0x00;
- }
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
- \param length
-*/
-char * xbExpn::STRZERO( xbDouble d, xbShort length )
-{
- return STRZERO( d, length, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-char * xbExpn::STRZERO( xbDouble d )
-{
- return STRZERO( d, 10, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \param length
- \param
-*/
-char * xbExpn::STRZERO( const char * String, xbShort length, xbShort )
-{
- xbShort i, len ;
- while( *String == ' ' ) String++;
- len = strlen(String);
- for( i = 0; i < abs( length-len); i++ )
- WorkBuf[i] = 0x30;
- WorkBuf[i] = 0x00;
- strcat( WorkBuf, String );
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \param length
-*/
-char * xbExpn::STRZERO( const char * String, xbShort length )
-{
- return STRZERO( String, length, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-char * xbExpn::STRZERO( const char * String )
-{
- return STRZERO( String, 10, 0 );
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
- \param StartPos
- \param Len
-*/
-char * xbExpn::SUBSTR( const char * String, xbShort StartPos, xbShort Len )
-{
- xbShort i;
- if( StartPos < 1 ) return NULL;
- String += (StartPos - 1);
- for( i = 0; i < Len; i++ )
- WorkBuf[i] = *String++;
- WorkBuf[i] = 0x00;
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
-*/
-char * xbExpn::DATE()
-{
- xbDate d;
- strcpy( WorkBuf, d.Sysdate());
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-char * xbExpn::TRIM( const char * String )
-{
- WorkBuf[0] = 0x00;
- if( !String )
- return WorkBuf;
- char *sp;
- xbShort len;
- len = strlen( String );
- if( len < WorkBufMaxLen ) {
- strcpy( WorkBuf, String );
- }
- else {
- strncpy( WorkBuf, String, WorkBufMaxLen );
- WorkBuf[ WorkBufMaxLen ] = 0x00;
- len = WorkBufMaxLen;
- }
- sp = WorkBuf + len - 1;
- while( *sp == 0x20 && sp >= WorkBuf ) {
- *sp = 0x00;
- sp--;
- }
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-char *xbExpn::UPPER( const char *String )
-{
- WorkBuf[0] = 0x00;
- if (!String)
- return WorkBuf;
- xbShort i;
- i = 0;
- while(*String && i < WorkBufMaxLen) {
- WorkBuf[i++] = toupper(*String);
- String++;
- }
- WorkBuf[i] = 0x00;
- return WorkBuf;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param String
-*/
-xbLong xbExpn::VAL( const char * String )
-{
- if( String )
- return (xbLong) *String;
- else
- return 0;
-}
-/*************************************************************************/
-//! Short description.
-/*!
- \param Date8
-*/
-xbLong xbExpn::YEAR( const char * Date8 ){
- xbDate d;
- return d.YearOf( Date8 );
-}
-/*************************************************************************/
-#endif // XB_EXPRESSIONS
diff --git a/xbase64/xbexpprc.cpp b/xbase64/xbexpprc.cpp
deleted file mode 100755
index 8334ea4..0000000
--- a/xbase64/xbexpprc.cpp
+++ /dev/null
@@ -1,549 +0,0 @@
-/* xbexpprc.cpp
-
- Xbase64 project source code
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-#ifdef XB_EXPRESSIONS
-
-#include <ctype.h>
-#include <math.h>
-
-/*! \file xbexpprc.cpp
-*/
-
-/*************************************************************************/
-//! Short description
-/*!
- \param e
-*/
-xbExpNode * xbExpn::GetFirstTreeNode( xbExpNode * e )
-{
- xbExpNode * WorkNode;
- if( !e ) return e;
- WorkNode = e;
- while( WorkNode->Sibling1 )
- WorkNode = WorkNode->Sibling1;
- return WorkNode;
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param Operand
- \param Op1
- \pamam Op2
-*/
-xbShort xbExpn::ValidOperation( char * Operand, char Op1, char Op2 )
-{
- /* Valid operation table
-
- operator Op1 Op2 operator Op1 Op2
-
- ** N N = N N
- * N N = C C
- / N N = D D
- + N N <>,# N N
- + C C <>,# C C
- + D N <>,# D D
- - N N <= N N
- - C C <= D D
- - D D <= C C
- - D N >= N N
- < N N >= D D
- < C C >= C C
- < D D $ C C
- > N N
- > C C
- > D D
-
- C = Character
- D = Date
- N = Numeric
-
- Maybe reversed to what you are thinking ==> think OP2 - OP1
-
- */
-
- // check for **
- if( Operand[0] == '*' && Operand[1] == '*' && Op1 == 'N' && Op2 == 'N' )
- return 1;
-
- // check for !=
- if(( Operand[0] == '!' && Operand[1] == '=' ) &&
- (( Op1 == 'N' && Op2 == 'N' ) ||
- ( Op1 == 'C' && Op2 == 'C' ) ||
- ( Op1 == 'D' && Op2 == 'D' )))
- return 1;
-
- switch( Operand[0] ) {
- case '*':
- case '/':
- if( Op1 == 'N' && Op2 == 'N' )
- return 1;
- else
- return 0;
-
- case '+':
- if(( Op1 == 'N' && Op2 == 'N' ) ||
- ( Op1 == 'C' && Op2 == 'C' ) ||
- ( Op1 == 'N' && Op2 == 'D' ))
- return 1;
- else
- return 0;
-
- case '-':
- if(( Op1 == 'N' && Op2 == 'N' ) ||
- ( Op1 == 'C' && Op2 == 'C' ) ||
- ( Op1 == 'D' && Op2 == 'D' ) ||
- ( Op1 == 'N' && Op2 == 'D' ))
- return 1;
- else
- return 0;
-
- case '<':
- case '>':
- case '=':
- case '#':
- if(( Op1 == 'N' && Op2 == 'N' ) ||
- ( Op1 == 'C' && Op2 == 'C' ) ||
- ( Op1 == 'D' && Op2 == 'D' ))
- return 1;
- else
- return 0;
-
- case '$':
- if( Op1 == 'C' && Op2 == 'C' )
- return 1;
- else
- return 0;
-
- case '.' :
- if( (strncmp( Operand, ".AND.", 5 ) == 0 ) ||
- (strncmp( Operand, ".OR.", 4 ) == 0 ) ||
- (strncmp( Operand, ".NOT.", 5 ) == 0 ))
- return 1;
- else
- return 0;
-
- default:
- return 0;
- }
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param e
-*/
-xbExpNode * xbExpn::GetNextTreeNode( xbExpNode * e )
-{
- if( !e->Node ) return NULL;
-
- /* sibling 1 && sibling 2 exists */
- if( e == e->Node->Sibling1 && e->Node->Sibling2 )
- return GetFirstTreeNode( e->Node->Sibling2 );
-
- /* sibling2 && sibling3 exists */
- else if( e == e->Node->Sibling2 && e->Node->Sibling3 )
- return GetFirstTreeNode( e->Node->Sibling3 );
-
- else
- return e->Node;
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param e
-*/
-xbShort xbExpn::ProcessExpression( xbExpNode * e )
-{
- return ProcessExpression( e, 0 );
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param Wtree
- \param RecBufSw
-*/
-xbShort xbExpn::ProcessExpression( xbExpNode * Wtree, xbShort RecBufSw )
-{
- xbExpNode * WorkNode;
- xbShort rc;
- if( Wtree == 0 )
- Wtree = Tree;
- memset(WorkBuf, 0x00, WorkBufMaxLen+1 );
- /* initialize the stack - free any expnodes */
- while( GetStackDepth() > 0 ) {
- WorkNode = (xbExpNode *) Pop();
- if( !WorkNode->InTree )
- delete WorkNode;
- }
- if(( WorkNode = GetFirstTreeNode( Wtree )) == NULL )
- return XB_NO_DATA;
-
- while( WorkNode ) {
- Push(WorkNode);
- if( WorkNode->Type == 'D' && WorkNode->dbf ) {
- WorkNode->dbf->GetField( WorkNode->FieldNo, WorkNode->StringResult, RecBufSw );
- if( WorkNode->dbf->GetFieldType( WorkNode->FieldNo ) == 'N' ||
- WorkNode->dbf->GetFieldType( WorkNode->FieldNo ) == 'F' )
- WorkNode->DoubResult = WorkNode->dbf->GetDoubleField( WorkNode->FieldNo, RecBufSw );
- } else if( WorkNode->Type == 'O' ) {
- if(( rc = ProcessOperator( RecBufSw )) != XB_NO_ERROR )
- return rc;
- } else if( WorkNode->Type == 'F' )
- if(( rc = ProcessFunction( WorkNode->NodeText )) != XB_NO_ERROR )
- return rc;
- WorkNode = GetNextTreeNode( WorkNode );
- }
- if( GetStackDepth() != 1 ) /* should only have result left in stack */
- return XB_PARSE_ERROR;
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param e
-*/
-char xbExpn::GetOperandType( xbExpNode * e )
-{
- /* this routine returns
- L - logical
- N - Numeric
- C - Character
- 0 - error
- */
- char WorkType;
- if( e->Type == 'd' || e->Type == 'N' || e->Type == 'i' ) return 'N';
- if( e->Type == 'l' ) return 'L';
- if( e->Type == 's' ) return 'C';
- if( e->Type == 'C' ) {
- if(e->NodeText[0]=='-' || e->NodeText[0]=='+' ||
- (isdigit(e->NodeText[0]) &&
- !(e->NodeText[e->DataLen] == '\'' || e->NodeText[e->DataLen] == '"')))
- return 'N';
- else
- return 'C';
- } else if( e->Type == 'D' && e->dbf ){
- WorkType = e->dbf->GetFieldType( e->FieldNo );
- if( WorkType == 'C' ) return 'C';
- else if( WorkType == 'F' || WorkType == 'N' ) return 'N';
- else if( WorkType == 'L' ) return 'L';
- else if( WorkType == 'D' ) return 'D';
- else return 0;
- } else
- return 0;
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param RecBufSw
-*/
-xbShort xbExpn::ProcessOperator( xbShort RecBufSw )
-{
- xbExpNode * WorkNode;
- char Operator[6];
- char t;
- if( GetStackDepth() < 3 )
- return XB_PARSE_ERROR;
- WorkNode = (xbExpNode *) Pop();
- if( WorkNode->Len > 5 )
- return XB_PARSE_ERROR;
-
- memset( Operator, 0x00, 6 );
- strncpy( Operator, WorkNode->NodeText, WorkNode->Len );
- if( !WorkNode->InTree )
- delete WorkNode;
-
- /* load up operand 1 */
- WorkNode = (xbExpNode *) Pop();
- if(( OpType1 = GetOperandType( WorkNode )) == 0 )
- return XB_PARSE_ERROR;
-
- if( OpLen1 < WorkNode->DataLen+1 && WorkNode->Type != 'd' ) {
- if( OpLen1 > 0 ) free( Op1 );
- if(( Op1 = (char *) malloc( WorkNode->DataLen+1 )) == NULL ) {
- return XB_NO_MEMORY;
- }
- OpLen1 = WorkNode->DataLen+1;
- }
- OpDataLen1 = WorkNode->DataLen;
- memset( Op1, 0x00, WorkNode->DataLen+1 );
- if( WorkNode->Type == 'D' && WorkNode->dbf ) { /* database field */
- WorkNode->dbf->GetField( WorkNode->FieldNo, Op1, RecBufSw );
- t = WorkNode->dbf->GetFieldType( WorkNode->FieldNo );
- if( t == 'N' || t == 'F' )
- Opd1 = strtod( WorkNode->StringResult, 0 );
- else if( t == 'D' ){ // date field
- xbDate d;
- Opd1 = d.JulianDays( WorkNode->StringResult );
- }
- }
- else if( WorkNode->Type == 'C' ) /* constant */
- memcpy( Op1, WorkNode->NodeText, WorkNode->DataLen );
- else if( WorkNode->Type == 's' ) /* previous result */
- memcpy( Op1, WorkNode->StringResult, WorkNode->DataLen+1 );
- else if( WorkNode->Type == 'd' ) /* previous numeric result */
- Opd1 = WorkNode->DoubResult;
- else if( WorkNode->Type == 'N' ) /* previous numeric result */
- Opd1 = strtod( WorkNode->StringResult, 0 );
- else if(WorkNode->Type == 'l') /* previous logical result 3/26/00 dtb */
- Opd1 = WorkNode->IntResult;
- if( !WorkNode->InTree )
- delete WorkNode;
-
- /* load up operand 2 */
- WorkNode = (xbExpNode *) Pop();
- if(( OpType2 = GetOperandType( WorkNode )) == 0 )
- return XB_PARSE_ERROR;
-
- if( OpLen2 < WorkNode->DataLen+1 && WorkNode->Type != 'd' ) {
- if( OpLen2 > 0 ) free( Op2 );
- if(( Op2 = (char *) malloc( WorkNode->DataLen+1 )) == NULL ) {
- return XB_NO_MEMORY;
- }
- OpLen2 = WorkNode->DataLen+1;
- }
- OpDataLen2 = WorkNode->DataLen;
- memset( Op2, 0x00, WorkNode->DataLen+1 );
- if( WorkNode->Type == 'D' && WorkNode->dbf ) { /* database field */
- WorkNode->dbf->GetField( WorkNode->FieldNo, Op2, RecBufSw );
- t = WorkNode->dbf->GetFieldType( WorkNode->FieldNo );
- if( t == 'N' || t == 'F' )
- Opd2 = strtod( WorkNode->StringResult, 0 );
- else if( t == 'D' ){ // date field
- xbDate d;
- Opd2 = d.JulianDays( WorkNode->StringResult );
- }
- }
- else if( WorkNode->Type == 'C' ) /* constant */
- memcpy( Op2, WorkNode->NodeText, WorkNode->DataLen );
- else if( WorkNode->Type == 's' ) /* previous result */
- memcpy( Op2, WorkNode->StringResult, WorkNode->DataLen+1 );
- else if( WorkNode->Type == 'd' ) /* previous numeric result */
- Opd2 = WorkNode->DoubResult;
- else if( WorkNode->Type == 'N' ) /* previous numeric result */
- Opd2 = strtod( WorkNode->StringResult, 0 );
- else if(WorkNode->Type == 'l') /* previous logical result 3/26/00 dtb*/
- Opd2 = WorkNode->IntResult;
- if( !WorkNode->InTree )
- delete WorkNode;
- if( !ValidOperation( Operator, OpType1, OpType2 ))
- return XB_PARSE_ERROR;
-
- if( OpType1 == 'N' || OpType1 == 'L' || OpType1 == 'D' ) /* numeric procesing */
- return NumericOperation( Operator );
- else /* must be character */
- return AlphaOperation( Operator );
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param Operator
-*/
-xbShort xbExpn::NumericOperation( char * Operator )
-{
- xbDouble Operand1, Operand2;
- xbExpNode * WorkNode;
- xbShort ResultLen;
- char SaveType;
- ResultLen = 0;
-
-/* This function assumes a valid operation coming in */
-
- if( Operator[0] == '=' || Operator[0] == '<' ||
- Operator[0] == '>' || Operator[0] == '#' ||
- Operator[0] == '.' || (strncmp( Operator, "!=", 2 ) == 0 ))
- SaveType = 'l';
- else
- SaveType = 'd';
-
- WorkNode = new xbExpNode;
-
- if( !WorkNode )
- return XB_PARSE_ERROR;
- WorkNode->ResultLen = ResultLen;
- WorkNode->Type = SaveType;
- WorkNode->DataLen = ResultLen;
-
- if( OpType1 == 'd' || OpType1 == 'N' || OpType2 == 'D' )
- Operand1 = Opd1;
- else
- Operand1 = strtod( Op1, NULL );
-
- if( OpType2 == 'd' || OpType2 == 'N' || OpType2 == 'D' )
- Operand2 = Opd2;
- else
- Operand2 = strtod( Op2, NULL );
-
- if( Operator[0] == '*' && Operator[1] == '*' )
- WorkNode->DoubResult = pow( Operand2, Operand1 );
- else if( Operator[0] == '*' )
- WorkNode->DoubResult = Operand2 * Operand1;
- else if( Operator[0] == '/')
- WorkNode->DoubResult = Operand2 / Operand1;
- else if( Operator[0] == '+' ){
- WorkNode->DoubResult = Operand2 + Operand1;
- xbDate d;
- WorkNode->StringResult = d.JulToDate8((xbLong) WorkNode->DoubResult );
- } else if( Operator[0] == '-' ){
- WorkNode->DoubResult = Operand2 - Operand1;
- xbDate d;
- WorkNode->StringResult = d.JulToDate8((xbLong) WorkNode->DoubResult );
- }
-
- /* = */
- else if( Operator[0]== '=' && Operand1 == Operand2 )
- WorkNode->IntResult = 1;
- else if( Operator[0] == '=' )
- WorkNode->IntResult = 0;
- /* not = */
- else if(( Operator[0] == '<' && Operator[1] == '>' )||
- ( Operator[0] == '!' && Operator[1] == '=' )||
- Operator[0] == '#' || (strncmp( Operator, "!=", 2 ) == 0 ))
- WorkNode->IntResult = ( Operand1 != Operand2 ) ? 1 : 0;
- /* less than */
- else if( Operator[0] == '<' )
- WorkNode->IntResult = ( Operand2 < Operand1 ) ? 1 : 0;
- /* greater than */
- else if( Operator[0] == '>' )
- WorkNode->IntResult = ( Operand2 > Operand1 ) ? 1 : 0;
- else if(Operator[0] == '.'){ // logical operators, added 3/26/00 dtb
- switch(Operator[1]){
- case 'A' : // and
- WorkNode->IntResult = (Opd1 && Opd2) ? 1 : 0;
- break;
-
- case 'N' : // not
- WorkNode->IntResult = (!(Opd1 && Opd2)) ? 1 : 0;
- break;
-
- case 'O' : // or
- WorkNode->IntResult = (Opd1 || Opd2) ? 1 : 0;
- break;
-
- default :
- return XB_PARSE_ERROR;
- }
- } else
- return XB_PARSE_ERROR;
-
- Push(WorkNode);
- return 0;
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param Operator
-*/
-xbShort xbExpn::AlphaOperation( char * Operator )
-{
- xbShort ResultLen, i;
- char SaveType;
- xbExpNode * WorkNode;
-
- if( Operator[0] == '=' || Operator[0] == '<' ||
- Operator[0] == '>' || Operator[0] == '#' ||
- (strncmp( Operator, "!=", 2 ) == 0 ) ||
- Operator[0] == '$'){
- ResultLen = 0;
- SaveType = 'l';
- } else {
- ResultLen = OpDataLen1 + OpDataLen2 + 1;
- SaveType = 's';
- }
-
- WorkNode = new xbExpNode;
- if( !WorkNode )
- return XB_PARSE_ERROR;
- WorkNode->ResultLen = ResultLen;
- WorkNode->Type = SaveType;
- if( WorkNode->Type == 'l' )
- WorkNode->DataLen = 0;
- else
- WorkNode->DataLen = ResultLen - 1;
-
- if( Operator[0] == '+' ){
- WorkNode->StringResult = Op2;
- WorkNode->StringResult += Op1;
- } else if( Operator[0] == '-' ) {
- WorkNode->StringResult = RTRIM( Op2 );
- WorkNode->StringResult += Op1;
- i = WorkNode->StringResult.len();
- for( ; i < ResultLen-1; i++)
- WorkNode->StringResult += " ";
- }
- /* == */
- else if(( strncmp( Operator, "==", 2 ) == 0 ) && strcmp(Op1,Op2) == 0)
- WorkNode->IntResult = 1;
-
- else if(( strncmp( Operator, "==", 2 ) == 0 ))
- WorkNode->IntResult = 0;
-
- /* = */
- else if( Operator[0] == '=' && strcmp(Op1,Op2) == 0 )
- WorkNode->IntResult = 1;
-
- else if( Operator[0] == '=' )
- WorkNode->IntResult = 0;
-
- /* not = */
- else if(( strncmp( Operator, "<>", 2 ) == 0 ) ||
- Operator[0] == '#' ||
- strncmp( Operator, "!=", 2 ) == 0 )
- WorkNode->IntResult = ( strcmp( Op1, Op2 ) != 0 ) ? 1 : 0;
- /* less than */
- else if( Operator[0] == '<' )
- WorkNode->IntResult = ( strcmp( Op2, Op1 ) < 0 ) ? 1 : 0;
- /* greater than */
- else if( Operator[0] == '>' )
- WorkNode->IntResult = ( strcmp( Op2, Op1 ) > 0 ) ? 1 : 0;
- else if(Operator[0] == '$')
- WorkNode->IntResult = (strstr(Op1,Op2)) ? 1 : 0;
- else
- return XB_PARSE_ERROR;
-
- Push(WorkNode);
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-#endif // XB_EXPRESSIONS
diff --git a/xbase64/xbfields.cpp b/xbase64/xbfields.cpp
deleted file mode 100755
index d3e2388..0000000
--- a/xbase64/xbfields.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/* xbfields.cpp
-
- Xbase64 project source code
-
- This file contains the basic X-Base routines for reading and writing
- Xbase fields.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-/*! \file xbfields.cpp
-*/
-/************************************************************************/
-/* This function returns true if the data is valid logical data */
-//! Determines if data is valid logical data.
-/*! Determines if the data in buf is valid for a logical field value.
-
- \param buf data to be tested
- \returns TRUE (non-zero) if valid, FALSE (zero) if not.
-*/
-xbShort xbDbf::ValidLogicalData(const char * buf) {
- if( buf[0] )
- if( buf[0] == 'T' || buf[0] == 't' || buf[0] == 'F' || buf[0] == 'f' ||
- buf[0] == 'Y' || buf[0] == 'y' || buf[0] == 'N' || buf[0] == 'n' ||
- buf[0] == '?' )
- return 1;
- return 0;
-}
-/************************************************************************/
-/* This function returns true if the data is valid numeric data */
-//! Determines if data is valid numeric data.
-/*! Determines if the data in buf is valid for a numeric field value.
-
- \param buf
- \returns TRUE (non-zero) if valid, FALSE (zero) if not.
-*/
-xbShort xbDbf::ValidNumericData(const char * buf) {
- const char *p;
-
- p = buf;
- while( *p ){
- if( *p != '+' && *p != '-' && *p != '.' && *p != '0' && *p != '1' &&
- *p != '2' && *p != '3' && *p != '4' && *p != '5' && *p != '6' &&
- *p != '7' && *p != '8' && *p != '9' )
- return 0;
- else
- p++;
- }
- return 1;
-}
-/************************************************************************/
-/* This function returns a fields length */
-//! Returns the length of the specified field.
-/*! Returns the length of the field specified by FieldNo.
-
- \param FieldNo Number of field.
- \returns Length of the specified field in bytes.
-*/
-xbShort xbDbf::GetFieldLen( xbShort FieldNo )
-{
- if( FieldNo >= 0 && FieldNo < NoOfFields ){
- if( SchemaPtr[FieldNo].Type == 'C' && SchemaPtr[FieldNo].NoOfDecs > 0 )
- return SchemaPtr[FieldNo].LongFieldLen;
- else
- return SchemaPtr[FieldNo].FieldLen;
- }
- else
- return 0;
-}
-/************************************************************************/
-/* This function returns a fields decimal length */
-//! Returns the number of decimals in the specified field.
-/*! Returns the number of decimals in the field specified by FieldNo.
-
- \param FieldNo Number of field.
- \returns Length of the specified field in bytes.
-*/
-
-xbShort xbDbf::GetFieldDecimal( xbShort FieldNo )
-{
- if( FieldNo >= 0 && FieldNo < NoOfFields )
- return SchemaPtr[FieldNo].NoOfDecs;
- else
- return 0;
-}
-/************************************************************************/
-/* This function returns a fields type */
-//! Returns the type of the specified field.
-/*! Returns the type of the field specified by FieldNo.
-
- \param FieldNo Number of field.
- \returns Type of specified field.
-*/
-char xbDbf::GetFieldType( xbShort FieldNo ) const
-{
- if( FieldNo >= 0 && FieldNo < NoOfFields )
- return SchemaPtr[FieldNo].Type;
- else
- return 0;
-}
-/************************************************************************/
-/* This function returns a fields name */
-//! Returns the name of the specified field.
-/*! Returns a pointer to the name for the field specified by FieldNo.
-
- \param FieldNo Number of field.
- \returns A pointer to the name of the field.
-*/
-char * xbDbf::GetFieldName( xbShort FieldNo )
-{
- if( FieldNo >= 0 && FieldNo < NoOfFields )
- return SchemaPtr[FieldNo].FieldName;
- else
- return 0;
-}
-/************************************************************************/
-/* This function returns the field ID number for a given field
- or -1 if the field is not one of the fields of the database */
-//! Returns the field number of the specified field.
-/*! Returns the field number for the named field.
-
- \param name Name of field.
- \returns Number of field named name.
-*/
-xbShort xbDbf::GetFieldNo( const char * name ) const
-{
- int i, len1, len2;
-
- if(( len1 = strlen( name )) > 10 )
- return -1;
-
- for( i = 0; i < NoOfFields; i++ ){
- len2 = strlen( SchemaPtr[i].FieldName );
- if( len1 == len2 )
-
-//#ifndef __WIN32__
-#ifdef HAVE_STRCASECMP
- if(!strcasecmp( SchemaPtr[i].FieldName, name ))
-#else
- if(!stricmp( SchemaPtr[i].FieldName, name ))
-#endif
-
- return i;
- }
- return -1;
-}
-/************************************************************************/
-/*
- Helpers
-*/
-
-//! Get the value of the specified field.
-/*! Get the value of the field referenced by Name and place its value
- in buf.
-
- \param Name Name of field.
- \param buf Buffer to hold field value. Must be large enough to hold
- the entire field value. Use GetFieldLen() to determine
- the length of the field, if necessary.
- \param RecBufSw
- \returns One of the following:
-*/
-xbShort xbDbf::GetField(const char *Name, char *buf,
- const xbShort RecBufSw ) const
-{
- return GetField(GetFieldNo(Name), buf, RecBufSw);
-}
-
-/************************************************************************/
-//! Get the value of the specified field.
-/*! Get the value of the field specified by Name and place its value
- in buf.
-
- \param Name Name of field.
- \param buf Buffer to hold field value. Must be large enough to hold
- the entire field value. Use GetFieldLen() to determine
- the length of the field, if necessary.
- \returns One of the following:
-*/
-xbShort xbDbf::GetField(const char *Name, char *buf) const
-{
- return GetField(GetFieldNo(Name), buf);
-}
-/************************************************************************/
-//! Get the raw value of the specified field.
-/*! Get the value of the field specified by Name and place its value
- in buf.
-
- \param Name Name of field.
- \param buf Buffer to hold field value. Must be large enough to hold
- the entire field value. Use GetFieldLen() to determine
- the length of the field, if necessary.
- \returns One of the following:
-*/
-xbShort xbDbf::GetRawField(const char *Name, char *buf) const
-{
- return GetRawField(GetFieldNo(Name), buf);
-}
-
-/************************************************************************/
-
-// FIXME this function doesn't follow look and feel of the rest of the lib
-// GAK
-
-static char __buf[1024];
-
-static void trim(char *s) {
- int len = strlen(s)-1;
- if (len > 0) {
- while ((len != 0) && (s[len] == ' '))
- len--;
- s[len+1] = 0;
- }
-}
-
-//! Get the value of the specified field.
-/*! Returns the value of the field specified by Name.
-
- \param Name Name of field.
- \returns Value of the specified field.
-*/
-const char *xbDbf::GetField(const char *Name) const {
- GetField(GetFieldNo(Name), __buf);
- trim(__buf);
- return __buf;
-}
-
-//! Get the value of the specified field.
-/*! Returns the value of the field specified by FieldNo.
-
- \param FieldNo Number of field.
- \returns Value of the specified field.
-*/
-const char *xbDbf::GetField(xbShort FieldNo) const {
- GetField(FieldNo, __buf);
- trim(__buf);
- return __buf;
-}
-/************************************************************************/
-/* This function fills a buffer with data from the record buffer
- for a particular field number.
-
- Use GetFieldNo to get a number based on a field's name
-
- If successful, this function returns the field size.
-*/
-
-//! Get the value of the specified field.
-/*! Get the value of the field specified by FieldNo and place its value
- in buf.
-
- \param FieldNo Number of field.
- \param buf Buffer to hold field value. Must be large enough to hold
- the entire field value. Use GetFieldLen() to determine
- the length of the field, if necessary.
- \param RecBufSw
- \returns The length of the field.
-*/
-xbShort xbDbf::GetField( xbShort FieldNo, char * buf, xbShort RecBufSw) const
-{
- xbShort length;
- if( FieldNo < 0 || FieldNo >= NoOfFields ) {
- buf[0] = 0x00;
- return 0x00;
- }
-
-// Check for existence of a long field length
- if( SchemaPtr[FieldNo].Type == 'C' && SchemaPtr[FieldNo].NoOfDecs > 0 )
- length = SchemaPtr[FieldNo].LongFieldLen;
- else
- length = SchemaPtr[FieldNo].FieldLen;
-
- if( RecBufSw )
- memcpy( buf, SchemaPtr[FieldNo].Address2, length );
- else
- memcpy( buf, SchemaPtr[FieldNo].Address, length );
- buf[length] = 0x00;
- return( length );
-}
-/************************************************************************/
-xbShort xbDbf::GetField( xbShort FieldNo, xbString & sf, xbShort RecBufSw) const
-{
- xbShort length;
- if( FieldNo < 0 || FieldNo >= NoOfFields ) {
- sf = "";
- return 0;
- }
-
- // Check for existence of a long field length
- if( SchemaPtr[FieldNo].Type == 'C' && SchemaPtr[FieldNo].NoOfDecs > 0 )
- length = SchemaPtr[FieldNo].LongFieldLen;
- else
- length = SchemaPtr[FieldNo].FieldLen;
-
- if( RecBufSw )
- sf.assign( xbString(SchemaPtr[FieldNo].Address2, length), 0, length );
- else
- sf.assign( xbString(SchemaPtr[FieldNo].Address, length), 0, length );
-
- return( length );
-}
-/************************************************************************/
-/* This function fills a field in the record buffer with data from
- a buffer for a particular field.
-
- Use GetFieldNo to get a number based on a field's name
-
- Field type N or F is loaded as right justified, left blank filled.
- Other fields are loaded as left justified, right blank filled.
-
- This method does check the data's validity.
-
- If successful, this function returns 0, if invalid data, it returns -1
- or XB_INVALID_FIELDNO
-*/
-
-//! Put a value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutField(const char *Name, const char *buf) {
- return PutField(GetFieldNo(Name), buf);
-}
-/************************************************************************/
-//! Put a raw value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutRawField(const char *Name, const char *buf) {
- return PutRawField(GetFieldNo(Name), buf);
-}
-/************************************************************************/
-//! Put a value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutField(const xbShort FieldNo, const char *buf) {
- xbShort len, i;
- char * startpos;
- char * tp; /* target pointer */
- const char * sp; /* source pointer */
-
- if( FieldNo < 0 || FieldNo >= NoOfFields )
- return XB_INVALID_FIELDNO;
-
- if( DbfStatus != XB_UPDATED ){
- DbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, RecordLen );
- }
-
- if( SchemaPtr[FieldNo].Type == 'L' && !ValidLogicalData( buf ))
- return XB_INVALID_DATA;
-
- else if(( SchemaPtr[FieldNo].Type == 'F' || SchemaPtr[FieldNo].Type == 'N' )
- && !ValidNumericData( buf ))
- return XB_INVALID_DATA;
-
- else if( SchemaPtr[FieldNo].Type == 'D' ){
- xbDate d;
- if( !d.DateIsValid( buf ))
- return XB_INVALID_DATA;
- }
-
- if( SchemaPtr[FieldNo].Type == 'C' && SchemaPtr[FieldNo].NoOfDecs > 0 )
- memset( SchemaPtr[FieldNo].Address, 0x20, SchemaPtr[FieldNo].LongFieldLen );
- else
- memset( SchemaPtr[FieldNo].Address, 0x20, SchemaPtr[FieldNo].FieldLen );
-
- len = strlen( buf );
-
- if(( SchemaPtr[FieldNo].Type == 'N' || SchemaPtr[FieldNo].Type == 'F')
- && len > SchemaPtr[FieldNo].FieldLen )
- return XB_INVALID_DATA;
- else if( len > SchemaPtr[FieldNo].FieldLen )
- len = SchemaPtr[FieldNo].FieldLen;
-
- if( SchemaPtr[FieldNo].Type == 'F' || SchemaPtr[FieldNo].Type == 'N'
- || SchemaPtr[FieldNo].Type == 'M') {
-
- const char *sdp = strchr( buf, '.' ); /* source decimal point */
- len = 0;
- sp =buf;
- while( *sp && *sp != '.' ) { len++; sp++; }
- if( SchemaPtr[FieldNo].NoOfDecs > 0 ){
- /* do the right of decimal area */
- tp = SchemaPtr[FieldNo].Address;
- tp += SchemaPtr[FieldNo].FieldLen - SchemaPtr[FieldNo].NoOfDecs - 1;
- *tp++ = '.';
- sp = sdp;
- if( sp ) sp++;
- for( i = 0; i < SchemaPtr[FieldNo].NoOfDecs; i++ )
- if( sp && *sp ) *tp++ = *sp++; else *tp++ = '0';
-
- startpos= SchemaPtr[FieldNo].Address +
- SchemaPtr[FieldNo].FieldLen -
- SchemaPtr[FieldNo].NoOfDecs - len - 1;
- }
- else
- {
- startpos=SchemaPtr[FieldNo].Address+SchemaPtr[FieldNo].FieldLen-len;
- }
- }
- else
- startpos = SchemaPtr[FieldNo].Address;
-
- memcpy( startpos, buf, len );
- return 0;
-}
-
-/************************************************************************/
-//! Put a raw value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutRawField(const xbShort FieldNo, const char *buf) {
- xbShort len;
- char * startpos;
-
- if( FieldNo < 0 || FieldNo >= NoOfFields )
- return XB_INVALID_FIELDNO;
-
- if( DbfStatus != XB_UPDATED ){
- DbfStatus = XB_UPDATED;
- memcpy( RecBuf2, RecBuf, RecordLen );
- }
-
- startpos = SchemaPtr[FieldNo].Address;
- len = SchemaPtr[FieldNo].FieldLen;
- memcpy( startpos, buf, len );
-
- return 0;
-}
-
-/************************************************************************/
-//! Get the value of the specified field.
-/*!
-*/
-xbShort xbDbf::GetField( xbShort FieldNo, char *buf) const {
- return GetField(FieldNo, buf, 0);
-}
-/************************************************************************/
-//! Get the raw value of the specified field.
-/*!
-*/
-xbShort xbDbf::GetRawField( xbShort FieldNo, char *buf ) const {
- return GetField(FieldNo, buf, 0);
-}
-/************************************************************************/
-//! Get the long value of the specified field.
-/*!
-*/
-xbLong xbDbf::GetLongField( xbShort FieldNo ) const
-{
- char buf[18];
- memset( buf, 0x00, 18 );
- GetField( FieldNo, buf );
- return atol( buf );
-}
-/************************************************************************/
-//! Get the long value of the specified field.
-/*!
-*/
-xbLong xbDbf::GetLongField( const char * FieldName ) const
-{
- return( GetLongField( GetFieldNo( FieldName )));
-}
-/************************************************************************/
-//! Put a long value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutLongField( xbShort FieldNo, xbLong Val )
-{
- char buf[18];
- memset( buf, 0x00, 18 );
- sprintf( buf, "%ld", Val );
- return( PutField( FieldNo, buf ));
-}
-/************************************************************************/
-//! Put a long value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutLongField(const char *FieldName, xbLong Val) {
- return ( PutLongField( GetFieldNo( FieldName ), Val ));
-}
-/************************************************************************/
-//! Get the float value of the specified field.
-/*!
-*/
-xbFloat xbDbf::GetFloatField( xbShort FieldNo )
-{
- char buf[21];
- memset( buf, 0x00, 21 );
- if( GetField( FieldNo, buf ) != 0 )
- return atof( buf );
- else
- return 0;
-}
-/************************************************************************/
-//! Get the float value of the specified field.
-/*!
-*/
-xbFloat xbDbf::GetFloatField(const char * FieldName) {
- xbShort fnum;
- if((fnum = GetFieldNo(FieldName)) != -1)
- return GetFloatField(fnum);
- else
- return 0;
-}
-/************************************************************************/
-//! Put a float value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutFloatField( xbShort FldNo, xbFloat f )
-{
- char buf[25];
- char buf2[12];
- memset( buf, 0x00, 25 );
- memset( buf2, 0x00, 12 );
- sprintf( buf, "%d.%df", GetFieldLen( FldNo ), GetFieldDecimal( FldNo ));
- strcpy( buf2, "%-" );
- strcat( buf2, buf );
- sprintf( buf, buf2, f );
-
- /* remove trailing space */
- xbShort i = 0;
- while( i < 25 )
- if( buf[i] == 0x20 ){
- buf[i] = 0x00;
- break;
- } else
- i++;
- return PutField( FldNo, buf );
-}
-/************************************************************************/
-//! Put a float value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutFloatField(const char *FieldName, xbFloat f) {
- xbShort fnum;
- if ((fnum = GetFieldNo(FieldName)) != -1)
- return PutFloatField(fnum, f);
- else
- return 0;
-}
-/************************************************************************/
-//! Get the double value of the specified field.
-/*!
-*/
-xbDouble xbDbf::GetDoubleField( xbShort FieldNo, xbShort RecBufSw )
-{
- char buf[21];
- memset( buf, 0x00, 21 );
- if( GetField( FieldNo, buf, RecBufSw ) != 0 )
- return strtod( buf, NULL );
- else
- return 0;
-}
-/************************************************************************/
-//! Get the double value of the specified field.
-/*!
-*/
-xbDouble xbDbf::GetDoubleField(const char *FieldName) {
- xbShort fnum;
- if ((fnum = GetFieldNo(FieldName)) != -1)
- return GetDoubleField(fnum);
- else
- return 0;
-}
-/************************************************************************/
-//! Put a double value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutDoubleField( xbShort FieldNo, xbDouble d) {
- return PutFloatField(FieldNo, (xbFloat)d);
-}
-/************************************************************************/
-//! Put a double value into the specified field.
-/*!
-*/
-xbShort xbDbf::PutDoubleField(const char *FieldName, xbDouble d) {
- xbShort fnum;
- if ((fnum = GetFieldNo(FieldName)) != -1)
- return PutFloatField(fnum, (xbFloat)d);
- else
- return 0;
-}
-/************************************************************************/
-//! Get the logical value of the specified field.
-/*!
-*/
-xbShort xbDbf::GetLogicalField( xbShort FieldNo )
-{
- char buf[3];
- if( GetFieldType( FieldNo ) != 'L' ) return -1;
- memset( buf, 0x00, 3 );
- GetField( FieldNo, buf );
- if( buf[0] == 'Y' || buf[0] == 'y' || buf[0] == 'T' || buf[0] == 't' )
- return 1;
- else
- return 0;
-}
-/************************************************************************/
-//! Get the logical value of the specified field.
-/*!
-*/
-xbShort xbDbf::GetLogicalField( const char * FieldName )
-{
- xbShort fnum;
- if(( fnum = GetFieldNo( FieldName )) != -1 )
- return GetLogicalField( fnum );
- else
- return -1;
-}
-/************************************************************************/
-//! Get the string value of the specified field.
-/*!
-*/
-char * xbDbf::GetStringField( const char * FieldName )
-{
- return GetStringField(GetFieldNo(FieldName));
-}
-/************************************************************************/
-//! Get the string value of the specified field.
-/*!
-*/
-char * xbDbf::GetStringField( xbShort FieldNo )
-{
- /* allocate memory if needed */
- if( !SchemaPtr[FieldNo].fp )
- SchemaPtr[FieldNo].fp = new char[GetFieldLen(FieldNo)+1];
-
- if( !SchemaPtr[FieldNo].fp )
- return 0;
-
- GetField( FieldNo, SchemaPtr[FieldNo].fp );
- return SchemaPtr[FieldNo].fp;
-}
-/************************************************************************/
diff --git a/xbase64/xbfile.cpp b/xbase64/xbfile.cpp
deleted file mode 100755
index 0064a88..0000000
--- a/xbase64/xbfile.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* xbfile.cpp
-
- Xbase64 project source code
-
- This file contains logic for the basic Xbase class.
-
- Copyright (C) 1997,2003,2004 Gary A Kunkel
- Sergiy Yakovin
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbfile.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-xbString xbFile::MakeFileName(const char *name)
-{
- xbString file=name;
- if (file.isEmpty()) return file;
- int len=strlen(name);
- const char *extLower=GetExtWithDot(true);
- const char *extUpper=GetExtWithDot(false);
- int lenLower=strlen(extLower);
- int lenUpper=strlen(extUpper);
- if (len>lenLower && strcmp(&name[len-lenLower], extLower)==0 ||
- len>lenUpper && strcmp(&name[len-lenUpper], extUpper)==0) return file;
- char lastSymbol=name[len-1];
- file+=GetExtWithDot(lastSymbol<'A' || lastSymbol>'Z');
- return file;
-}
-
diff --git a/xbase64/xbfile.h b/xbase64/xbfile.h
deleted file mode 100755
index 50c69e9..0000000
--- a/xbase64/xbfile.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* xbfile.h
-
- Xbase project source code
-
- This file conatains a header file for the xbLock virtual objects which
- is used for controlling file and record locking. Record and file
- locking has been rewritten in version 3.
-
- Copyright (C) 1997,2003,2004 Gary A Kunkel
- Sergio Yakovin
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-/*! \file xblock.h
-*/
-
-#ifndef __XB_FILE_H__
-#define __XB_FILE_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-class XBDLLEXPORT xbFile
-{
- public:
- xbFile(){}
- virtual const char* GetExtWithDot(bool lower)=0;
- const xbString& GetFileName() {return fileName_;}
- xbString MakeFileName(const char* filename);
-
- protected:
- void SetFileName(const char *filename)
- {
- fileName_=MakeFileName(filename);
- }
-
- private:
- xbString fileName_;
-};
-
-#endif // XBFILE_H
diff --git a/xbase64/xbfilter.cpp b/xbase64/xbfilter.cpp
deleted file mode 100755
index 104e113..0000000
--- a/xbase64/xbfilter.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* xbfilter.cpp
-
- Xbase project source code
-
- This file conatains logic for the xbfilter class.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbfilter.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-//#include <xbase64/xbexcept.h>
-
-/*! \file xbfilter.cpp
-*/
-
-#ifdef XB_FILTERS
-/************************************************************************/
-//! Constructor.
-/*!
- \param dbf
- \param index
- \param exp
-*/
-xbFilter::xbFilter( xbDbf * dbf, xbIndex * index, char * exp )
-{
- xbShort rc;
- Status = 0;
- CurFilterRecNo = 0L;
- d = dbf;
- i = index;
-// e = 0;
-
-
- flExpn = new xbExpn( d->xbase );
- if(( rc = flExpn->ParseExpression( exp, d )) != XB_NO_ERROR )
- Status = rc;
- else{
- if( flExpn->GetExpressionResultType() != 'L' )
- Status = XB_PARSE_ERROR;
- }
-}
-
-/***********************************************************************/
-//! Destructor.
-/*!
-*/
-xbFilter::~xbFilter()
-{
- if( flExpn )
- delete flExpn;
-}
-
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbFilter::GetFirstFilterRec()
-{
- xbShort rc;
-
- if( Status )
- return Status;
-
- if( i )
- rc = i->GetFirstKey();
- else
- rc = d->GetFirstRecord();
-
- while( rc == XB_NO_ERROR ){
- if(( rc = flExpn->ProcessExpression()) != XB_NO_ERROR )
- return rc;
-
- if( flExpn->GetIntResult() )
- {
- CurFilterRecNo = d->GetCurRecNo();
- return XB_NO_ERROR;
- }
- if( i )
- rc = i->GetNextKey();
- else
- rc = d->GetNextRecord();
- }
- return rc;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbFilter::GetLastFilterRec()
-{
- xbShort rc;
-
- if( Status )
- return Status;
-
- if( i )
- rc = i->GetLastKey();
- else
- rc = d->GetLastRecord();
-
- while( rc == XB_NO_ERROR ){
- if(( rc = flExpn->ProcessExpression()) != XB_NO_ERROR )
- return rc;
-
- if( flExpn->GetIntResult() )
- {
- CurFilterRecNo = d->GetCurRecNo();
- return XB_NO_ERROR;
- }
- if( i )
- rc = i->GetPrevKey();
- else
- rc = d->GetPrevRecord();
- }
- return rc;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbFilter::GetNextFilterRec()
-{
- xbShort rc;
-
- if( Status )
- return Status;
-
- if( !CurFilterRecNo )
- return GetFirstFilterRec();
-
- if( i ){
- rc = i->GetNextKey();
- }
- else
- rc = d->GetNextRecord();
-
- while( rc == XB_NO_ERROR ){
- if(( rc = flExpn->ProcessExpression()) != XB_NO_ERROR )
- return rc;
-
- if( flExpn->GetIntResult())
- {
- CurFilterRecNo = d->GetCurRecNo();
- return XB_NO_ERROR;
- }
- if( i )
- rc = i->GetNextKey();
- else
- rc = d->GetNextRecord();
- }
- return rc;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbFilter::GetPrevFilterRec()
-{
- xbShort rc;
-
- if( Status )
- return Status;
-
- if( !CurFilterRecNo )
- return GetLastFilterRec();
-
- if( i ){
- rc = i->GetPrevKey();
- }
- else
- rc = d->GetPrevRecord();
-
- while( rc == XB_NO_ERROR ){
- if(( rc = flExpn->ProcessExpression()) != XB_NO_ERROR )
- return rc;
-
- if( flExpn->GetIntResult())
- {
- CurFilterRecNo = d->GetCurRecNo();
- return XB_NO_ERROR;
- }
- if( i )
- rc = i->GetPrevKey();
- else
- rc = d->GetPrevRecord();
- }
- return rc;
-}
-/***********************************************************************/
-#endif // XB_FILTERS_ON
diff --git a/xbase64/xbfilter.h b/xbase64/xbfilter.h
deleted file mode 100755
index 578a1da..0000000
--- a/xbase64/xbfilter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* xbfilter.h
-
- Xbase project source code
-
- This file conatains a header file for the xbFilter object which
- is used for filtering data.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-/*! \file xbfilter.h
-*/
-
-#ifndef __XB_FILTER_H__
-#define __XB_FILTER_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-//! xbFilter class
-/*!
-*/
-
-class XBDLLEXPORT xbFilter
-{
-public:
- xbFilter( xbDbf * dbf, xbIndex * index, char * expression );
- virtual ~xbFilter();
-
- xbShort GetFirstFilterRec();
- xbShort GetLastFilterRec();
- xbShort GetNextFilterRec();
- xbShort GetPrevFilterRec();
- xbShort GetStatus() { return Status; }
-
-protected:
- xbULong CurFilterRecNo;
- xbShort Status;
- xbExpn * flExpn;
- xbDbf *d;
- xbIndex *i;
-};
-
-#endif
diff --git a/xbase64/xbindex.cpp b/xbase64/xbindex.cpp
deleted file mode 100755
index f3a9c17..0000000
--- a/xbase64/xbindex.cpp
+++ /dev/null
@@ -1,220 +0,0 @@
-/* xbindex.cpp
-
- Xbase64 project source code
-
- This file contains the implementation of the xbIndex class.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbindex.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/*! \file xbindex.cpp
-*/
-
-#ifdef XB_INDEX_ANY
-//! Constructor
-/*!
- \param pdbf
-*/
-xbIndex::xbIndex(xbDbf * pdbf)
-{
- index = this;
- dbf = pdbf;
-// ExpressionTree = NULL;
- IxExp = NULL;
- indexfp = NULL;
-// IndexStatus = 0;
- CurDbfRec = 0L;
- KeyBuf = NULL;
- KeyBuf2 = NULL;
-#ifdef XB_LOCKING_ON
- LockCnt = 0;
-
- CurLockCount = 0;
- CurLockType = -1;
-#endif // XB_LOCKING_ON
-}
-
-/*************************************************************************/
-
-//! Destructor
-/*!
- \param pdbf
-*/
-xbIndex::~xbIndex()
-{
- if( IxExp ){
- delete IxExp;
- IxExp = NULL;
- }
-}
-/*************************************************************************/
-
-void xbIndex::Flush()
-{
- if(indexfp) fflush(indexfp);
-}
-
-/*************************************************************************/
-xbShort xbIndex::OpenIndex(const char* FileName)
-{
- if (IsOpen()) return XB_ALREADY_OPEN;
-
- int rc;
-
- SetFileName(FileName);
-
- /* open the file */
- if(( indexfp = fopen( GetFileName(), "r+b" )) == NULL ){
- //
- // Try to open read only if can't open read/write
- //
- if(( indexfp = fopen( GetFileName(), "rb" )) == NULL )
- return XB_OPEN_ERROR;
- }
-
-#ifdef XB_LOCKING_ON
- /*
- ** Must turn off buffering when multiple programs may be accessing
- ** index files.
- */
- setbuf( indexfp, NULL );
-#endif
-
-// IndexStatus = 1;
- if(( rc = GetHeadNode()) != 0){
- fclose( indexfp );
- return rc;
- }
-
- /* parse the expression */
-/* pre 3.0
- if(( rc = dbf->xbase->BuildExpressionTree( HeadNode.KeyExpression,
- strlen( HeadNode.KeyExpression ), dbf )) != XB_NO_ERROR ){
- return rc;
- }
- ExpressionTree = dbf->xbase->GetTree();
- dbf->xbase->SetTreeToNull();
-*/
- IxExp = new xbExpn( dbf->xbase );
- if(( rc = IxExp->BuildExpressionTree( GetKeyExpression(),
- strlen( GetKeyExpression() ), dbf )) != XB_NO_ERROR ){
- fclose( indexfp );
- return rc;
- }
-
- rc=AllocKeyBufs();
- if(rc){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- fclose(indexfp);
- return rc;
- }
-
-#ifdef XBASE_DEBUG
-// CheckIndexIntegrity( 0 );
-#endif
-
-#ifdef XB_LOCKING_ON
- //if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
-
- rc = dbf->AddIndexToIxList( index, GetFileName() );
- return rc;
-}
-/*************************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbIndex::AllocKeyBufs()
-{
- KeyBuf = (char *) malloc( GetKeyLen() + 1 );
- if(KeyBuf==NULL) {
- return XB_NO_MEMORY;
- };
- KeyBuf2 = (char *) malloc( GetKeyLen() + 1);
- if(KeyBuf2==NULL) {
- free(KeyBuf);
- return XB_NO_MEMORY;
- };
- memset( KeyBuf, 0x00, GetKeyLen() + 1 );
- memset( KeyBuf2, 0x00, GetKeyLen() + 1 );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-
-xbShort xbIndex::CloseIndex( void )
-{
- if(KeyBuf){
- free(KeyBuf);
- KeyBuf = NULL;
- }
- if(KeyBuf2){
- free(KeyBuf2);
- KeyBuf2 = NULL;
- }
-
- dbf->RemoveIndexFromIxList( index ); // why not 'this'?
- FreeNodesMemory();
- if( IxExp ){
- delete IxExp;
- IxExp = 0;
- }
-
- if(indexfp){
- fclose( indexfp );
- indexfp = NULL;
- }
-// IndexStatus = 0;
- return 0;
-}
-/***********************************************************************/
-
-#endif // XB_INDEX_ANY
diff --git a/xbase64/xbindex.h b/xbase64/xbindex.h
deleted file mode 100755
index 69f55dc..0000000
--- a/xbase64/xbindex.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* xbindex.h
-
- Xbase64 project source code
-
- This file contains a header file for the NTX object, which is used
- for handling NTX type indices. NTX are the Clipper equivalant of xbNdx
- files.
-
- Copyright (C) 1998 SynXis Corp., Bob Cotton
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XB_INDEX_H__
-#define __XB_INDEX_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#include <xbase64/xbase64.h>
-#include <string.h>
-/*! \file xbindex.h
-*/
-
-#define XB_UNIQUE 1
-#define XB_NOT_UNIQUE 0
-
-//! xbIndex class
-/*!
-*/
-
-class XBDLLEXPORT xbIndex: protected xbFile
-{
- public:
- xbIndex() {}
- xbIndex(xbDbf *);
-
- virtual ~xbIndex();
-
- xbShort OpenIndex ( const char * );
- xbShort CloseIndex();
- virtual xbShort CreateIndex( const char *, const char *, xbShort, xbShort ) = 0;
- virtual xbLong GetTotalNodes() = 0;
- virtual xbULong GetCurDbfRec() = 0;
- virtual xbShort CreateKey( xbShort, xbShort ) = 0;
- virtual xbShort GetCurrentKey(char *key) = 0;
- virtual xbShort AddKey( xbLong ) = 0;
- virtual xbShort UniqueIndex() = 0;
- virtual xbShort DeleteKey( xbLong ) = 0;
- virtual xbShort KeyWasChanged() = 0;
- virtual xbShort FindKey( const char * ) = 0;
- virtual xbShort FindKey() = 0;
- virtual xbShort FindKey( xbDouble ) = 0;
- virtual xbShort GetNextKey() = 0;
- virtual xbShort GetLastKey() = 0;
- virtual xbShort GetFirstKey() = 0;
- virtual xbShort GetPrevKey() = 0;
- virtual xbShort ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0) = 0;
-// virtual xbShort KeyExists( char * Key ) { return FindKey( Key, strlen( Key ), 0 ); }
- virtual xbShort KeyExists( xbDouble ) = 0;
- virtual xbShort TouchIndex() { return XB_NO_ERROR; }
- virtual void SetNodeSize(xbShort size) {}
- virtual xbShort GetNodeSize() { return NodeSize; }
- virtual void GetExpression(char *buf, int len) = 0;
- virtual void Flush();
- virtual const char * GetIxName() {return GetFileName().getData();}
- xbShort AllocKeyBufs();
- xbBool IsOpen() {return indexfp!=NULL;}
-
-#ifdef XBASE_DEBUG
- virtual void DumpHdrNode( xbShort Option ) = 0;
- virtual void DumpNodeRec( xbLong ) = 0;
- virtual void DumpNodeChain() = 0;
- virtual xbShort CheckIndexIntegrity( xbShort ) = 0;
-#endif
-
-#ifdef XB_LOCKING_ON
-// xbShort LockIndex( xbShort LockType );
-// virtual xbShort LockIndex( const xbShort, const xbShort );
-#else
-// virtual xbShort LockIndex( const xbShort, const xbShort ) const { return XB_NO_ERROR; }
-#endif
-
- protected:
- virtual xbShort GetHeadNode()=0;
- virtual xbUShort GetKeyLen()=0;
- virtual const char* GetKeyExpression()=0;
- virtual void FreeNodesMemory()=0;
-
- xbIndex *index;
- xbDbf *dbf;
- xbExpn *IxExp; /* index expression defines keys */
- FILE *indexfp; /* NULL = closed, other = open */
-// int IndexStatus; /* old - 0 = closed, 1 = open */
- xbULong CurDbfRec; /* current Dbf record number */
- char *KeyBuf; /* work area key buffer */
- char *KeyBuf2; /* work area key buffer */
- xbShort NodeSize;
-
-#ifdef XB_LOCKING_ON
- int LockCnt; /* current index lock count */
- int CurLockCount; /* old locking field */
- int CurLockType; /* old locking field */
-#endif
-};
-
-#endif /* __XB_INDEX_H__ */
diff --git a/xbase64/xblock.cpp b/xbase64/xblock.cpp
deleted file mode 100755
index c44cbb9..0000000
--- a/xbase64/xblock.cpp
+++ /dev/null
@@ -1,580 +0,0 @@
-/* xblock.cpp
-
- Xbase64 project source code
- written at 35000 feet on SWA
-
- This file contains the implementation of the xbLock.
-
- This file conatains a header file for the xbLock virtual objects which
- is used for controlling file and record locking. Record and file
- locking has been rewritten in version 3.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xblock.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-#ifdef HAVE_IO_H // windows locking
-#include <io.h>
-#endif
-
-#ifdef HAVE_DOS_H // _sleep
-#include <dos.h>
-#endif
-
-//#include <stdio.h>
-//#include <stdlib.h>
-
-/*! \file xblock.cpp
-*/
-#ifdef XB_LOCKING_ON
-
-//! Constructor
-/*!
- \param pdbf
-*/
-
-/*************************************************************************/
-xbLock::xbLock(xbDbf * pdbf)
-{
- dbf = pdbf;
- HdrLockCnt = 0;
- TableLockCnt = 0;
- MemoLockCnt = 0;
- IndexLockCnt = 0;
- std::cout << "xbLock constructor" << std::cout;
-}
-/*************************************************************************/
-xbLock::~xbLock()
-{
- std::cout << "xbLock destructor" << std::endl;
-}
-/*************************************************************************/
-
-//! File lock routine
-/*!
- Lowest level lock routine
- Locks/unlocks a database,memo or index file.
- This function assumes the file position has been correctly set
-
- \param fn file to lock/unlock
- \param LockType lock type, one of: XB_LOCK or XB_UNLOCK
- \param lockLen byte count to lock
-*/
-
-#ifdef __WIN32__
-xbShort xbLock::LockFile( int fn, xbShort LockType, xbOffT lockLen)
-{
- int mode;
- int rc;
- int tries = 0;
-
- /* convert the xbase locking command into a windows locking command */
- if( LockType == XB_UNLOCK )
- mode = LK_UNLCK;
- else if( LockType == XB_LOCK || LockType == XB_LOCK_HOLD )
- mode = LK_NBLCK;
- else
- return XB_INVALID_LOCK_OPTION;
-
- do{
- rc = locking( fn, mode, lockLen );
- if( rc )
- _sleep( 1 );
- } while( rc == -1 && tries < dbf->xbase->GetLockRetryCount());
-
- if( rc )
- return XB_LOCK_FAILED;
-
- return 0;
-}
-
-#elif HAVE_FCNTL_H
-
-xbShort xbLock::LockFile( int fn, xbShort LockType, xbOffT lockLen )
-{
- xbShort cmd, rc;
- xbShort tries = 0;
-
-/* convert cross platform xbase lock type to unix lock type */
- if( LockType == XB_UNLOCK )
- cmd = F_ULOCK;
-else if( LockType == XB_LOCK || LockType == XB_LOCK_HOLD )
- cmd = F_TLOCK;
- else
- return XB_INVALID_LOCK_OPTION;
-
-/* do the actual lock */
- do{
- #ifdef _LARGEFILE64_SOURCE
- rc = lockf64( fn, cmd, lockLen );
- #else
- rc = lockf( fn, cmd, lockLen );
- #endif
- if( rc == -1 && errno != EINTR ){
- tries++;
- sleep(1);
- }
- } while( rc == -1 && tries < dbf->xbase->GetLockRetryCount());
-
- if( rc )
- return XB_LOCK_FAILED;
-
- return XB_NO_ERROR;
-}
-#endif // HAVE_FCNTL
-/*************************************************************************/
-/*************************************************************************/
-xbaseLock::xbaseLock( xbDbf * pdbf ) : xbLock( pdbf )
-{
- std::cout << "xbaseLock constructor" << std::cout;
-}
-/*************************************************************************/
-xbShort xbaseLock::LockTableHeader( xbShort LockType )
-{
- if( LockType == XB_UNLOCK )
- return XB_NO_ERROR;
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort xbaseLock::LockTable( xbShort LockType )
-{
- if(( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ) && TableLockCnt ){
- TableLockCnt++;
- return XB_NO_ERROR;
- }
- if( LockType == XB_UNLOCK && TableLockCnt > 1 ){
- TableLockCnt--;
- return XB_NO_ERROR;
- }
-
-#ifdef _LARGEFILE64_SOURCE
- if( lseek64( fileno( lfh ), 1, SEEK_SET ) != 1 )
- return XB_LOCK_FAILED;
-
- if( LockFile( fileno( lfh ), LockType, 4294967295LL ) != XB_NO_ERROR )
- return XB_LOCK_FAILED;
-#else
- if( lseek( fileno( lfh ), 1, SEEK_SET ) != 1 )
- return XB_LOCK_FAILED;
-
- if( LockFile( fileno( lfh ), LockType, 4294967295L ) != XB_NO_ERROR )
- return XB_LOCK_FAILED;
-#endif
-
- if( LockType == XB_UNLOCK )
- TableLockCnt--;
- else
- TableLockCnt++;
-
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-xbShort xbaseLock::LockRecord(xbShort LockType,xbULong RecNo,xbOffT RecCnt)
-{
-
-#ifdef _LARGEFILE64_SOURCE
- if( lseek64( fileno( lfh ), 100L + RecNo, SEEK_SET ) == -1 ){
- return XB_LOCK_FAILED;
- }
-#else
- if( lseek( fileno( lfh ), 100L + RecNo, SEEK_SET ) == -1 ){
- return XB_LOCK_FAILED;
- }
-#endif
-
- return LockFile( fileno( lfh ), LockType, (xbOffT) RecCnt );
-}
-/*************************************************************************/
-xbShort xbaseLock::LockMemo( xbShort LockType )
-{
- xbShort rc;
-
- if(( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ) && MemoLockCnt ){
- MemoLockCnt++;
- return XB_NO_ERROR;
- }
- else if ( LockType == XB_UNLOCK && MemoLockCnt > 1 ){
- MemoLockCnt--;
- return XB_NO_ERROR;
- }
-
-#ifdef _LARGEFILE64_SOURCE
- if( lseek64( fileno( lfh ), 2, SEEK_SET ) != 2 )
- return XB_LOCK_FAILED;
-#else
- if( lseek( fileno( lfh ), 2, SEEK_SET ) != 2 )
- return XB_LOCK_FAILED;
-#endif
- rc = LockFile( fileno( lfh ), LockType, 1 );
-
- if( rc == XB_NO_ERROR ){
- if( LockType == XB_UNLOCK )
- MemoLockCnt--;
- else
- MemoLockCnt++;
- }
- return rc;
-}
-/*************************************************************************/
-//! Lock Index
-/*!
- Locks all indices for a table when using lock mode XB_XBASE_LOCK_MODE
-
- \param LockType is one of XB_LOCK, XB_LOCK_HOLD or XB_UNLOCK
-*/
-
-xbShort xbaseLock::LockIndex( xbShort LockType )
-{
- xbShort rc;
-
-// if( !NdxList )
-// printf( "no index\n" );
-
- if(( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ) && IndexLockCnt ){
- IndexLockCnt++;
- return XB_NO_ERROR;
- }
- if( LockType == XB_UNLOCK && IndexLockCnt > 1 ){
- IndexLockCnt--;
- return XB_NO_ERROR;
- }
-
-#ifdef _LARGEFILE64_SOURCE
- if( lseek64( fileno( lfh ), 3, SEEK_SET ) == -1 ){
- printf( "here cp1\n");
- return XB_LOCK_FAILED;
- }
-#else
- if( lseek( fileno( lfh ), 3, SEEK_SET ) == -1 ){
- printf( "here cp2\n" );
- return XB_LOCK_FAILED;
- }
-#endif
-
- rc = LockFile( fileno( lfh ), LockType, 1 );
-
- if( rc == XB_NO_ERROR )
- if( LockType == XB_UNLOCK )
- IndexLockCnt--;
- else
- IndexLockCnt++;
-
- return rc;
-}
-/*************************************************************************/
-xbShort xbaseLock::UnlockAll()
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/************************************************************************/
-xbShort xbaseLock::LockInit()
-{
- xbShort len;
- xbString lfn;
-
- lfn = dbf->GetDbfName();
- lfn.resize( lfn.len() - 3 );
-
- lfn += ".lck";
-
-#ifdef _LARGEFILE_SOURCE
- if(( lfh = fopen64( lfn.getData(), "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-#else
- if(( lfh = fopen( lfn.getData(), "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-#endif
-
- else
- return XB_NO_ERROR;
-}
-
-/*************************************************************************/
-/*************************************************************************/
-dbaseLock::dbaseLock( xbDbf * pdbf ) : xbLock( pdbf )
-{
- std::cout << "dbaseLock constructor" << std::cout;
-}
-/*************************************************************************/
-xbShort dbaseLock::LockTableHeader( xbShort LockType )
-{
- if( LockType == XB_UNLOCK )
- return XB_NO_ERROR;
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort dbaseLock::LockTable( xbShort LockType )
-{
-
- if(( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ) && TableLockCnt ){
- TableLockCnt++;
- return XB_NO_ERROR;
- }
- if( LockType == XB_UNLOCK && TableLockCnt > 1 ){
- TableLockCnt--;
- return XB_NO_ERROR;
- }
-
-#ifdef _LARGEFILE64_SOURCE
- if( lseek64( dbf->GetDbfFileNo(), 4026531838LL, SEEK_SET ))
- return XB_LOCK_FAILED;
-
- if( LockFile( dbf->GetDbfFileNo(), LockType, 1 ) != XB_NO_ERROR )
- return XB_LOCK_FAILED;
-
- if( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ){
- if( LockRecord( XB_LOCK, 1, 4294967295LL ) != XB_NO_ERROR )
- return LockTable( XB_UNLOCK );
- LockRecord( XB_UNLOCK, 1, 4294967295LL );
- }
-
- if( LockType == XB_UNLOCK )
- TableLockCnt--;
- else
- TableLockCnt++;
-
- return XB_NO_ERROR;
-#else
- /* I couldn't figure out how Dbase locks a file at offset 4026531838
- for a 32 bit platform - if you know how, please let me know
-
- Gary - gkunkel@zhsac.com
-
- */
-
- return XB_INVALID_LOCK_OPTION;
-#endif
-
-}
-
-/*************************************************************************/
-xbShort dbaseLock::LockRecord( xbShort LockType, xbULong RecNo, xbOffT RecCnt )
-{
-#ifdef _LARGEFILE64_SOURCE
-
- if( lseek64( dbf->GetDbfFileNo(), 4026531838LL - (RecNo+RecCnt-1), SEEK_SET ) == -1 )
- return XB_LOCK_FAILED;
-
- return LockFile( dbf->GetDbfFileNo(), LockType, RecCnt );
-
-#else
-
- /* I couldn't figure out how dbase locks a file at offset 4026531838
- for a 32 bit platform - if you know how, please let me know
-
- Gary - gkunkel@zhsac.com
-
- */
-
- return XB_INVALID_LOCK_OPTION;
-#endif
-}
-
-/*************************************************************************/
-xbShort dbaseLock::LockMemo( xbShort LockType )
-{
-
- xbShort rc;
-
- if(( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ) && MemoLockCnt ){
- MemoLockCnt++;
- return XB_NO_ERROR;
- }
- else if ( LockType == XB_UNLOCK && MemoLockCnt > 1 ){
- MemoLockCnt--;
- return XB_NO_ERROR;
- }
-
-#ifdef _LARGEFILE_SOURCE
- if( lseek64( dbf->GetMemoFileNo(), 4026531838LL, SEEK_SET ) == -1 )
- return XB_LOCK_FAILED;
- rc = LockFile( dbf->GetMemoFileNo(), LockType, 1 );
-#else
- rc = XB_INVALID_OPTION;
-#endif
-
- if( rc == XB_NO_ERROR ){
- if( LockType == XB_UNLOCK )
- MemoLockCnt--;
- else
- MemoLockCnt++;
- }
- return rc;
-}
-/*************************************************************************/
-xbShort dbaseLock::LockIndex( xbShort LockType )
-{
- if( LockType == XB_NO_ERROR )
- return XB_NO_ERROR;
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort dbaseLock::UnlockAll()
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-/*************************************************************************/
-clipperLock::clipperLock( xbDbf * pdbf ) : xbLock( pdbf )
-{
- std::cout << "clipperLock constructor" << std::cout;
-}
-/*************************************************************************/
-xbShort clipperLock::LockTableHeader( xbShort LockType )
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort clipperLock::LockTable( xbShort LockType )
-{
- if(( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ) && TableLockCnt ){
- TableLockCnt++;
- return XB_NO_ERROR;
- }
- if( LockType == XB_UNLOCK && TableLockCnt > 1 ){
- TableLockCnt--;
- return XB_NO_ERROR;
- }
-
- if( LockRecord( LockType, 1L, 1000000000L ) != XB_NO_ERROR )
- return XB_LOCK_FAILED;
-
- if( LockType == XB_UNLOCK )
- TableLockCnt--;
- else
- TableLockCnt++;
-
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-xbShort clipperLock::LockRecord(
- xbShort LockType, xbULong RecNo, xbOffT RecCnt )
-{
-
-#ifdef _LARGEFILE64_SOURCE
- if( lseek64( dbf->GetDbfFileNo(), 1000000000L + RecNo, SEEK_SET ))
- return XB_LOCK_FAILED;
-#else
- if( lseek( dbf->GetDbfFileNo(), 1000000000L + RecNo, SEEK_SET ))
- return XB_LOCK_FAILED;
-#endif
-
- return LockFile( dbf->GetDbfFileNo(), LockType, RecCnt );
-}
-/*************************************************************************/
-xbShort clipperLock::LockMemo( xbShort LockType )
-{
- return XB_NO_ERROR;
-}
-/*************************************************************************/
-xbShort clipperLock::LockIndex( xbShort LockType )
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort clipperLock::UnlockAll()
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-/*************************************************************************/
-foxproLock::foxproLock( xbDbf * pdbf ) : xbLock( pdbf )
-{
- std::cout << "foxproLock constructor" << std::cout;
-}
-/*************************************************************************/
-xbShort foxproLock::LockTableHeader( xbShort LockType )
-{
-
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort foxproLock::LockTable( xbShort LockType )
-{
-
- if(( LockType == XB_LOCK || LockType == XB_LOCK_HOLD ) && TableLockCnt ){
- TableLockCnt++;
- return XB_NO_ERROR;
- }
- if( LockType == XB_UNLOCK && TableLockCnt > 1 ){
- TableLockCnt--;
- return XB_NO_ERROR;
- }
-
-
-// something goes in here
-
-
- if( LockType == XB_UNLOCK )
- TableLockCnt--;
- else
- TableLockCnt++;
-
- return XB_NO_ERROR;
-
-}
-/*************************************************************************/
-xbShort foxproLock::LockRecord( xbShort LockType, xbULong RecNo, xbOffT len )
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort foxproLock::LockMemo( xbShort LockType )
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort foxproLock::LockIndex( xbShort LockType )
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-xbShort foxproLock::UnlockAll()
-{
- return XB_INVALID_LOCK_OPTION;
-}
-/*************************************************************************/
-
-#endif // XB_LOCKING_ON
-
diff --git a/xbase64/xblock.h b/xbase64/xblock.h
deleted file mode 100755
index 50dfcf2..0000000
--- a/xbase64/xblock.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* xblock.h
-
- Xbase project source code
-
- This file conatains a header file for the xbLock virtual objects which
- is used for controlling file and record locking. Record and file
- locking has been rewritten in version 3.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-/*! \file xblock.h
-*/
-
-#ifndef __XB_XBLOCK_H__
-#define __XB_XBLOCK_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#ifdef XB_LOCKING_ON
-
-//! xbLock class
-/*!
-*/
-
-class XBDLLEXPORT xbLock
-{
-public:
- xbLock( xbDbf * dbf );
- virtual ~xbLock();
- virtual xbShort LockTableHeader( xbShort LockType ) = 0;
- virtual xbShort LockTable( xbShort LockType ) = 0;
- virtual xbShort LockRecord( xbShort LockType, xbULong RecNo, xbOffT len ) = 0;
- virtual xbShort LockMemo( xbShort LockType ) = 0;
- virtual xbShort LockIndex( xbShort LockType ) = 0;
- virtual xbShort UnlockAll() = 0;
- virtual xbShort LockInit() { return XB_NO_ERROR; }
-
-protected:
- xbDbf *dbf;
- xbShort HdrLockCnt;
- xbShort TableLockCnt;
- xbShort MemoLockCnt;
- xbShort IndexLockCnt;
- xbShort LockFile( int fn, xbShort LockType, xbOffT lockLen );
-};
-
-class XBDLLEXPORT xbaseLock : xbLock
-{
-public:
- xbaseLock( xbDbf * pdbf );
- virtual ~xbaseLock() {}
- virtual xbShort LockTableHeader( xbShort LockType );
- virtual xbShort LockTable( xbShort LockType );
- virtual xbShort LockRecord( xbShort LockType, xbULong RecNo, xbOffT len );
- virtual xbShort LockMemo( xbShort LockType );
- virtual xbShort LockIndex( xbShort LockType );
- virtual xbShort UnlockAll();
- virtual xbShort LockInit();
-private:
- FILE *lfh; /* lock file handle */
-
-};
-
-class XBDLLEXPORT dbaseLock : xbLock
-{
-public:
- dbaseLock( xbDbf * pdbf );
- virtual ~dbaseLock() {}
- virtual xbShort LockTableHeader( xbShort LockType );
- virtual xbShort LockTable( xbShort LockType );
- virtual xbShort LockRecord( xbShort LockType, xbULong RecNo, xbOffT len );
- virtual xbShort LockMemo( xbShort LockType );
- virtual xbShort LockIndex( xbShort LockType );
- virtual xbShort UnlockAll();
-};
-
-
-class XBDLLEXPORT clipperLock : xbLock
-{
-public:
- clipperLock( xbDbf * pdbf );
- virtual ~clipperLock() {}
- virtual xbShort LockTableHeader( xbShort LockType );
- virtual xbShort LockTable( xbShort LockType );
- virtual xbShort LockRecord( xbShort LockType, xbULong RecNo, xbOffT len );
- virtual xbShort LockMemo( xbShort LockType );
- virtual xbShort LockIndex( xbShort LockType );
- virtual xbShort UnlockAll();
-};
-
-class XBDLLEXPORT foxproLock : xbLock
-{
-public:
- foxproLock( xbDbf * pdbf );
- virtual ~foxproLock() {}
- virtual xbShort LockTableHeader( xbShort LockType );
- virtual xbShort LockTable( xbShort LockType );
- virtual xbShort LockRecord( xbShort LockType, xbULong RecNo, xbOffT len );
- virtual xbShort LockMemo( xbShort LockType );
- virtual xbShort LockIndex( xbShort LockType );
- virtual xbShort UnlockAll();
-};
-
-class XBDLLEXPORT noLock : xbLock
-{
-public:
- noLock( xbDbf * pdbf ) : xbLock( pdbf ) {};
- virtual ~noLock() {}
- virtual xbShort LockTableHeader( xbShort LockType )
- { return XB_NO_ERROR; }
- virtual xbShort LockTable( xbShort LockType )
- { return XB_NO_ERROR; }
- virtual xbShort LockRecord( xbShort LockType, xbULong RecNo )
- { return XB_NO_ERROR; }
- virtual xbShort LockMemo( xbShort LockType )
- { return XB_NO_ERROR; }
- virtual xbShort LockIndex( xbShort LockType )
- { return XB_NO_ERROR; }
- virtual xbShort UnlockAll()
- { return XB_NO_ERROR; }
-};
-
-
-
-
-#endif // XB_LOCKING_ON
-#endif // __XB_XBLOCK_H__
diff --git a/xbase64/xbmemo.cpp b/xbase64/xbmemo.cpp
deleted file mode 100755
index 75956dd..0000000
--- a/xbase64/xbmemo.cpp
+++ /dev/null
@@ -1,1173 +0,0 @@
-/* xbmemo.cpp
-
- Xbase64 project source code
-
- This file contains the basic Xbase64 routines for handling
- dBASE III+ and dBASE IV style memo .dbt files
-
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-#ifdef XB_MEMO_FIELDS
-
-#include <stdio.h>
-//#include <xbase64/xbexcept.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-
-/*! \file xbmemo.cpp
-*/
-
-/************************************************************************/
-//! Short description
-/*!
-*/
-xbLong xbDbf::CalcLastDataBlock()
-{
- if( _fseek( mfp, 0, SEEK_END ) != 0 )
- return XB_SEEK_ERROR;
- return ( _ftell( mfp ) / MemoHeader.BlockSize );
-}
-/************************************************************************/
-//! Short description
-/*!
- \param BlocksNeeded
- \param Location
- \param PrevNode
-*/
-xbShort xbDbf::GetBlockSetFromChain( xbLong BlocksNeeded,
- xbLong Location, xbLong PrevNode )
-
-/* this routine grabs a set of blocks out of the free block chain */
-{
- xbShort rc;
- xbLong NextFreeBlock2, NewFreeBlocks, SaveNextFreeBlock;
-
- if(( rc = ReadMemoBlock( Location, 2 )) != XB_NO_ERROR )
- return rc;
-
- if( BlocksNeeded == FreeBlockCnt ){ /* grab this whole set of blocks */
- if( PrevNode == 0 ){ /* first in the chain */
- MemoHeader.NextBlock = NextFreeBlock;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR )
- return rc;
- }
- else /* remove out of the middle or end */
- {
- NextFreeBlock2 = NextFreeBlock;
- if(( rc = ReadMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )
- return rc;
- NextFreeBlock = NextFreeBlock2;
- if(( rc = WriteMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )
- return rc;
- }
- }
-
- else /* only take a portion of this set */
- {
- if( PrevNode == 0 ){ /* first in the set */
- MemoHeader.NextBlock = Location + BlocksNeeded;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR )
- return rc;
- FreeBlockCnt -= BlocksNeeded;
- if(( rc = WriteMemoBlock( MemoHeader.NextBlock, 2 )) != XB_NO_ERROR )
- return rc;
- }
- else /* remove out of the middle or end */
- {
- NewFreeBlocks = FreeBlockCnt - BlocksNeeded;
- SaveNextFreeBlock = NextFreeBlock;
- NextFreeBlock2= Location + BlocksNeeded;
- if(( rc = ReadMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )
- return rc;
- NextFreeBlock = NextFreeBlock2;
- if(( rc = WriteMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )
- return rc;
- FreeBlockCnt = NewFreeBlocks;
- NextFreeBlock = SaveNextFreeBlock;
- if(( rc = WriteMemoBlock( NextFreeBlock2, 2 )) != XB_NO_ERROR )
- return rc;
- }
- }
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param BlocksNeeded
- \param LastDataBlock
- \param Location
- \param PreviousNode
-*/
-xbShort xbDbf::FindBlockSetInChain( xbLong BlocksNeeded,
- xbLong LastDataBlock, xbLong &Location, xbLong &PreviousNode )
-
-/* this routine searches thru the free node chain in a dbase IV type
- memo file searching for a place to grab some free blocks for reuse
-
- LastDataBlock- is the last data block in the file, enter 0
- for the routine to calculate it.
- BlocksNeeded - is the size to look in the chain for
- Location - is the location it finds
- PreviousNode - is the block number of the node imediately previous
- to this node in the chain - 0 if header node
- returns - 0 if no spot in chain found
- 1 if spot in chain is found
-*/
-{
- xbShort rc;
- xbLong LDB, PrevNode, CurNode;
-
- if( LastDataBlock == 0 )
- LDB = CalcLastDataBlock();
- else
- LDB = LastDataBlock;
-
- if( MemoHeader.NextBlock < LDB ){
- PrevNode = 0L;
- CurNode = MemoHeader.NextBlock;
- if(( rc = ReadMemoBlock( MemoHeader.NextBlock, 2 )) != XB_NO_ERROR )
- return rc;
- while( BlocksNeeded > FreeBlockCnt && NextFreeBlock < LDB ){
- PrevNode = CurNode;
- CurNode = NextFreeBlock;
- if(( rc = ReadMemoBlock( NextFreeBlock, 2 )) != XB_NO_ERROR )
- return rc;
- }
- if( BlocksNeeded <= FreeBlockCnt ){
- Location = CurNode;
- PreviousNode = PrevNode;
- return 1;
- }
- else{ /* no data found and at end of chain */
- PreviousNode = CurNode;
- return 0;
- }
- }
- else{
- PreviousNode = 0;
- return 0;
- }
-}
-/************************************************************************/
-//! Short description
-/*!
- \param BlockSize
-*/
-xbShort xbDbf::SetMemoBlockSize( xbShort BlockSize )
-{
- if(IsType3Dbt())
- return XB_NO_ERROR; // not applicable for type 3
- if( BlockSize % 512 != 0 )
- return XB_INVALID_BLOCK_SIZE;
-
- MemoHeader.BlockSize = BlockSize;
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param Option
-*/
-xbShort xbDbf::GetDbtHeader( xbShort Option )
-{
- char *p;
- xbShort i;
- char MemoBlock[24];
-
- /* Option = 0 --> read only first four bytes
- 1 --> read the entire thing */
-
- if( !mfp )
- return XB_NOT_OPEN;
-
- if( _fseek( mfp, 0, SEEK_SET ))
- return XB_SEEK_ERROR;
-
- if(( fread( MemoBlock, 24, 1, mfp )) != 1 )
- return XB_READ_ERROR;
-
- p = MemoBlock;
- MemoHeader.NextBlock = xbase->GetLong( p );
- if(IsType3Dbt() || Option == 0)
- return XB_NO_ERROR;
-
- /* version IV stuff follows */
- p+=8;
- for( i = 0; i < 8; i++, p++ )
- MemoHeader.FileName[i] = *p;
- MemoHeader.Version = *p;
- p+=4;
- MemoHeader.BlockSize = xbase->GetShort( p );
- return XB_NO_ERROR;
-}
-
-/***********************************************************************/
-xbShort xbDbf::OpenFPTFile()
-{
- if (GetFileName().len() < 3)
- return XB_INVALID_NAME;
-
- xbShort len = GetFileName().len() - 1;
- xbString ext = GetFileName().mid(len-2, 3);
- MemofileName = GetFileName().mid(0, len-2);
- if (ext == "DBF")
- MemofileName += "FPT";
- else
- if (ext = "dbf")
- MemofileName += "fpt";
- else
- return XB_INVALID_NAME;
- if ((mfp = fopen(MemofileName, "r+b" )) == NULL){
- //
- // Try to open read only if can't open read/write
- //
- if ((mfp = fopen(MemofileName, "rb" )) == NULL)
- return XB_OPEN_ERROR;
- }
- char header[8];
- if ((fread(header, 8, 1, mfp)) != 1)
- return XB_READ_ERROR;
-
- char *p = header;
- MemoHeader.NextBlock = xbase->GetHBFULong(p);
- p += 6;
- MemoHeader.BlockSize = xbase->GetHBFShort(p);
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbDbf::OpenMemoFile()
-{
- if (Version == (char)0xf5 || Version == (char)0x30)
- return OpenFPTFile();
-
- xbShort len, rc;
- xbOffT Size, NewSize, l;
- MemofileName = GetFileName();
- len = GetFileName().len() - 1;
- if( MemofileName[len] == 'F' )
- MemofileName.putAt(len, 'T');
- else if( MemofileName[len] == 'f' )
- MemofileName.putAt(len, 't');
- else
- return XB_INVALID_NAME;
-
- if(( mfp = fopen( MemofileName, "r+b" )) == NULL ){
- //
- // Try to open read only if can't open read/write
- //
- if(( mfp = fopen( MemofileName, "rb" )) == NULL )
- return XB_OPEN_ERROR;
- }
-#ifdef XB_LOCKING_ON
- setbuf( mfp, NULL );
-#endif
- if(( rc = GetDbtHeader(1)) != 0 ){
- fclose( mfp );
- return rc;
- }
-
- len = GetMemoBlockSize();
- if( len == 0 || ((len % 512) != 0 )){
- fclose( mfp );
- return XB_INVALID_BLOCK_SIZE;
- }
-
- /* logic to verify file size is a multiple of block size */
- if(( rc = _fseek( mfp, 0, SEEK_END )) != 0 ){
- fclose( mfp );
- return XB_SEEK_ERROR;
- }
-
- /* if the file is not a multiple of block size, fix it, append nulls */
- Size = _ftell( mfp );
- if(( Size % MemoHeader.BlockSize ) != 0 ){
- NewSize = ( Size / MemoHeader.BlockSize + 1) * MemoHeader.BlockSize;
- for( l = Size; l < NewSize; l++ )
- fputc( 0x00, mfp );
- }
-
- if(( mbb = (void *) malloc(len)) == NULL ){
- fclose( mfp );
- return XB_NO_MEMORY;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbDbf::CreateMemoFile( void )
-{
- xbShort len,i;
- char *sp;
- char buf[4];
-
- len = GetMemoBlockSize();
- if( len == 0 || len % 512 != 0 )
- return XB_INVALID_BLOCK_SIZE;
-
- if(( sp = (char*)strrchr(GetFileName(), PATH_SEPARATOR)) != NULL )
- sp++;
- else
- sp = MemoHeader.FileName;
-
- memset( MemoHeader.FileName, 0x00, 8 );
-
- for( i = 0; i < 8 && *sp != '.'; i++ )
- MemoHeader.FileName[i] = *sp++;
-
- MemofileName = GetFileName();
-
- len = GetFileName().len() - 1;
- if( MemofileName[len] == 'F' )
- MemofileName.putAt(len, 'T');
- else if( MemofileName[len] == 'f' )
- MemofileName.putAt(len, 't');
- else
- return XB_INVALID_NAME;
-
- /* Initialize the variables */
- MemoHeader.NextBlock = 1L;
-
- if(( mfp = fopen( MemofileName, "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-#ifdef XB_LOCKING_ON
- setbuf( mfp, NULL );
-#endif
-
- if(( _fseek( mfp, 0, SEEK_SET )) != 0 ){
- fclose( mfp );
- return XB_SEEK_ERROR;
- }
-
- memset( buf, 0x00, 4 );
- xbase->PutLong( buf, MemoHeader.NextBlock );
- if(( fwrite( &buf, 4, 1, mfp )) != 1 ){
- fclose( mfp );
- return XB_WRITE_ERROR;
- }
-
- if( IsType3Dbt() ){ /* dBASE III+ */
- for( i = 0; i < 12; i++ ) fputc( 0x00, mfp );
- fputc( 0x03, mfp );
- for( i = 0; i < 495; i++ ) fputc( 0x00, mfp );
- }
- else
- {
- for( i = 0; i < 4; i++ ) fputc( 0x00, mfp );
- fwrite( &MemoHeader.FileName, 8, 1, mfp );
- for( i = 0; i < 4; i++ ) fputc( 0x00, mfp );
- memset( buf, 0x00, 2 );
- xbase->PutShort( buf, MemoHeader.BlockSize );
- if(( fwrite( &buf, 2, 1, mfp )) != 1 ){
- fclose( mfp );
- return XB_WRITE_ERROR;
- }
- for( i = 22; i < MemoHeader.BlockSize; i++ ) fputc( 0x00, mfp );
- }
-
- if(( mbb = (void *) malloc( MemoHeader.BlockSize )) == NULL ){
- fclose( mfp );
- return XB_NO_MEMORY;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param BlockNo
- \param Option
-*/
-
-/* Option = 0 - 1st Block of a set of valid data blocks, load buckets */
-/* Option = 1 - subsequant block of data in a multi block set or db III*/
-/* Option = 2 - 1st block of a set of free blocks, load buckets */
-/* Option = 3 - read 8 bytes of a block, don't load any buckets */
-/* Option = 4 - read 8 bytes of a block, load data buckets */
-
-xbShort xbDbf::ReadMemoBlock( xbLong BlockNo, xbShort Option )
-{
- size_t ReadSize;
- CurMemoBlockNo = -1;
-
- if( BlockNo < 1L )
- return XB_INVALID_BLOCK_NO;
-
- if( _fseek( mfp,((xbOffT)BlockNo*MemoHeader.BlockSize), SEEK_SET ))
- return XB_SEEK_ERROR;
-
-
- if( Option == 0 || Option == 1 )
- ReadSize = MemoHeader.BlockSize;
- else
- ReadSize = 8L;
-
- if(fread( mbb, ReadSize, 1, mfp ) != 1 )
- return XB_READ_ERROR;
-
- if( Option == 0 || Option == 4){ // 1st block of a set of valid data blocks
- mfield1 = xbase->GetShort( (char *) mbb );
- MStartPos = xbase->GetShort( (char *) mbb+2 );
- MFieldLen = xbase->GetLong ( (char *) mbb+4 );
- }
- else if( Option == 2 ){ // 1st block of a set of free blocks
- NextFreeBlock = xbase->GetLong( (char *) mbb );
- FreeBlockCnt = xbase->GetLong( (char *) mbb+4 );
- }
-
- if( Option == 0 || Option == 1 )
- CurMemoBlockNo = BlockNo;
-
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param BlockNo
- \param Option
-*/
-xbShort xbDbf::WriteMemoBlock( xbLong BlockNo, xbShort Option )
-{
-/* Option = 0 - 1st Block of a set of valid data blocks, set buckets */
-/* Option = 1 - subsequant block of data in a multi block set or db III */
-/* Option = 2 - 1st block of a set offree blocks, set buckets */
-
- xbLong WriteSize;
-
- if( BlockNo < 1L )
- return XB_INVALID_BLOCK_NO;
-
- CurMemoBlockNo = -1;
-
- if( Option == 0 ){
- xbase->PutShort( (char *) mbb, mfield1 );
- xbase->PutShort( (char *) mbb+2, MStartPos );
- xbase->PutLong ( (char *) mbb+4, MFieldLen );
- WriteSize = MemoHeader.BlockSize;
- }
- else if( Option == 2 ){
- xbase->PutLong((char *) mbb, NextFreeBlock );
- xbase->PutLong((char *) mbb+4, FreeBlockCnt );
- WriteSize = 8L;
- }
- else
- WriteSize = MemoHeader.BlockSize;
-
- if( _fseek( mfp,((xbOffT)BlockNo*MemoHeader.BlockSize), SEEK_SET ))
- return XB_SEEK_ERROR;
-
- if(( fwrite( mbb, WriteSize, 1, mfp )) != 1 )
- return XB_WRITE_ERROR;
-
- if( Option == 0 || Option == 1 )
- CurMemoBlockNo = BlockNo;
-
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
- \param len
- \param Buf
- \param LockOpt
-*/
-xbShort xbDbf::GetFPTField(xbShort FieldNo, xbLong len,
- char * Buf, xbShort LockOpt) {
-
- if (FieldNo < 0 || FieldNo > (NoOfFields - 1))
- return XB_INVALID_FIELDNO;
-
- if (GetFieldType(FieldNo) != 'M')
- return XB_NOT_MEMO_FIELD;
-
-#ifdef XB_LOCKING_ON
-// if( LockOpt != -1 )
-// if( LockMemoFile( XB_LOCK ) != XB_NO_ERROR )
-// return XB_LOCK_FAILED;
-#endif
-
- xbLong BlockNo;
- char buf[18];
-
- if( Version == (char)0x30 ) {
- memset( buf, 0x00, 18 ) ;
- GetField( FieldNo, buf );
- BlockNo = xbase->GetLong((char*) buf);
- } else {
- BlockNo = GetLongField(FieldNo);
- }
-
- if ( BlockNo == 0L )
- return 0L;
-
- // Seek to start_of_block + 4
-
-
-// FIXME LOCK
-
-#ifdef XB_LOCKING_ON
-// try {
-#endif
- if (_fseek(mfp, ((xbOffT)BlockNo * MemoHeader.BlockSize + 4), SEEK_SET) != 0)
- return XB_SEEK_ERROR;
- char h[4];
- if ((fread(h, 4, 1, mfp)) != 1)
- return XB_READ_ERROR;
-
- xbULong fLen = xbase->GetHBFULong(h);
-
- xbULong l = (fLen < (xbULong)len) ? fLen : len;
- if ((fread(Buf, l, 1, mfp)) != 1)
- return XB_READ_ERROR;
- Buf[l]=0;
-#ifdef XB_LOCKING_ON
-// }
-// catch (...) {
-// if (LockOpt != -1)
-// LockMemoFile( XB_UNLOCK );
-// throw;
-// }
-#endif
-
-#ifdef XB_LOCKING_ON
-// if (LockOpt != -1)
-// LockMemoFile( XB_UNLOCK );
-#endif
-
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
- \param len
- \param Buf
- \param LockOpt
-*/
-xbShort xbDbf::GetMemoField( xbShort FieldNo, xbLong len,
- char * Buf, xbShort LockOpt )
-{
- if( Version == (char)0xf5 || Version == (char)0x30 )
- return GetFPTField(FieldNo, len, Buf, LockOpt);
-
- xbLong BlockNo, Tcnt, Scnt;
- char *tp, *sp; /* target and source pointers */
- xbShort rc;
- xbShort Vswitch;
- xbLong MemoLen;
-
- if( FieldNo < 0 || FieldNo > ( NoOfFields - 1 ))
- return XB_INVALID_FIELDNO;
-
- if( GetFieldType( FieldNo ) != 'M' )
- return XB_NOT_MEMO_FIELD;
-
-#ifdef XB_LOCKING_ON
-// if( LockOpt != -1 )
-// if(( rc = LockMemoFile( LockOpt, XB_LOCK )) != XB_NO_ERROR )
-// return XB_LOCK_FAILED;
-#endif
-
- if(( BlockNo = GetLongField( FieldNo )) == 0 ){
-#ifdef XB_LOCKING_ON
-// if( LockOpt != -1 )
-// LockMemoFile( XB_UNLOCK );
-#endif
- return XB_NO_MEMO_DATA;
- }
-
- if( IsType3Dbt() )
- Vswitch = 1;
- else
- Vswitch = 0;
-
- if(( rc = ReadMemoBlock( BlockNo, Vswitch )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( LockOpt != -1 )
-// LockMemoFile( XB_UNLOCK );
-#endif
- return rc;
- }
-
- tp = Buf;
- sp = (char *) mbb;
-
- if( IsType4Dbt() ){
- sp+=8;
- Scnt = 8L;
- }
- else
- Scnt = 0L;
-
- Tcnt = 0L;
- MemoLen = GetMemoFieldLen( FieldNo );
- while( Tcnt < len && Tcnt < MemoLen ){
- *tp++ = *sp++;
- Scnt++;
- Tcnt++;
- if( Scnt >= MemoHeader.BlockSize ){
- BlockNo++;
- if(( rc = ReadMemoBlock( BlockNo, 1 )) != 0 )
- return rc;
- Scnt = 0;
- sp = (char *) mbb;
- }
- }
-#ifdef XB_LOCKING_ON
- //if( LockOpt != -1 )
-// LockMemoFile( XB_LOCK );
-#endif
-
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
-*/
-xbLong xbDbf::GetFPTFieldLen( xbShort FieldNo )
-{
- xbLong BlockNo;
- if(( BlockNo = GetLongField(FieldNo)) == 0L )
- return 0L;
- // Seek to start_of_block + 4
- if(_fseek(mfp, ((xbOffT)BlockNo * MemoHeader.BlockSize + 4), SEEK_SET) != 0)
- return XB_SEEK_ERROR;
- char h[4];
- if((fread(h, 4, 1, mfp)) != 1)
- return XB_READ_ERROR;
-
- return xbase->GetHBFULong(h);
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
-*/
-xbLong xbDbf::GetMemoFieldLen( xbShort FieldNo ) {
- if (Version == (char)0xf5 || Version == (char)0x30 )
- return GetFPTFieldLen(FieldNo);
-
- xbLong BlockNo, ByteCnt;
- xbShort scnt, NotDone;
- char *sp, *spp;
-
- if(( BlockNo = GetLongField( FieldNo )) == 0L )
- return 0L;
-
- if( IsType4Dbt()){ /* dBASE IV */
- if( BlockNo == CurMemoBlockNo && CurMemoBlockNo != -1 )
- return MFieldLen - MStartPos;
- if( ReadMemoBlock( BlockNo, 0 ) != XB_NO_ERROR )
- return 0L;
- return MFieldLen - MStartPos;
- } else { /* version 0x03 dBASE III+ */
- ByteCnt = 0L;
- spp = NULL;
- NotDone = 1;
- while( NotDone ){
- if( ReadMemoBlock( BlockNo++, 1 ) != XB_NO_ERROR )
- return 0L;
- scnt = 0;
- sp = (char *) mbb;
- while( scnt < 512 && NotDone ){
- if( *sp == 0x1a && *spp == 0x1a )
- NotDone = 0;
- else{
- ByteCnt++; scnt++; spp = sp; sp++;
- }
- }
- }
- if( ByteCnt > 0 ) ByteCnt--;
- return ByteCnt;
- }
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbDbf::MemoFieldsPresent() const
-{
- xbShort i;
- for( i = 0; i < NoOfFields; i++ )
- if( GetFieldType( i ) == 'M' )
- return 1;
-
- return 0;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
-*/
-xbShort xbDbf::DeleteMemoField( xbShort FieldNo )
-{
- xbLong SBlockNo, SNoOfBlocks, SNextBlock;
- xbLong LastFreeBlock, LastFreeBlockCnt, LastDataBlock;
- xbShort rc;
-
- NextFreeBlock = 0L;
- LastFreeBlockCnt = 0L;
- LastFreeBlock = 0L;
-
- if( IsType3Dbt() ){ /* type III */
- PutField( FieldNo, " " );
- return XB_NO_ERROR;
- }
-
- /* Get Block Number */
- if(( SBlockNo = GetLongField( FieldNo )) == 0 )
- return XB_INVALID_BLOCK_NO;
-
- /* Load the first block */
-
- if(( rc = ReadMemoBlock( SBlockNo, 4 )) != XB_NO_ERROR )
- return rc;
-
- if( (MFieldLen+2) % MemoHeader.BlockSize )
- SNoOfBlocks = (MFieldLen+2)/MemoHeader.BlockSize+1L;
- else
- SNoOfBlocks = (MFieldLen+2)/MemoHeader.BlockSize;
-
- /* Determine last good data block */
- LastDataBlock = CalcLastDataBlock();
-
- /* position to correct location in chain */
- NextFreeBlock = MemoHeader.NextBlock;
- while( SBlockNo > NextFreeBlock && SBlockNo < LastDataBlock ){
- LastFreeBlock = NextFreeBlock;
- if(( rc = ReadMemoBlock( NextFreeBlock, 2 )) != XB_NO_ERROR )
- return rc;
- LastFreeBlockCnt = FreeBlockCnt;
- }
-
-
- /* if next block should be concatonated onto the end of this set */
-
- if((SBlockNo+SNoOfBlocks) == NextFreeBlock && NextFreeBlock < LastDataBlock )
- {
- if(( rc = ReadMemoBlock( NextFreeBlock, 2 )) != XB_NO_ERROR )
- return XB_NO_ERROR;
- SNoOfBlocks += FreeBlockCnt;
- SNextBlock = NextFreeBlock;
- } else if( LastFreeBlock == 0L )
- SNextBlock = MemoHeader.NextBlock;
- else
- SNextBlock = NextFreeBlock;
-
- /* if this is the first set of free blocks */
- if( LastFreeBlock == 0L ){
- /* 1 - write out the current block */
- /* 2 - update header block */
- /* 3 - write header block */
- /* 4 - update data field */
-
- NextFreeBlock = SNextBlock;
- FreeBlockCnt = SNoOfBlocks;
- if(( rc = WriteMemoBlock( SBlockNo, 2 )) != XB_NO_ERROR )
- return rc;
-
- MemoHeader.NextBlock = SBlockNo;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR )
- return rc;
- PutField( FieldNo, " " );
- return XB_NO_ERROR;
- }
-
-/* determine if this block set should be added to the previous set */
-
- if(( LastFreeBlockCnt + LastFreeBlock ) == SBlockNo ){
- if(( rc = ReadMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )
- return rc;
- NextFreeBlock = SNextBlock;
- FreeBlockCnt += SNoOfBlocks;
- if(( rc = WriteMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )
- return rc;
- PutField( FieldNo, " " );
- return XB_NO_ERROR;
- }
-
- /* insert into the chain */
- /* 1 - set the next bucket on the current node */
- /* 2 - write this node */
- /* 3 - go to the previous node */
- /* 4 - insert this nodes id into the previous node set */
- /* 5 - write previous node */
-
- FreeBlockCnt = SNoOfBlocks;
- if(( rc = WriteMemoBlock( SBlockNo, 2 )) != XB_NO_ERROR )
- return rc;
- if(( rc = ReadMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )
- return rc;
- NextFreeBlock = SBlockNo;
- if(( rc = WriteMemoBlock( LastFreeBlock, 2 )) != XB_NO_ERROR )
- return rc;
- PutField( FieldNo, " " );
-
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
- \param DataLen
- \param Buf
-*/
-
-xbShort xbDbf::AddMemoData( xbShort FieldNo, xbLong DataLen,
- const char * Buf )
-{
- xbShort rc;
- xbLong BlocksNeeded, LastDataBlock;
- xbLong PrevNode, HeadBlock;
- xbLong TotalLen; /* total length of needed area for memo field */
-
- TotalLen = DataLen+2;
- LastDataBlock = CalcLastDataBlock();
-
- if( IsType3Dbt() || /* always append to end */
- ( LastDataBlock == MemoHeader.NextBlock )){ /* no free space */
- if( TotalLen % MemoHeader.BlockSize )
- BlocksNeeded = TotalLen / MemoHeader.BlockSize + 1;
- else
- BlocksNeeded = TotalLen / MemoHeader.BlockSize;
-
- MemoHeader.NextBlock = LastDataBlock + BlocksNeeded; /* reset to eof */
- if(( rc = PutMemoData( LastDataBlock, BlocksNeeded, DataLen, Buf ))
- != XB_NO_ERROR )
- return rc;
- HeadBlock = LastDataBlock;
- if(( rc = UpdateHeadNextNode()) != XB_NO_ERROR )
- return rc;
- }else{
- TotalLen += 8;
- if( TotalLen % MemoHeader.BlockSize )
- BlocksNeeded = TotalLen / MemoHeader.BlockSize + 1;
- else
- BlocksNeeded = TotalLen / MemoHeader.BlockSize;
-
- if(( rc = FindBlockSetInChain( BlocksNeeded, LastDataBlock,
- HeadBlock, PrevNode )) == 1 ){
- if(( rc = GetBlockSetFromChain( BlocksNeeded, HeadBlock, PrevNode ))
- != XB_NO_ERROR )
- return rc;
- if(( rc = PutMemoData( HeadBlock, BlocksNeeded, DataLen, Buf ))
- != XB_NO_ERROR )
- return rc;
- } else { /* append to the end */
- /* if header block needed updated, already done by here */
- if(( rc = PutMemoData( LastDataBlock, BlocksNeeded, DataLen, Buf ))
- != XB_NO_ERROR )
- return rc;
- HeadBlock = LastDataBlock;
- if(( rc = ReadMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )
- return rc;
- NextFreeBlock += BlocksNeeded;
- if(( rc = WriteMemoBlock( PrevNode, 2 )) != XB_NO_ERROR )
- return rc;
- }
- }
- PutLongField( FieldNo, HeadBlock );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbDbf::UpdateHeadNextNode() const
-{
- char buf[4];
- memset( buf, 0x00, 4 );
- xbase->PutLong( buf, MemoHeader.NextBlock );
- if(( _fseek( mfp, 0, SEEK_SET )) != 0 )
- return XB_SEEK_ERROR;
-
- if(( fwrite( &buf, 4, 1, mfp )) != 1 )
- return XB_WRITE_ERROR;
-
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param StartBlock First block to write
- \param BlocksNeeded Total number of blocks needed
- \param DataLen Length of data to write
- \param Buf Actual data
-*/
-xbShort xbDbf::PutMemoData( xbLong StartBlock, xbLong BlocksNeeded,
- xbLong DataLen, const char *Buf )
-{
- xbShort i, rc, Tctr;
- xbShort BytesProcessed; // bytes processed so far
- xbShort TotalLen; // total length of data
- xbLong CurBlock;
- char *tp;
- const char *sp;
-
- TotalLen = DataLen + 2;
- CurBlock = StartBlock;
- memset( (char *) mbb, 0x00, MemoHeader.BlockSize );
- tp = (char *) mbb;
- sp = Buf;
- BytesProcessed = 0; /* total length processed */
-
-
- if( IsType3Dbt() )
- Tctr = 0;
- else{ /* dBASE IV */
- tp += 8;
- Tctr = 8;
- }
-
- for( i = 0; i < BlocksNeeded; i++ ){
- while( Tctr < MemoHeader.BlockSize && BytesProcessed < TotalLen ){
- if( BytesProcessed >= DataLen )
- *tp++ = 0x1a; /* end of data marker */
- else
- *tp++ = *sp++; /* copy data to memo block buffer */
- Tctr++;
- BytesProcessed++;
- }
-
- /* if incomplete block, finish it out with 0x00 */
- while( Tctr++ < MemoHeader.BlockSize )
- *tp++ = 0x00;
-
- if( i == 0 && IsType4Dbt() ){
- mfield1 = -1;
- MStartPos = 8;
- MFieldLen = DataLen + MStartPos;
- if(( rc = WriteMemoBlock( CurBlock++, 0 )) != XB_NO_ERROR )
- return rc;
- } else {
- if(( rc = WriteMemoBlock( CurBlock++, 1 )) != XB_NO_ERROR )
- return rc;
- }
- Tctr = 0;
- tp = (char *) mbb;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
- \param DataLen
- \param Buf
- \param LockOpt
-*/
-xbShort xbDbf::UpdateMemoData( xbShort FieldNo, xbLong DataLen,
- const char * Buf, xbShort LockOpt )
-{
- xbShort rc;
- xbLong TotalLen;
- xbLong BlocksNeeded, BlocksAvailable;
-
- #ifdef XB_LOCKING_ON
- if( LockOpt != -1 )
-// if(( rc = LockMemoFile( XB_LOCK )) != XB_NO_ERROR )
-// return XB_LOCK_FAILED;
- #endif
-
- if( DataLen ){
- TotalLen = DataLen + 2; // add 2 eod 0x1a chars
- if( IsType4Dbt()) TotalLen += 8; // leading fields for dbase iv
- }
- else
- TotalLen = 0;
-
- if( DataLen == 0L ){ /* handle delete */
- if( MemoFieldExists( FieldNo )){
- if(( rc = DeleteMemoField( FieldNo )) != XB_NO_ERROR ){
- #ifdef XB_LOCKING_ON
-// LockMemoFile( XB_UNLOCK );
- #endif
- return rc;
- }
- }
- } else if((IsType3Dbt() || GetMemoFieldLen(FieldNo)==0L)){
- if(( rc = AddMemoData( FieldNo, DataLen, Buf )) != XB_NO_ERROR ){
- #ifdef XB_LOCKING_ON
-// LockMemoFile( XB_UNLOCK );
- #endif
- return rc;
- }
- } else { /* version IV type files, reuse unused space */
- if( TotalLen % MemoHeader.BlockSize )
- BlocksNeeded = TotalLen / MemoHeader.BlockSize + 1;
- else
- BlocksNeeded = TotalLen / MemoHeader.BlockSize;
-
- if(( rc = ReadMemoBlock( GetLongField( FieldNo ), 4 )) != XB_NO_ERROR ){
- #ifdef XB_LOCKING_ON
-// LockMemoFile( XB_UNLOCK );
- #endif
- return rc;
- }
-
- if( (MFieldLen+2) % MemoHeader.BlockSize )
- BlocksAvailable = (MFieldLen+2) / MemoHeader.BlockSize + 1;
- else
- BlocksAvailable = (MFieldLen+2) / MemoHeader.BlockSize;
-
- if( BlocksNeeded == BlocksAvailable ){
- if(( rc = PutMemoData( GetLongField( FieldNo ), BlocksNeeded,
- DataLen, Buf )) != XB_NO_ERROR ){
- #ifdef XB_LOCKING_ON
-// LockMemoFile( XB_UNLOCK );
- #endif
- return rc;
- }
- } else {
- if(( rc = DeleteMemoField( FieldNo )) != XB_NO_ERROR ){
- #ifdef XB_LOCKING_ON
-// LockMemoFile( XB_UNLOCK );
- #endif
- return rc;
- }
- if(( rc = AddMemoData( FieldNo, DataLen, Buf )) != XB_NO_ERROR ){
- #ifdef XB_LOCKING_ON
-// LockMemoFile( XB_UNLOCK );
- #endif
- return rc;
- }
- }
- }
-
-
- #ifdef XB_LOCKING_ON
-// if( LockOpt != -1 )
-// if(( rc = LockMemoFile( XB_UNLOCK )) != XB_NO_ERROR )
-// return XB_LOCK_FAILED;
- #endif
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param FieldNo
-*/
-xbShort xbDbf::MemoFieldExists( xbShort FieldNo ) const
-{
- if( GetLongField( FieldNo ) == 0L )
- return 0;
- else
- return 1;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-#ifdef XBASE_DEBUG
-void xbDbf::DumpMemoHeader() const
-{
- xbShort i;
- std::cout << "\n*********************************";
- std::cout << "\nMemo header data...";
- std::cout << "\nNext Block " << MemoHeader.NextBlock;
- if( IsType4Dbt() ){
- std::cout << "\nFilename ";
- for( i = 0; i < 8; i++ )
- std::cout << MemoHeader.FileName[i];
- }
- std::cout << "\nBlocksize " << MemoHeader.BlockSize;
- return;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbDbf::DumpMemoFreeChain()
-{
- xbShort rc;
- xbLong CurBlock, LastDataBlock;
-
- if(( rc = GetDbtHeader(1)) != XB_NO_ERROR )
- return rc;
- LastDataBlock = CalcLastDataBlock();
- CurBlock = MemoHeader.NextBlock;
- std::cout << "Total blocks in file = " << LastDataBlock << std::endl;
- std::cout << "Head Next Block = " << CurBlock << std::endl;;
- while( CurBlock < LastDataBlock ){
- if(( rc = ReadMemoBlock( CurBlock, 2 )) != XB_NO_ERROR )
- return rc;
- std::cout << "**********************************" << std::endl;
- std::cout << "This Block = " << CurBlock << std::endl;
- std::cout << "Next Block = " << NextFreeBlock << std::endl;
- std::cout << "No Of Blocks = " << FreeBlockCnt << std::endl;
- CurBlock = NextFreeBlock;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-void xbDbf::DumpMemoBlock() const
-{
- xbShort i;
- char *p;
- p = (char *) mbb;
- if( IsType3Dbt() ){
- for( i = 0; i < 512; i++ )
- std::cout << *p++;
- } else {
- std::cout << "\nField1 => " << mfield1;
- std::cout << "\nStart Pos => " << MStartPos;
- std::cout << "\nField Len => " << MFieldLen;
- std::cout << "\nBlock data => ";
- p += 8;
- for( i = 8; i < MemoHeader.BlockSize; i++ )
- std::cout << *p++;
- }
- return;
-}
-#endif /* XBASE_DEBUG */
-#endif /* MEMO_FIELD */
diff --git a/xbase64/xbmindex.h b/xbase64/xbmindex.h
deleted file mode 100755
index 2cda630..0000000
--- a/xbase64/xbmindex.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef xbMultiIndex_h
-#define xbMultiIndex_h
-
-#include <xbase64/xbase64.h>
-
-class xbMultiIndex: public xbIndex
-{
- public:
- xbMultiIndex(xbDbf* dbf): xbIndex(dbf) {}
- virtual ~xbMultiIndex() {}
- virtual xbShort CreateIndex(const char * filename, const char* tag,
- const char* expr, xbShort unique, xbShort overwrite)=0;
-};
-#endif
diff --git a/xbase64/xbndx.cpp b/xbase64/xbndx.cpp
deleted file mode 100755
index e89bc7a..0000000
--- a/xbase64/xbndx.cpp
+++ /dev/null
@@ -1,2402 +0,0 @@
-/* xbndx.cpp
-
- Xbase64 project source code
-
- NDX indexing routines for X-Base
-
- Copyright (C) 1997,2003,2004 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbndx.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-#include <iostream>
-
-#ifdef XB_INDEX_NDX
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-//#include <xbase64/xbexcept.h>
-
-/*! \file xbndx.cpp
-*/
-
-/***********************************************************************/
-//! Short description
-/*!
-*/
-/* This routine dumps the node chain to stdout */
-#ifdef XBASE_DEBUG
-void xbNdx::DumpNodeChain()
-{
- xbNdxNodeLink *n;
- std::cout << std::endl << "*************************" << std::endl;
- std::cout << "xbNodeLinkCtr = " << xbNodeLinkCtr << std::endl;
- std::cout << "Reused = " << ReusedxbNodeLinks << std::endl;
-
- n = NodeChain;
- while(n){
- std::cout << "xbNodeLink Chain ->" << n->NodeNo << std::endl;
- std::cout << " CurKeyNo ->" << n->CurKeyNo << std::endl;
- n = n->NextNode;
- }
- n = FreeNodeChain;
- while(n){
- std::cout << "FreexbNodeLink Chain " << n->NodeNo << std::endl;
- n = n->NextNode;
- }
- n = DeleteChain;
- while(n){
- std::cout << "DeleteLink Chain " << n->NodeNo << std::endl;
- n = n->NextNode;
- }
-}
-#endif
-/***********************************************************************/
-//! Short description
-/*!
- \param n
-*/
-/* This routine returns a chain of one or more index nodes back to the */
-/* free node chain */
-
-void xbNdx::ReleaseNodeMemory(xbNdxNodeLink *n, xbBool doFree)
-{
- xbNdxNodeLink *temp;
-
- if(doFree){
- while(n){
- temp = n->NextNode;
- free(n);
- n = temp;
- }
- } else {
- if( !FreeNodeChain )
- FreeNodeChain = n;
- else { /* put this list at the end */
- temp = FreeNodeChain;
- while( temp->NextNode )
- temp = temp->NextNode;
- temp->NextNode = n;
- }
- }
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-/* This routine returns a node from the free chain if available, */
-/* otherwise it allocates new memory for the requested node */
-
-xbNdxNodeLink * xbNdx::GetNodeMemory()
-{
- xbNdxNodeLink * temp;
- if( FreeNodeChain ){
- temp = FreeNodeChain;
- FreeNodeChain = temp->NextNode;
- ReusedxbNodeLinks++;
- } else {
- temp = (xbNdxNodeLink *) malloc( sizeof( xbNdxNodeLink ));
- xbNodeLinkCtr++;
- }
- memset( temp, 0x00, sizeof( xbNdxNodeLink ));
- return temp;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-#ifdef XBASE_DEBUG
-void xbNdx::DumpHdrNode( xbShort opt )
-{
- if( opt ){
- FILE * log;
- if(( log = fopen( "xbase64.log", "a+t" )) == NULL ) return;
- fprintf( log, "Index Header Node for %s\n", GetFileName().getData());
- fprintf( log, "--------------------------------\n" );
- fprintf( log, "Start node = %ld\n", HeadNode.StartNode );
- fprintf( log, "Total nodes = %ld\n", HeadNode.TotalNodes );
- fprintf( log, "No of keys = %ld\n", HeadNode.NoOfKeys );
- fprintf( log, "Key Length = %d\n", HeadNode.KeyLen );
- fprintf( log, "Keys Per Node = %d\n", HeadNode.KeysPerNode );
- fprintf( log, "Key type = %d\n", HeadNode.KeyType );
- fprintf( log, "Key size = %ld\n", HeadNode.KeySize );
- fprintf( log, "Unknown 2 = %d\n", HeadNode.Unknown2 );
- fprintf( log, "Unique = %d\n", HeadNode.Unique );
- fprintf( log, "KeyExpression = %s\n", HeadNode.KeyExpression );
- fclose( log );
- }
- else
- {
- std::cout << "Start node = " << HeadNode.StartNode << std::endl;
- std::cout << "Total nodes = " << HeadNode.TotalNodes << std::endl;
- std::cout << "No of keys = " << HeadNode.NoOfKeys << std::endl;
- std::cout << "Key Length = " << HeadNode.KeyLen << std::endl;
- std::cout << "Keys Per Node = " << HeadNode.KeysPerNode << std::endl;
- std::cout << "Key type = " << HeadNode.KeyType << std::endl;
- std::cout << "Key size = " << HeadNode.KeySize << std::endl;
- std::cout << "Unknown 2 = " << HeadNode.Unknown2 << std::endl;
- std::cout << "Unique = " << HeadNode.Unique << std::endl;
- std::cout << "KeyExpression = " << HeadNode.KeyExpression << std::endl;
-#ifdef XB_VAR_NODESIZE
- std::cout << "NodeSize = " << NodeSize << std::endl;
-#endif // XB_VAR_NODESIZE
- std::cout << std::endl;
- }
-}
-#endif
-
-/***********************************************************************/
-//! Constructor
-/*!
- \param pdbf
-*/
-xbNdx::xbNdx() : xbIndex()
-{
-}
-
-/***********************************************************************/
-//! Constructor
-/*!
- \param pdbf
-*/
-xbNdx::xbNdx(xbDbf *pdbf) : xbIndex(pdbf) {
-#ifndef XB_VAR_NODESIZE
- memset( Node, 0x00, XB_NDX_NODE_SIZE );
-#else
- memset( Node, 0x00, XB_MAX_NDX_NODE_SIZE );
-#endif
- memset( &HeadNode, 0x00, sizeof( xbNdxHeadNode ));
- NodeChain = NULL;
- FreeNodeChain = NULL;
- DeleteChain = NULL;
- CurNode = NULL;
- xbNodeLinkCtr = 0L;
- ReusedxbNodeLinks = 0L;
-#ifndef XB_VAR_NODESIZE
- NodeSize = XB_NDX_NODE_SIZE;
-#else
- NodeSize = XB_DEFAULT_NDX_NODE_SIZE;
-#endif // XB_VAR_NODESIZE
-}
-
-/***********************************************************************/
-//! Destructor
-/*!
-*/
-xbNdx::~xbNdx()
-{
- CloseIndex();
-}
-
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbNdx::GetHeadNode( void )
-{
- char *p, *q;
- xbShort i;
-
- if( !IsOpen() )
- return XB_NOT_OPEN;
-
- if( _fseek( indexfp, 0, SEEK_SET ))
- return XB_SEEK_ERROR;
-
- if(( fread( Node, XB_NDX_NODE_SIZE, 1, indexfp )) != 1 )
- return XB_READ_ERROR;
-
- /* load the head node structure */
- p = Node;
- HeadNode.StartNode = dbf->xbase->GetLong ( p ); p+=4;
- HeadNode.TotalNodes = dbf->xbase->GetLong ( p ); p+=4;
- HeadNode.NoOfKeys = dbf->xbase->GetLong ( p ); p+=4;
- HeadNode.KeyLen = dbf->xbase->GetShort( p ); p+=2;
- HeadNode.KeysPerNode = dbf->xbase->GetShort( p ); p+=2;
- HeadNode.KeyType = dbf->xbase->GetShort( p ); p+=2;
- HeadNode.KeySize = dbf->xbase->GetLong ( p ); p+=4;
- HeadNode.Unknown2 = *p++;
- HeadNode.Unique = *p++;
-
-#ifdef XB_VAR_NODESIZE
- //
- // Automagically determine the node size. Note the (2 * sizeof(xbLong))
- // is taken directly from CreateIndex(). I don't understand it exactly,
- // but this is the value used to calculate the number of keys per node.
- // DTB.
- //
- NodeSize = (2 * sizeof(xbLong)) + HeadNode.KeySize * HeadNode.KeysPerNode;
- if(NodeSize % XB_NDX_NODE_MULTIPLE)
- NodeSize = ((NodeSize + XB_NDX_NODE_MULTIPLE) / XB_NDX_NODE_MULTIPLE) *
- XB_NDX_NODE_MULTIPLE;
-#endif
-
- q = HeadNode.KeyExpression;
- for( i = XB_NDX_NODE_BASESIZE; i < XB_NDX_NODE_SIZE && *p; i++ )
- *q++ = *p++;
-
- return 0;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param NodeNo
- \param SetNodeChain
-*/
-/* This routine reads a leaf node from disk */
-/* */
-/* If SetNodeChain 2, then the node is not appended to the node chain */
-/* but the CurNode pointer points to the node read */
-/* If SetNodeChain 1, then the node is appended to the node chain */
-/* If SetNodeChain 0, then record is only read to Node memory */
-
-xbShort xbNdx::GetLeafNode( xbLong NodeNo, xbShort SetNodeChain )
-{
- xbNdxNodeLink *n;
-
- if( !IsOpen() )
- return XB_NOT_OPEN;
-
- if( _fseek( indexfp, (xbOffT)NodeNo * XB_NDX_NODE_SIZE, SEEK_SET ))
- return XB_SEEK_ERROR;
-
- if(( fread( Node, XB_NDX_NODE_SIZE, 1, indexfp )) != 1 )
- return XB_READ_ERROR;
-
- if( !SetNodeChain ) return 0;
-
- if(( n = GetNodeMemory()) == NULL )
- return XB_NO_MEMORY;
-
- n->NodeNo = NodeNo;
- n->CurKeyNo = 0L;
- n->NextNode = NULL;
- n->Leaf.NoOfKeysThisNode = dbf->xbase->GetLong( Node );
- memcpy( n->Leaf.KeyRecs, Node+4, XB_NDX_NODE_SIZE - 4 );
-
- /* put the node in the chain */
- if( SetNodeChain == 1 ){
- if( NodeChain == NULL ){ /* first one ? */
- NodeChain = n;
- CurNode = n;
- CurNode->PrevNode = NULL;
- } else {
- n->PrevNode = CurNode;
- CurNode->NextNode = n;
- CurNode = n;
- }
- }
- else
- CurNode = n;
- return 0;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param n
-*/
-#ifdef XBASE_DEBUG
-void xbNdx::DumpNodeRec( xbLong n )
-{
- char *p;
- xbLong NoOfKeys, LeftBranch, RecNo, NodeType;
- xbShort i,j;
- FILE * log;
-
- if(( log = fopen( "xbase64.log", "a+t" )) == NULL ) return;
- GetLeafNode( n, 0 );
- NoOfKeys = dbf->xbase->GetLong( Node );
- p = Node + 4; /* go past no of keys */
-
- fprintf( log, "----------------------------------------------------\n" );
- fprintf( log, "Node # %ld\n", n );
- fprintf( log, "Number of keys = %ld\n", NoOfKeys );
- fprintf( log, " Key Left Dbf Rec Key\n" );
- fprintf( log, "Number Branch Number Data\n" );
-
- NodeType = 0;
- for( i = 0; i < (NoOfKeys+NodeType); i++ ){
- LeftBranch = dbf->xbase->GetLong( p );
- if( i == 0 && LeftBranch ){
- NodeType = 1; /* print one extra entry for interior nodes */
- fprintf( log, "Interior node\n" );
- }
-
- p+=4;
- RecNo = dbf->xbase->GetLong( p );
- p+=4;
-
- fprintf( log, " %3d %9ld %9ld ", i, LeftBranch, RecNo );
-
- if( NodeType == 1 && i == NoOfKeys )
- fprintf( log, "...\n" );
-
- else if( !HeadNode.KeyType ){
- for( j = 0; j < HeadNode.KeyLen; j++ )
- fputc( *p++, log );
- fputc( '\n', log );
- }
-
- else {
- fprintf( log, "??????\n" /*, dbf->xbase->GetDouble( p )*/ );
- p += 8;
- }
- }
- fclose( log );
-}
-#endif
-/***********************************************************************/
-#ifndef XB_INLINE_GETDBFNO
-xbLong xbNdx::GetDbfNo( xbShort RecNo, xbNdxNodeLink * n )
-{
- xbNdxLeafNode *temp;
- char *p;
- if( !n ) return 0L;
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode - 1 )) return 0L;
- p = temp->KeyRecs + 4;
- p += RecNo * ( 8 + HeadNode.KeyLen );
- return( dbf->xbase->GetLong( p ));
-}
-#endif
-/***********************************************************************/
-//! Short description
-/*!
- \param RecNo
- \param n
-*/
-xbLong xbNdx::GetLeftNodeNo( xbShort RecNo, xbNdxNodeLink * n )
-{
- xbNdxLeafNode *temp;
- char *p;
- if( !n ) return 0L;
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > temp->NoOfKeysThisNode ) return 0L;
- p = temp->KeyRecs;
- p += RecNo * ( 8 + HeadNode.KeyLen );
- return( dbf->xbase->GetLong( p ));
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param RecNo
- \param n
-*/
-char * xbNdx::GetKeyData( xbShort RecNo, xbNdxNodeLink * n )
-{
- xbNdxLeafNode *temp;
- char *p;
- if( !n ) return 0L;
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode - 1 )) return 0L;
- p = temp->KeyRecs + 8;
- p += RecNo * ( 8 + HeadNode.KeyLen );
- return( p );
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbLong xbNdx::GetTotalNodes( void )
-{
- if( &HeadNode )
- return HeadNode.TotalNodes;
- else
- return 0L;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbUShort xbNdx::GetKeysPerNode( void )
-{
- if( &HeadNode )
- return HeadNode.KeysPerNode;
- else
- return 0L;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param RetrieveSw
-*/
-xbShort xbNdx::GetFirstKey( xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the first index pointer */
-
- xbLong TempNodeNo;
- xbShort rc;
-
- /* initialize the node chain */
- if( NodeChain ){
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL;
- }
-
- if(( rc = GetHeadNode()) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
-
- /* get a node and add it to the link */
- if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ){
- return rc;
- }
-
-/* traverse down the left side of the tree */
- while( GetLeftNodeNo( 0, CurNode )){
- TempNodeNo = GetLeftNodeNo( 0, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
- CurNode->CurKeyNo = 0;
- }
- CurDbfRec = GetDbfNo( 0, CurNode );
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param RetrieveSw
-*/
-xbShort xbNdx::GetNextKey( xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the next index pointer */
-
- xbNdxNodeLink * TempxbNodeLink;
- xbLong TempNodeNo;
- xbShort rc;
-
- if( !IsOpen() ){
- CurDbfRec = 0L;
- return XB_NOT_OPEN;
- }
-
- if( !CurNode ){
- rc = GetFirstKey( RetrieveSw );
- return rc;
- }
-
- /* more keys on this node ? */
- if(( CurNode->Leaf.NoOfKeysThisNode-1) > CurNode->CurKeyNo ){
- CurNode->CurKeyNo++;
- CurDbfRec = GetDbfNo( CurNode->CurKeyNo, CurNode );
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
- }
-
- /* if head node we are at eof */
- if( CurNode->NodeNo == HeadNode.StartNode ) {
- return XB_EOF;
- }
-
- /* this logic assumes that interior nodes have n+1 left node no's where */
- /* n is the number of keys in the node */
-
- /* pop up one node to the interior node level & free the leaf node */
-
- TempxbNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempxbNodeLink );
-
- /* while no more right keys && not head node, pop up one node */
- while(( CurNode->CurKeyNo >= CurNode->Leaf.NoOfKeysThisNode ) &&
- ( CurNode->NodeNo != HeadNode.StartNode )){
- TempxbNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempxbNodeLink );
- }
-
- /* if head node && right most key, return end-of-file */
- if(( HeadNode.StartNode == CurNode->NodeNo ) &&
- ( CurNode->CurKeyNo >= CurNode->Leaf.NoOfKeysThisNode )) {
- return XB_EOF;
- }
-
- /* move one to the right */
- CurNode->CurKeyNo++;
- TempNodeNo = GetLeftNodeNo( CurNode->CurKeyNo, CurNode );
-
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
- return rc;
- }
-
-/* traverse down the left side of the tree */
- while( GetLeftNodeNo( 0, CurNode )){
- TempNodeNo = GetLeftNodeNo( 0, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
- CurNode->CurKeyNo = 0;
- }
- CurDbfRec = GetDbfNo( 0, CurNode );
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param NodeNo
- \param RetrieveSw
-*/
-xbShort xbNdx::GetLastKey( xbLong NodeNo, xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the last index pointer */
-
-/* If NodeNo = 0, start at head node, otherwise start at NodeNo */
-
- xbLong TempNodeNo;
- xbShort rc;
-
- if( NodeNo < 0 || NodeNo > HeadNode.TotalNodes )
- return XB_INVALID_NODE_NO;
-
- /* initialize the node chain */
- if( NodeChain ){
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL;
- }
- if( NodeNo == 0L )
- if(( rc = GetHeadNode()) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
-
- /* get a node and add it to the link */
- if( NodeNo == 0L ){
- if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
- } else {
- if(( rc = GetLeafNode( NodeNo, 1 )) != 0 ) {
- CurDbfRec = 0L;
- return rc;
- }
- }
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
-
-/* traverse down the right side of the tree */
- while( GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode )){
- TempNodeNo = GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- }
- CurNode->CurKeyNo--; /* leaf node has one fewer ix recs */
- CurDbfRec = GetDbfNo( CurNode->Leaf.NoOfKeysThisNode-1, CurNode );
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param RetrieveSw
-*/
-xbShort xbNdx::GetPrevKey( xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the previous index pointer */
-
- xbNdxNodeLink * TempxbNodeLink;
- xbLong TempNodeNo;
- xbShort rc;
-
- if( !IsOpen() ){
- CurDbfRec = 0L;
- return XB_NOT_OPEN;
- }
-
- if( !CurNode ){
- CurDbfRec = 0L;
- return GetFirstKey( RetrieveSw );
- }
-
- /* more keys on this node ? */
- if( CurNode->CurKeyNo > 0 ){
- CurNode->CurKeyNo--;
- CurDbfRec = GetDbfNo( CurNode->CurKeyNo, CurNode );
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
- }
-
- /* this logic assumes that interior nodes have n+1 left node no's where */
- /* n is the number of keys in the node */
- /* pop up one node to the interior node level & free the leaf node */
-
- if( !CurNode->PrevNode ) { /* michael - make sure prev node exists */
- return XB_EOF;
- }
-
- TempxbNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempxbNodeLink );
-
- /* while no more left keys && not head node, pop up one node */
- while(( CurNode->CurKeyNo == 0 ) &&
- ( CurNode->NodeNo != HeadNode.StartNode )) {
- TempxbNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempxbNodeLink );
- }
-
- /* if head node && left most key, return beginning-of-file */
- if(( HeadNode.StartNode == CurNode->NodeNo ) &&
- ( CurNode->CurKeyNo == 0 )) {
- return XB_BOF;
- }
-
- /* move one to the left */
- CurNode->CurKeyNo--;
- TempNodeNo = GetLeftNodeNo( CurNode->CurKeyNo, CurNode );
-
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ) {
- return rc;
- }
-
- if( GetLeftNodeNo( 0, CurNode )) /* if interior node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- else /* leaf node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode - 1;
-
-/* traverse down the right side of the tree */
- while( GetLeftNodeNo( 0, CurNode )){ /* while interior node */
- TempNodeNo = GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
- if( GetLeftNodeNo( 0, CurNode )) /* if interior node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- else /* leaf node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode - 1;
- }
- CurDbfRec = GetDbfNo( CurNode->Leaf.NoOfKeysThisNode - 1, CurNode );
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/**************************************************************************/
-//! Short description
-/*!
- \param key
- \param klen
- \param node
- \param comp
-*/
-/*
-** This is a pretty basic binary search with two exceptions: 1) it will
-** find the first of duplicate key values and 2) will return the index
-** and the value of the last comparision even if it doesn't find a
-** match.
-*/
-xbShort
-xbNdx::BSearchNode(const char *key, xbShort klen, const xbNdxNodeLink *node,
- xbShort *comp)
-{
- xbShort c, p, start = 0, end = node->Leaf.NoOfKeysThisNode - 1;
-
- if(start > end){
- *comp = 2;
- return 0;
- }
-
- do {
- p = (start + end) / 2;
- c = CompareKey(key, GetKeyData(p, (xbNdxNodeLink *)node), klen);
- switch(c){
-
- case 1 : /* greater than */
- start = p + 1;
- break;
-
- case 2 : /* less than */
- end = p - 1;
- break;
- }
- } while(start <= end && c);
-
-
- if(c == 1)
- while(p < node->Leaf.NoOfKeysThisNode &&
- (c = CompareKey(key, GetKeyData(p, (xbNdxNodeLink *)node), klen)) == 1)
- p++;
-
- *comp = c;
-
- if(!c)
- while(p > 0 && !CompareKey(key, GetKeyData(p - 1, (xbNdxNodeLink *)node), klen))
- p--;
-
- return p;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param Tkey
- \param Klen
-*/
-xbLong xbNdx::GetLeafFromInteriorNode( const char * Tkey, xbShort Klen )
-{
- /* This function scans an interior node for a key and returns the */
- /* correct interior leaf node no */
-
- xbShort p, c;
-
- /* if Tkey > any keys in node, return right most key */
- p = CurNode->Leaf.NoOfKeysThisNode - 1;
- if( CompareKey( Tkey, GetKeyData( p, CurNode ), Klen ) == 1 ) {
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- return GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode );
- }
-
- p = BSearchNode(Tkey, Klen, CurNode, &c);
- CurNode->CurKeyNo = p;
- return GetLeftNodeNo( p, CurNode );
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param d
-*/
-xbShort xbNdx::KeyExists( xbDouble d )
-{
- char buf[9];
- memset( buf, 0x00, 9 );
- dbf->xbase->PutDouble( buf, d );
- return FindKey( buf, 8, 0 );
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param d
-*/
-xbShort xbNdx::FindKey( xbDouble d )
-{
- char buf[9];
- memset( buf, 0x00, 9 );
- dbf->xbase->PutDouble( buf, d );
- return FindKey( buf, 8, 1 );
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param Key
-*/
-xbShort xbNdx::FindKey( const char * Key )
-{
- return FindKey( Key, strlen( Key ), 1 );
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param Tkey
- \param DbfRec
-*/
-xbShort xbNdx::FindKey( const char * Tkey, xbLong DbfRec )
-{
- /* find a key with a specifc DBF record number */
- xbShort rc;
-
- xbLong CurDbfRecNo;
- xbLong CurNdxDbfNo;
-
- /* if we are already on the correct key, return XB_FOUND */
- if( CurNode ) {
- CurDbfRecNo = dbf->GetCurRecNo();
- CurNdxDbfNo = GetDbfNo( CurNode->CurKeyNo, CurNode );
- if( CurDbfRecNo == CurNdxDbfNo &&
- (strncmp(Tkey, GetKeyData( CurNode->CurKeyNo, CurNode ),
- HeadNode.KeyLen ) == 0 )) {
- return XB_FOUND;
- }
- }
- rc = FindKey( Tkey, HeadNode.KeyLen, 0 );
-
- while( rc == 0 || rc == XB_FOUND ) {
- if( strncmp( Tkey, GetKeyData( CurNode->CurKeyNo, CurNode ),
- HeadNode.KeyLen ) == 0 ){
- if( DbfRec == GetDbfNo( CurNode->CurKeyNo, CurNode )) {
- return XB_FOUND;
- }
- else
- rc = GetNextKey( 0 );
- } else {
- return XB_NOT_FOUND;
- }
- }
- return XB_NOT_FOUND;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbNdx::FindKey( void )
-{
- /* if no paramaters given, use KeyBuf */
- return( FindKey( KeyBuf, HeadNode.KeyLen, 0 ));
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param Tkey
- \param Klen
- \param RetrieveSw
-*/
-xbShort xbNdx::FindKey( const char * Tkey, xbShort Klen, xbShort RetrieveSw )
-{
- /* This routine sets the current key to the found key */
- /* if RetrieveSw is true, the method positions the dbf record */
- xbShort rc,i;
- xbLong TempNodeNo;
-
- if( NodeChain ) {
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL;
- }
-
- if(( rc = GetHeadNode()) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
-
- /* load first node */
- if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
-
- /* traverse down the tree until it hits a leaf */
- while( GetLeftNodeNo( 0, CurNode )){ /* while interior node */
- TempNodeNo = GetLeafFromInteriorNode( Tkey, Klen );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
- CurDbfRec = 0L;
- return rc;
- }
- }
-
- i = BSearchNode(Tkey, Klen, CurNode, &rc);
- switch(rc) {
- case 0 : /* found! */
- CurNode->CurKeyNo = i;
- CurDbfRec = GetDbfNo( i, CurNode );
- if( RetrieveSw )
- dbf->GetRecord(CurDbfRec);
- return XB_FOUND;
-
- case 1 : /* less than */
-// if(i < CurNode->Leaf.NoOfKeysThisNode)
- break;
-// i++;
-
- case 2 : /* greater than */
- CurNode->CurKeyNo = i;
- CurDbfRec = GetDbfNo( i, CurNode );
- if( RetrieveSw )
- dbf->GetRecord(CurDbfRec);
- return XB_NOT_FOUND;
- }
-
- CurNode->CurKeyNo = i;
- if(i >= CurNode->Leaf.NoOfKeysThisNode){
- CurDbfRec = 0;
- return XB_EOF;
- }
-
- CurDbfRec = GetDbfNo( i, CurNode );
- if((RetrieveSw) && (CurDbfRec > 0))
- dbf->GetRecord( CurDbfRec );
-
- return XB_NOT_FOUND;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbNdx::CalcKeyLen()
-{
- xbShort rc;
- xbExpNode * TempNode;
- char FieldName[11];
- char Type;
-
- TempNode = IxExp->GetFirstTreeNode();
-
- if( !TempNode )
- return 0;
-
- if( TempNode->Type == 'd' ) return -8;
- if( TempNode->Type == 'D' ){
- memset( FieldName, 0x00, 11 );
- memcpy( FieldName, TempNode->NodeText, TempNode->Len );
- Type = dbf->GetFieldType( dbf->GetFieldNo( FieldName ));
- if( Type == 'N' || Type == 'F' )
- return -8;
- }
-
- if(( rc = IxExp->ProcessExpression()) != XB_NO_ERROR )
- return 0;
-
- TempNode = (xbExpNode *) IxExp->Pop();
- if( !TempNode )
- return 0;
- rc = TempNode->DataLen;
-
- if( !TempNode->InTree )
- delete TempNode;
-
- return rc;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param IxName
- \param Exp
- \param Unique
- \param Overlay
-*/
-xbShort xbNdx::CreateIndex(const char * IxName, const char * Exp,
- xbShort Unique, xbShort Overlay )
-{
- xbShort i, KeyLen, rc;
-
- if( IsOpen()) CloseIndex();
- if( strlen( Exp ) > 488 )
- return XB_INVALID_KEY_EXPRESSION;
-
- if( dbf->GetDbfStatus() == 0 )
- return XB_NOT_OPEN;
-
- /* Get the index file name and store it in the class */
- SetFileName(IxName);
-
- /* check if the file already exists */
- if (((indexfp = fopen( GetFileName(), "r" )) != NULL ) && !Overlay ) {
- fclose( indexfp );
- return XB_FILE_EXISTS;
- }
-
- if (indexfp)
- fclose(indexfp);
-
- if(( indexfp = fopen( GetFileName(), "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-
-#ifdef XB_LOCKING_ON
- /*
- ** Must turn off buffering when multiple programs may be accessing
- ** index files.
- */
- setbuf( indexfp, NULL );
-#endif
-
- /* parse the expression */
- IxExp = new xbExpn( dbf->xbase );
- if(( rc = IxExp->BuildExpressionTree( Exp, strlen( Exp ), dbf )) != XB_NO_ERROR )
- return rc;
-
- /* build the header record */
- memset( &HeadNode, 0x00, sizeof( xbNdxHeadNode ));
- HeadNode.StartNode = 1L;
- HeadNode.TotalNodes = 2L;
- HeadNode.NoOfKeys = 1L;
- KeyLen = CalcKeyLen();
-
- if( KeyLen == 0 || KeyLen > 100 ) /* 100 byte key length limit */
- return XB_INVALID_KEY;
- else if( KeyLen == -8 ){
- HeadNode.KeyType = 1; /* numeric key */
- HeadNode.KeyLen = 8;
- } else {
- HeadNode.KeyType = 0; /* character key */
- HeadNode.KeyLen = KeyLen;
- }
-
-// HeadNode.KeysPerNode = (xbUShort) ( XB_NDX_NODE_SIZE - (2*sizeof( xbLong ))) /
-// (HeadNode.KeyLen + 8 );
-// HeadNode.KeySize = HeadNode.KeyLen + 8;
-// while(( HeadNode.KeySize % 4 ) != 0 ) HeadNode.KeySize++; /* multiple of 4*/
-
-/* above code replaced with following by Paul Koufalis pkoufalis@cogicom.com */
-// while(( HeadNode.KeyLen % 4 ) != 0 ) HeadNode.KeyLen++; /* multiple of 4*/
-// HeadNode.KeySize = HeadNode.KeyLen + 8;
-
-
-/* above two lines commented out by gary 4/14/99 and replaced w/ following
- For compatibility with other Xbase tools
- KeyLen is the length of the key data
- KeySize = KeyLen+8, rounded up until divisible by 4
-*/
-
- HeadNode.KeySize = HeadNode.KeyLen + 8;
- while(( HeadNode.KeySize % 4 ) != 0 ) HeadNode.KeySize++; /* multiple of 4*/
-
- HeadNode.KeysPerNode = (xbUShort)
- (XB_NDX_NODE_SIZE - (2*sizeof( xbLong ))) / HeadNode.KeySize;
-
- HeadNode.Unique = Unique;
- strncpy( HeadNode.KeyExpression, Exp, 488 );
- KeyBuf = (char *) malloc( HeadNode.KeyLen + 1 );
- KeyBuf2 = (char *) malloc( HeadNode.KeyLen + 1 );
- memset( KeyBuf, 0x00, HeadNode.KeyLen + 1 );
- memset( KeyBuf2, 0x00, HeadNode.KeyLen + 1 );
-
- if(( rc = PutHeadNode( &HeadNode, indexfp, 0 )) != 0 ){
- return rc;
- }
- /* write node #1 all 0x00 */
- for( i = 0; i < XB_NDX_NODE_SIZE; i++ ){
- if ((fwrite("\x00", 1, 1, indexfp)) != 1){
- fclose( indexfp );
- return XB_WRITE_ERROR;
- }
- }
-// IndexStatus = XB_OPEN;
- return dbf->AddIndexToIxList( index, GetFileName() );
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param RecNo
- \param n
- \param NodeNo
-*/
-xbShort xbNdx::PutLeftNodeNo( xbShort RecNo, xbNdxNodeLink *n, xbLong NodeNo )
-{
- /* This routine sets n node's leftnode number */
- xbNdxLeafNode *temp;
- char *p;
- if( !n )
- return XB_INVALID_NODELINK;
-
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > HeadNode.KeysPerNode)
- return XB_INVALID_KEY;
-
- p = temp->KeyRecs;
- p+= RecNo * ( 8 + HeadNode.KeyLen );
- dbf->xbase->PutLong( p, NodeNo );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param RecNo
- \param n
- \param DbfNo
-*/
-xbShort xbNdx::PutDbfNo( xbShort RecNo, xbNdxNodeLink *n, xbLong DbfNo )
-{
- /* This routine sets n node's dbf number */
- xbNdxLeafNode *temp;
- char *p;
- if( !n )
- return XB_INVALID_NODELINK;
-
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode-1))
- return XB_INVALID_KEY;
-
- p = temp->KeyRecs + 4;
- p+= RecNo * ( 8 + HeadNode.KeyLen );
- dbf->xbase->PutLong( p, DbfNo );
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param l
- \param n
-*/
-xbShort xbNdx::PutLeafNode( xbLong l, xbNdxNodeLink *n )
-{
- if ((_fseek(indexfp, (xbOffT)l * XB_NDX_NODE_SIZE , SEEK_SET)) != 0) {
- fclose( indexfp );
- return XB_SEEK_ERROR;
- }
- dbf->xbase->PutLong( Node, n->Leaf.NoOfKeysThisNode );
-
- if(( fwrite( Node, 4, 1, indexfp )) != 1 ){
- fclose( indexfp );
- return XB_WRITE_ERROR;
- }
- if(( fwrite( &n->Leaf.KeyRecs, XB_NDX_NODE_SIZE-4, 1, indexfp )) != 1 ){
- fclose( indexfp );
- return XB_WRITE_ERROR;
- }
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param Head
- \param f
- \param UpdateOnly
-*/
-xbShort xbNdx::PutHeadNode( xbNdxHeadNode * Head, FILE * f, xbShort UpdateOnly )
-{
- char buf[4];
-
- if(( _fseek( f, 0L, SEEK_SET )) != 0 ){
- fclose( f );
- return XB_SEEK_ERROR;
- }
- memset( buf, 0x00, 4 );
- dbf->xbase->PutLong( buf, Head->StartNode );
- if(( fwrite( &buf, 4, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- memset( buf, 0x00, 4 );
- dbf->xbase->PutLong( buf, Head->TotalNodes );
- if(( fwrite( &buf, 4, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- memset( buf, 0x00, 4 );
- dbf->xbase->PutLong( buf, Head->NoOfKeys );
- if(( fwrite( &buf, 4, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- if( UpdateOnly )
- return XB_NO_ERROR;
- memset( buf, 0x00, 2 );
- dbf->xbase->PutLong( buf, Head->KeyLen );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- memset( buf, 0x00, 2 );
- dbf->xbase->PutLong( buf, Head->KeysPerNode );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- memset( buf, 0x00, 2 );
- dbf->xbase->PutLong( buf, Head->KeyType );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- memset( buf, 0x00, 4 );
- dbf->xbase->PutLong( buf, Head->KeySize );
- if(( fwrite( &buf, 4, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- if(( fwrite( &Head->Unknown2, XB_NDX_NODE_SIZE - 22, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param RecNo
- \param n
-*/
-xbShort xbNdx::PutKeyData( xbShort RecNo, xbNdxNodeLink *n )
-{
- /* This routine copies the KeyBuf data into xbNdxNodeLink n */
- xbNdxLeafNode *temp;
- char *p;
- xbShort i;
- if( !n )
- return XB_INVALID_NODELINK;
-
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode-1))
- return XB_INVALID_KEY;
-
- p = temp->KeyRecs + 8;
- p+= RecNo * ( 8 + HeadNode.KeyLen );
- for( i = 0; i < HeadNode.KeyLen; i++ ) {
- *p = KeyBuf[i];
- p++;
- }
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param n
- \param pos
- \param d
- \param l
- \param w
-*/
-xbShort xbNdx::PutKeyInNode( xbNdxNodeLink * n, xbShort pos, xbLong d,
- xbLong l, xbShort w )
-{
- xbShort i;
-
- /* check the node */
- if (!n)
- return XB_INVALID_NODELINK;
-
- if(pos < 0 || pos > HeadNode.KeysPerNode)
- return XB_INVALID_RECORD;
-
- if(n->Leaf.NoOfKeysThisNode >= HeadNode.KeysPerNode)
- return XB_NODE_FULL;
-
- /* if key movement, save the original key */
- if( pos < n->Leaf.NoOfKeysThisNode )
- memcpy( KeyBuf2, KeyBuf, HeadNode.KeyLen + 1);
-
- /* if interior node, handle the right most left node no */
- if( GetLeftNodeNo( 0, n ))
- PutLeftNodeNo( n->Leaf.NoOfKeysThisNode+1, n,
- GetLeftNodeNo( n->Leaf.NoOfKeysThisNode, n ));
-
- for( i = n->Leaf.NoOfKeysThisNode; i > pos; i-- ){
- memcpy( KeyBuf, GetKeyData(i-1,n), HeadNode.KeyLen );
- PutKeyData( i, n );
- PutDbfNo( i, n, GetDbfNo(i-1,n));
- PutLeftNodeNo(i, n, GetLeftNodeNo(i-1,n));
- }
-
- /* put new key in node */
- if( pos < n->Leaf.NoOfKeysThisNode )
- memcpy( KeyBuf, KeyBuf2, HeadNode.KeyLen + 1);
-
- PutKeyData( pos, n );
- PutDbfNo( pos, n, d );
- PutLeftNodeNo( pos, n, l );
- n->Leaf.NoOfKeysThisNode++;
- if( w )
- return PutLeafNode( n->NodeNo, n );
- else
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param curNode Current Node
- \param newNode New Empty Node
- \param pos Position of new key in current node
- \param d dbf record number
-*/
-/* This function splits a full index leaf node into two parts
- as of 2/13/04, this split logic was modified to cause an
- even split in order to keep the index tree balanced
-
-*/
-
-xbShort xbNdx::SplitLeafNode( xbNdxNodeLink *curNode,
- xbNdxNodeLink *newNode, xbShort pos, xbLong d )
-{
- xbShort curNodeNewSize;
- xbShort newNodeSize;
- xbShort i,j,rc,startPos;
-
- curNodeNewSize = (curNode->Leaf.NoOfKeysThisNode + 1) / 2;
- newNodeSize = curNode->Leaf.NoOfKeysThisNode + 1 - curNodeNewSize;
-
- /* save off the current key buffer */
- memcpy( KeyBuf2, KeyBuf, HeadNode.KeyLen + 1 );
- if( pos < curNodeNewSize ){ /* new key goes in current node */
-
- /* copy second half of current node to beginning of new node */
- /* memcpy( dst, src, len ); */
- startPos = curNode->Leaf.NoOfKeysThisNode - newNodeSize;
-
- for( i = startPos, j = 0; i < CurNode->Leaf.NoOfKeysThisNode; i++, j++){
- memcpy( KeyBuf, GetKeyData( i, curNode ), HeadNode.KeyLen );
- PutKeyData( j, newNode );
- PutDbfNo( j, newNode, GetDbfNo( i, curNode ));
- }
-
- /* make a hole for the new key */
- for( i = curNodeNewSize - 1; i > pos; i-- ){
- memcpy( KeyBuf, GetKeyData( i-1, curNode ), HeadNode.KeyLen );
- PutKeyData( i, curNode );
- PutDbfNo( i, curNode, GetDbfNo( i-1, curNode ));
- }
-
- /* insert key appropriately */
- memcpy( KeyBuf, KeyBuf2, HeadNode.KeyLen + 1 );
- PutKeyData( pos, curNode );
- PutDbfNo( pos, curNode, d );
- }
- else
- {
- pos -= curNodeNewSize;
-
- /* do part one of the key migration */
- if( pos ){
-
-/* was originally
-
- startPos = curNode->Leaf.NoOfKeysThisNode - curNodeNewSize + 1;
-
-
- then was changed to
-*/
-
-/*
- if( ((pos + curNodeNewSize) == HeadNode.KeysPerNode) &&
- (pos == newNodeSize) ){ // off the right end
- startPos = curNode->Leaf.NoOfKeysThisNode - curNodeNewSize;
- }
- else
- {
- startPos = curNode->Leaf.NoOfKeysThisNode - curNodeNewSize + 1;
- }
-
-*/
-
-/*
- and this didn't work
-
-
- startPos = curNode->Leaf.NoOfKeysThisNode - curNodeNewSize;
-
-*/
-
- startPos = curNodeNewSize;
- for( i = startPos, j = 0;
- j < pos && i < curNode->Leaf.NoOfKeysThisNode; i++, j++){
- memcpy( KeyBuf, GetKeyData( i, curNode ), HeadNode.KeyLen );
- PutKeyData( j, newNode );
- PutDbfNo( j, newNode, GetDbfNo( i, curNode ));
- }
- }
-
- /* insert new key appropriately */
- memcpy( KeyBuf, KeyBuf2, HeadNode.KeyLen + 1 );
- PutKeyData( pos, newNode );
- PutDbfNo( pos, newNode, d );
-
- /* Load the remainder of the keys on the new node past the new key */
- if( pos < (newNodeSize-1) ){
-
-// startPos = curNode->Leaf.NoOfKeysThisNode - curNodeNewSize + pos + 1;
-
- startPos = curNodeNewSize + pos;
- for( i = startPos, j = pos+1; j < newNodeSize; i++, j++){
- memcpy( KeyBuf, GetKeyData( i, curNode ), HeadNode.KeyLen );
- PutKeyData( j, newNode );
- PutDbfNo( j, newNode, GetDbfNo( i, curNode ));
- }
- }
- }
-
- curNode->Leaf.NoOfKeysThisNode = curNodeNewSize;
- newNode->Leaf.NoOfKeysThisNode = newNodeSize;
-
- /* write the new nodes to disk */
- if(( rc = PutLeafNode( curNode->NodeNo, curNode )) != 0 )
- return rc;
- if(( rc = PutLeafNode( newNode->NodeNo, newNode )) != 0 )
- return rc;
-
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param nodeToSplit Interior node to split
- \param newNode New empty node to use
- \param dscNodeNo Descendant node number
-*/
-/* This routine splits an interior node */
-
-xbShort xbNdx::SplitINode( xbNdxNodeLink *nodeToSplit,
- xbNdxNodeLink *newNode, xbLong dscNodeNo )
-{
- xbShort i,j,rc;
- xbNdxNodeLink * SaveNodeChain;
- xbNdxNodeLink * SaveCurNode;
- xbLong newNodeToSplitSize;
- xbLong newNodeSize;
- xbShort pos, startPos, offset;
-
- newNodeToSplitSize = (nodeToSplit->Leaf.NoOfKeysThisNode + 2 ) / 2;
- newNodeSize = nodeToSplit->Leaf.NoOfKeysThisNode + 2 - newNodeToSplitSize;
- pos = nodeToSplit->CurKeyNo;
-
- if( pos < (newNodeToSplitSize-1) ){
- /* copy second half of nodeToSplit to newNode */
- startPos = nodeToSplit->Leaf.NoOfKeysThisNode - newNodeSize +1;
- for(i=startPos, j=0; i <= nodeToSplit->Leaf.NoOfKeysThisNode; i++, j++ ){
- if( i < nodeToSplit->Leaf.NoOfKeysThisNode ){
- memcpy( KeyBuf, GetKeyData( i, nodeToSplit ), HeadNode.KeyLen );
- PutKeyData( j, newNode );
- }
- PutLeftNodeNo( j, newNode, GetLeftNodeNo( i, nodeToSplit ));
- }
-
- /* make a hole for the new key */
- for( i = newNodeToSplitSize; i > pos; i-- ){
- memcpy( KeyBuf, GetKeyData( i-1, nodeToSplit ), HeadNode.KeyLen );
- PutKeyData( i, nodeToSplit );
- PutLeftNodeNo( i, nodeToSplit, GetLeftNodeNo( i-1, nodeToSplit ));
- }
-
- /* load new high key value into current position on nodeToSplit */
- if( pos < (newNodeToSplitSize - 1 )){
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
- SaveCurNode = CurNode;
- GetLastKey( GetLeftNodeNo( pos, nodeToSplit ), 0 );
- memcpy( KeyBuf, GetKeyData( CurNode->CurKeyNo, CurNode ), HeadNode.KeyLen );
- PutKeyData( pos, nodeToSplit );
- ReleaseNodeMemory( NodeChain );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- }
- PutLeftNodeNo( pos+1, nodeToSplit, dscNodeNo );
- }
-
-/*************/
-/* part b */
-/*************/
-
- else
- {
- pos -= newNodeToSplitSize-1;
- /* do part one of the key migration */
- if( pos ){
-// startPos = nodeToSplit->Leaf.NoOfKeysThisNode - newNodeToSplitSize + 2;
-
-// 5/29/04 gak changed the following line for index probs
-// startPos = nodeToSplit->Leaf.NoOfKeysThisNode - newNodeToSplitSize + 1;
-
- if( HeadNode.KeysPerNode % 2 )
- offset = 2;
- else
- offset = 1;
-
- startPos = nodeToSplit->Leaf.NoOfKeysThisNode - newNodeToSplitSize + offset;
-
- for( i = startPos, j = 0; j < pos; i++, j++ ){
- if( i < nodeToSplit->Leaf.NoOfKeysThisNode && j < (pos-1)){
- memcpy( KeyBuf, GetKeyData( i, nodeToSplit ), HeadNode.KeyLen );
- PutKeyData( j, newNode );
- }
- else
- {
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
- SaveCurNode = CurNode;
- GetLastKey( GetLeftNodeNo( i, nodeToSplit ), 0 );
- memcpy(KeyBuf,GetKeyData(CurNode->CurKeyNo,CurNode),HeadNode.KeyLen);
- PutKeyData( j, newNode );
- ReleaseNodeMemory( NodeChain );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- }
- PutLeftNodeNo( j, newNode, GetLeftNodeNo( i, nodeToSplit ));
- }
- }
-
- /* insert new key appropriately */
- if( pos < (newNodeSize - 1)){
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
- SaveCurNode = CurNode;
- GetLastKey( dscNodeNo, 0 );
- memcpy(KeyBuf,GetKeyData(CurNode->CurKeyNo,CurNode),HeadNode.KeyLen);
- PutKeyData( pos, newNode );
- ReleaseNodeMemory( NodeChain );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- }
- PutLeftNodeNo( pos, newNode, dscNodeNo );
-
- /* load remainder of the keys */
- if( pos < (newNodeSize - 1)){
-
-
-// startPos=nodeToSplit->Leaf.NoOfKeysThisNode-newNodeToSplitSize+pos+2;
-// 5/29/04 gak changed the following line for index probs
-
- startPos=nodeToSplit->Leaf.NoOfKeysThisNode-newNodeToSplitSize+pos+offset;
-
- for( i = startPos, j = pos+1; j < newNodeSize; i++, j++ ){
- if( i < nodeToSplit->Leaf.NoOfKeysThisNode ){
- memcpy( KeyBuf, GetKeyData( i, nodeToSplit ), HeadNode.KeyLen );
- PutKeyData( j, newNode );
- }
- PutLeftNodeNo( j, newNode, GetLeftNodeNo( i, nodeToSplit ));
- }
- }
- }
-
- nodeToSplit->Leaf.NoOfKeysThisNode = newNodeToSplitSize - 1;
- newNode->Leaf.NoOfKeysThisNode = newNodeSize - 1;
-
- if((rc = PutLeafNode( nodeToSplit->NodeNo, nodeToSplit )) != 0) return rc;
- if((rc = PutLeafNode( newNode->NodeNo, newNode )) != 0) return rc;
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param RecBufSw
- \param KeyBufSw
-*/
-xbShort xbNdx::CreateKey( xbShort RecBufSw, xbShort KeyBufSw )
-{
- /* RecBufSw 0 Use RecBuf */
- /* 1 Use RecBuf2 */
- /* KeyBufSw 0 Use KeyBuf */
- /* 1 Use KeyBuf2 */
-
- xbShort rc;
- xbExpNode * TempNode;
-
- if(( rc = IxExp->ProcessExpression( RecBufSw )) != XB_NO_ERROR )
- return rc;
- TempNode = (xbExpNode *) IxExp->Pop();
- if( !TempNode )
- return XB_INVALID_KEY;
-
- if( KeyBufSw ){
- if( HeadNode.KeyType == 1 ) /* numeric key */
- dbf->xbase->PutDouble( KeyBuf2, TempNode->DoubResult );
- else{ /* character key */
- memset( KeyBuf2, 0x00, HeadNode.KeyLen + 1 );
- memcpy( KeyBuf2, TempNode->StringResult, XB_MIN(HeadNode.KeyLen + 1, TempNode->DataLen) );
- }
- } else {
- if( HeadNode.KeyType == 1 ) /* numeric key */
- dbf->xbase->PutDouble( KeyBuf, TempNode->DoubResult );
- else { /* character key */
- memset( KeyBuf, 0x00, HeadNode.KeyLen + 1 );
- memcpy( KeyBuf, TempNode->StringResult.c_str(), XB_MIN(HeadNode.KeyLen + 1, TempNode->DataLen) );
- }
- }
-// if( !TempNode->InTree ) dbf->xbase->FreeExpNode( TempNode );
- if( !TempNode->InTree ) delete TempNode;
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param key
-*/
-xbShort
-xbNdx::GetCurrentKey(char *key)
-{
- CreateKey(0, 0);
- if(HeadNode.KeyType == 1)
- memcpy(key, KeyBuf, 8);
- else
- memcpy(key, KeyBuf, HeadNode.KeyLen + 1);
- return 0;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param DbfRec
-*/
-xbShort xbNdx::AddKey( xbLong DbfRec )
-{
- /* This routine assumes KeyBuf contains the contents of the index to key */
-
- char *p;
- xbShort i,rc;
- xbNdxNodeLink * TempNode;
- xbNdxNodeLink * Tparent;
- xbLong TempNodeNo; /* new, unattached leaf node no */
- xbNdxNodeLink * SaveNodeChain;
- xbNdxNodeLink * SaveCurNode;
-
- /* find node key belongs in */
- rc = FindKey( KeyBuf, HeadNode.KeyLen, 0 );
- if( rc == XB_FOUND && HeadNode.Unique )
- return XB_KEY_NOT_UNIQUE;
-
- if( CurNode->Leaf.NoOfKeysThisNode > 0 && rc == XB_FOUND ){
- rc = 0;
- while( rc == 0 ){
- if(( p = GetKeyData( CurNode->CurKeyNo, CurNode )) == NULL )
- rc = -1;
- else {
- rc = CompareKey( KeyBuf, p, HeadNode.KeyLen );
- if( rc == 0 && DbfRec >= GetDbfNo( CurNode->CurKeyNo, CurNode )){
- if((rc = GetNextKey(0)) == XB_EOF) {
- if((rc = GetLastKey(0, 0)) != XB_NO_ERROR)
- return rc;
- CurNode->CurKeyNo++;
- }
- }
- else
- rc = -1;
- }
- }
- }
-
- /* update header node */
- HeadNode.NoOfKeys++;
- /************************************************/
- /* section A - if room in node, add key to node */
- /************************************************/
-
- if( CurNode->Leaf.NoOfKeysThisNode < HeadNode.KeysPerNode ){
- if(( rc = PutKeyInNode( CurNode,CurNode->CurKeyNo,DbfRec,0L,1)) != 0)
- return rc;
- if(( rc = PutHeadNode( &HeadNode, indexfp, 1 )) != 0)
- return rc;
- return XB_NO_ERROR;
- }
-
- /***********************************************************************/
- /* section B - split leaf node if full and put key in correct position */
- /***********************************************************************/
-
- TempNode = GetNodeMemory();
- TempNode->NodeNo = HeadNode.TotalNodes++;
- rc = SplitLeafNode( CurNode, TempNode, CurNode->CurKeyNo, DbfRec );
- if( rc )
- return rc;
-
- TempNodeNo = TempNode->NodeNo;
- ReleaseNodeMemory( TempNode );
-
- /*****************************************************/
- /* section C go up tree splitting nodes as necessary */
- /*****************************************************/
- Tparent = CurNode->PrevNode;
-
- while( Tparent &&
- Tparent->Leaf.NoOfKeysThisNode >= HeadNode.KeysPerNode-1) {
-
- TempNode = GetNodeMemory();
-
- if( !TempNode )
- return XB_NO_MEMORY;
- TempNode->NodeNo = HeadNode.TotalNodes++;
-
- rc = SplitINode( Tparent, TempNode, TempNodeNo );
- if( rc ) return rc;
-
- TempNodeNo = TempNode->NodeNo;
- ReleaseNodeMemory( TempNode );
- ReleaseNodeMemory( CurNode );
- CurNode = Tparent;
- CurNode->NextNode = NULL;
- Tparent = CurNode->PrevNode;
- }
-
- /************************************************************/
- /* Section D if CurNode is split root, create new root */
- /************************************************************/
-
- /* at this point
- CurNode = The node that was just split
- TempNodeNo = The new node split off from CurNode */
-
- if(CurNode->NodeNo == HeadNode.StartNode ){
- TempNode = GetNodeMemory();
- if( !TempNode )
- return XB_NO_MEMORY;
-
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
- SaveCurNode = CurNode;
- GetLastKey( CurNode->NodeNo, 0 );
- memcpy( KeyBuf, GetKeyData( CurNode->CurKeyNo,CurNode ),HeadNode.KeyLen );
- ReleaseNodeMemory( NodeChain );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- PutKeyData( 0, TempNode );
- PutLeftNodeNo( 0, TempNode, CurNode->NodeNo );
- PutLeftNodeNo( 1, TempNode, TempNodeNo );
- TempNode->NodeNo = HeadNode.TotalNodes++;
- TempNode->Leaf.NoOfKeysThisNode++;
- HeadNode.StartNode = TempNode->NodeNo;
- rc = PutLeafNode( TempNode->NodeNo, TempNode );
- if( rc ) return rc;
- rc = PutHeadNode( &HeadNode, indexfp, 1 );
- if( rc ) return rc;
- ReleaseNodeMemory( TempNode );
- return XB_NO_ERROR;
- }
- /**********************************/
- /* Section E make room in parent */
- /**********************************/
- for( i = Tparent->Leaf.NoOfKeysThisNode; i > Tparent->CurKeyNo; i-- ){
- memcpy( KeyBuf, GetKeyData( i-1, Tparent ), HeadNode.KeyLen );
- PutKeyData( i, Tparent );
- PutLeftNodeNo( i+1, Tparent, GetLeftNodeNo( i, Tparent ));
- }
-
- /* put key in parent */
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
- SaveCurNode = CurNode;
- GetLastKey( CurNode->NodeNo, 0 );
- memcpy( KeyBuf,GetKeyData( CurNode->CurKeyNo, CurNode ), HeadNode.KeyLen );
- ReleaseNodeMemory( NodeChain );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- PutKeyData( i, Tparent );
- PutLeftNodeNo( i+1, Tparent, TempNodeNo );
- Tparent->Leaf.NoOfKeysThisNode++;
- rc = PutLeafNode( Tparent->NodeNo, Tparent );
- if( rc ) return rc;
- rc = PutHeadNode( &HeadNode, indexfp, 1 );
- if( rc ) return rc;
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param pos
- \param n
-*/
-xbShort xbNdx::RemoveKeyFromNode( xbShort pos, xbNdxNodeLink *n )
-{
- xbShort i;
- /* check the node */
- if( !n )
- return XB_INVALID_NODELINK;
-
- if( pos < 0 || pos > HeadNode.KeysPerNode )
- return XB_INVALID_KEY;
-
- for( i = pos; i < n->Leaf.NoOfKeysThisNode-1; i++ ){
- memcpy( KeyBuf, GetKeyData( i+1, n), HeadNode.KeyLen );
- PutKeyData( i, n );
- PutDbfNo( i, n, GetDbfNo( i+1, n ));
- PutLeftNodeNo( i, n, GetLeftNodeNo( i+1, n ));
- }
- PutLeftNodeNo( i, n, GetLeftNodeNo( i+1, n ));
- n->Leaf.NoOfKeysThisNode--;
- /* if last key was deleted, decrement CurKeyNo */
- if( n->CurKeyNo > n->Leaf.NoOfKeysThisNode )
- n->CurKeyNo--;
- return PutLeafNode( n->NodeNo, n );
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param n
-*/
-xbShort xbNdx::UpdateParentKey( xbNdxNodeLink * n )
-{
-/* this routine goes backwards thru the node chain looking for a parent
- node to update */
-
- xbNdxNodeLink * TempNode;
- if( !n )
- return XB_INVALID_NODELINK;
-
- if( !GetDbfNo( 0, n ))
- return XB_NOT_LEAFNODE;
-
- TempNode = n->PrevNode;
- while( TempNode ){
- if( TempNode->CurKeyNo < TempNode->Leaf.NoOfKeysThisNode ){
- memcpy(KeyBuf,GetKeyData(n->Leaf.NoOfKeysThisNode-1,n),HeadNode.KeyLen);
- PutKeyData( TempNode->CurKeyNo, TempNode );
- return PutLeafNode( TempNode->NodeNo, TempNode );
- }
- TempNode = TempNode->PrevNode;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param n
-*/
-/* This routine queues up a list of nodes which have been emptied */
-void xbNdx::UpdateDeleteList( xbNdxNodeLink *n )
-{
- n->NextNode = DeleteChain;
- DeleteChain = n;
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-/* Delete nodes from the node list - for now we leave the empty nodes */
-/* dangling in the file. Eventually we will remove nodes from the file */
-
-void xbNdx::ProcessDeleteList( void )
-{
- if( DeleteChain ){
- ReleaseNodeMemory( DeleteChain );
- DeleteChain = NULL;
- }
-}
-/***********************************************************************/
-//! Short description
-/*!
-*/
-xbShort xbNdx::KeyWasChanged( void )
-{
- CreateKey( 0, 0 ); /* use KeyBuf, RecBuf */
- CreateKey( 1, 1 ); /* use KeyBuf2, RecBuf2 */
- if( CompareKey( KeyBuf, KeyBuf2, HeadNode.KeyLen ) != 0 )
- return 1;
- else
- return 0;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param n
-*/
-xbNdxNodeLink * xbNdx::LeftSiblingHasSpace( xbNdxNodeLink * n )
-{
- xbNdxNodeLink * TempNode;
- xbNdxNodeLink * SaveCurNode;
-
- /* returns a Nodelink to xbNdxNodeLink n's left sibling if it has space */
- /* if left most node in parent return NULL */
- if( n->PrevNode->CurKeyNo == 0 )
- return NULL;
-
- SaveCurNode = CurNode;
- GetLeafNode( GetLeftNodeNo( n->PrevNode->CurKeyNo-1, n->PrevNode ), 2 );
- if( CurNode->Leaf.NoOfKeysThisNode < HeadNode.KeysPerNode ){
- TempNode = CurNode;
- CurNode = SaveCurNode;
- TempNode->PrevNode = n->PrevNode;
- return TempNode;
- } else { /* node is already full */
- ReleaseNodeMemory( CurNode );
- CurNode = SaveCurNode;
- return NULL;
- }
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param n
-*/
-xbNdxNodeLink * xbNdx::RightSiblingHasSpace( xbNdxNodeLink * n )
-{
- /* returns a Nodelink to xbNdxNodeLink n's right sibling if it has space */
-
- xbNdxNodeLink * TempNode;
- xbNdxNodeLink * SaveCurNode;
-
- /* if left most node in parent return NULL */
- if( n->PrevNode->CurKeyNo >= n->PrevNode->Leaf.NoOfKeysThisNode )
- return NULL;
- SaveCurNode = CurNode;
- /* point curnode to right sib*/
- GetLeafNode( GetLeftNodeNo( n->PrevNode->CurKeyNo+1, n->PrevNode ), 2 );
- if( CurNode->Leaf.NoOfKeysThisNode < HeadNode.KeysPerNode ){
- TempNode = CurNode;
- CurNode = SaveCurNode;
- TempNode->PrevNode = n->PrevNode;
- return TempNode;
- } else { /* node is already full */
- ReleaseNodeMemory( CurNode );
- CurNode = SaveCurNode;
- return NULL;
- }
-}
-/*************************************************************************/
-//! Short description
-/*!
- \param n
- \param Right
-*/
-xbShort xbNdx::MoveToRightNode( xbNdxNodeLink * n, xbNdxNodeLink * Right )
-{
- xbShort j;
- xbNdxNodeLink * TempNode;
- xbNdxNodeLink * SaveCurNode;
- xbNdxNodeLink * SaveNodeChain;
-
- if( n->CurKeyNo == 0 ){
- j = 1;
- SaveNodeChain = NodeChain;
- SaveCurNode = CurNode;
- NodeChain = NULL;
- GetLastKey( n->NodeNo, 0 );
- memcpy( KeyBuf, GetKeyData( CurNode->CurKeyNo, CurNode),HeadNode.KeyLen);
- ReleaseNodeMemory( NodeChain );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- } else {
- j = 0;
- memcpy( KeyBuf, GetKeyData( j, n ), HeadNode.KeyLen);
- }
- PutKeyInNode( Right, 0, 0L, GetLeftNodeNo( j, n ), 1 );
- ReleaseNodeMemory( Right );
- TempNode = n;
- CurNode = n->PrevNode;
- n = n->PrevNode;
- n->NextNode = NULL;
- UpdateDeleteList( TempNode );
- DeleteSibling( n );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param n
- \param Left
-*/
-xbShort xbNdx::MoveToLeftNode( xbNdxNodeLink * n, xbNdxNodeLink * Left )
-{
- xbShort j, rc;
- xbNdxNodeLink * SaveNodeChain;
- xbNdxNodeLink * TempNode;
-
- if( n->CurKeyNo == 0 )
- j = 1;
- else
- j = 0;
-
- /* save the original node chain */
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
-
- /* determine new right most key for left node */
- GetLastKey( Left->NodeNo, 0 );
- memcpy( KeyBuf, GetKeyData( CurNode->CurKeyNo, CurNode ), HeadNode.KeyLen);
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL; /* for next GetLastKey */
- PutKeyData( Left->Leaf.NoOfKeysThisNode, Left);
- PutLeftNodeNo( Left->Leaf.NoOfKeysThisNode+1, Left, GetLeftNodeNo( j,n ));
- Left->Leaf.NoOfKeysThisNode++;
- Left->CurKeyNo = Left->Leaf.NoOfKeysThisNode;
- if(( rc = PutLeafNode( Left->NodeNo, Left )) != 0 )
- return rc;
- n->PrevNode->NextNode = NULL;
- UpdateDeleteList( n );
-
- /* get the new right most key for left to update parents */
- GetLastKey( Left->NodeNo, 0 );
-
- /* assemble the chain */
- TempNode = Left->PrevNode;
- TempNode->CurKeyNo--;
- NodeChain->PrevNode = Left->PrevNode;
- UpdateParentKey( CurNode );
- ReleaseNodeMemory( NodeChain );
- ReleaseNodeMemory( Left );
- CurNode = TempNode;
- NodeChain = SaveNodeChain;
- TempNode->CurKeyNo++;
- DeleteSibling( TempNode );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param n
-*/
-xbShort xbNdx::DeleteSibling( xbNdxNodeLink * n )
-{
- xbNdxNodeLink * Left;
- xbNdxNodeLink * Right;
- xbNdxNodeLink * SaveCurNode;
- xbNdxNodeLink * SaveNodeChain;
- xbNdxNodeLink * TempNode;
- xbShort rc;
-
- /* this routine deletes sibling CurRecNo out of xbNodeLink n */
- if( n->Leaf.NoOfKeysThisNode > 1 ){
- RemoveKeyFromNode( n->CurKeyNo, n );
- if( n->CurKeyNo == n->Leaf.NoOfKeysThisNode ){
- SaveNodeChain = NodeChain;
- SaveCurNode = CurNode;
- NodeChain = NULL;
- GetLastKey( n->NodeNo, 0 );
- /* assemble the node chain */
- TempNode = NodeChain->NextNode;
- NodeChain->NextNode = NULL;
- ReleaseNodeMemory( NodeChain );
- TempNode->PrevNode = n;
- UpdateParentKey( CurNode );
- /* take it back apart */
- ReleaseNodeMemory( TempNode );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- }
- } else if( n->NodeNo == HeadNode.StartNode ) {
- /* get here if root node and only one child remains */
- /* make remaining node the new root */
- if( n->CurKeyNo == 0 )
- HeadNode.StartNode = GetLeftNodeNo( 1, n );
- else
- HeadNode.StartNode = GetLeftNodeNo( 0, n );
- UpdateDeleteList( n );
- NodeChain = NULL;
- CurNode = NULL;
- }
- else if (( Left = LeftSiblingHasSpace( n )) != NULL )
- return MoveToLeftNode( n, Left );
- else if (( Right = RightSiblingHasSpace( n )) != NULL )
- return MoveToRightNode( n, Right );
- /* else if left sibling exists */
- else if( n->PrevNode->CurKeyNo > 0 ) {
- /* move right branch from left sibling to this node */
- SaveCurNode = CurNode;
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
- GetLeafNode( GetLeftNodeNo( n->PrevNode->CurKeyNo-1, n->PrevNode ), 2 );
- Left = CurNode;
- Left->PrevNode = SaveCurNode->PrevNode;
- GetLastKey( Left->NodeNo, 0 );
- strncpy( KeyBuf, GetKeyData( CurNode->CurKeyNo,CurNode),HeadNode.KeyLen );
- if( n->CurKeyNo == 1 )
- PutLeftNodeNo( 1, n, GetLeftNodeNo( 0, n ));
- PutKeyData( 0, n );
- PutLeftNodeNo( 0, n, GetLeftNodeNo( Left->Leaf.NoOfKeysThisNode, Left ));
- if(( rc = PutLeafNode( n->NodeNo, n )) != XB_NO_ERROR ) return rc;
- SaveCurNode = n->PrevNode;
- SaveCurNode->NextNode = NULL;
- ReleaseNodeMemory( n );
- Left->Leaf.NoOfKeysThisNode--;
- if(( rc = PutLeafNode( Left->NodeNo, Left )) != XB_NO_ERROR ) return rc;
- /* rebuild left side of tree */
- GetLastKey( Left->NodeNo, 0 );
- NodeChain->PrevNode = SaveCurNode;
- SaveCurNode->CurKeyNo--;
- UpdateParentKey( CurNode );
- ReleaseNodeMemory( NodeChain );
- ReleaseNodeMemory( Left );
- CurNode = SaveCurNode;
- NodeChain = SaveNodeChain;
- }
- /* right sibling must exist */
- else if( n->PrevNode->CurKeyNo <= n->PrevNode->Leaf.NoOfKeysThisNode ){
- /* move left branch from left sibling to this node */
- SaveCurNode = CurNode;
- SaveNodeChain = NodeChain;
- NodeChain = NULL;
-
- /* move the left node number one to the left if necessary */
- if( n->CurKeyNo == 0 ){
- PutLeftNodeNo( 0, n, GetLeftNodeNo( 1, n ));
- GetLastKey( GetLeftNodeNo( 0, n ), 0 );
- memcpy(KeyBuf,GetKeyData(CurNode->CurKeyNo,CurNode),HeadNode.KeyLen);
- PutKeyData( 0, n );
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL;
- }
- GetLeafNode( GetLeftNodeNo( n->PrevNode->CurKeyNo+1, n->PrevNode ), 2 );
- /* put leftmost node number from right node in this node */
- PutLeftNodeNo( 1, n, GetLeftNodeNo( 0, CurNode ));
- if(( rc = PutLeafNode( n->NodeNo, n )) != XB_NO_ERROR ) return rc;
-
- /* remove the key from the right node */
- RemoveKeyFromNode( 0, CurNode );
- if(( rc = PutLeafNode( CurNode->NodeNo, CurNode )) != XB_NO_ERROR )
- return rc;
- ReleaseNodeMemory( CurNode );
-
- /* update new parent key value */
- GetLastKey( n->NodeNo, 0 );
- NodeChain->PrevNode = n->PrevNode;
- UpdateParentKey( CurNode );
- ReleaseNodeMemory( NodeChain );
- NodeChain = SaveNodeChain;
- CurNode = SaveCurNode;
- } else {
- /* this should never be true-but could be if 100 byte limit is ignored*/
- std::cout << "Fatal index error" << std::endl;
- exit(0);
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description
-/*!
- \param DbfRec
-*/
-xbShort xbNdx::DeleteKey( xbLong DbfRec )
-{
-/* this routine assumes the key to be deleted is in KeyBuf */
-
- xbNdxNodeLink * TempNode;
- xbShort rc;
-
-#if 0
- // Not sure why this check is here, but it prevents numeric keys
- // from being deleted (and thus index updates will also fail).
- // I have removed it for now. Derry Bryson
- if( HeadNode.KeyType != 0x00 )
- xb_error(XB_INVALID_KEY_TYPE);
-#endif
-
- if(( rc = FindKey( KeyBuf, DbfRec )) != XB_FOUND )
- return rc;
-
- /* found the record to delete at this point */
- HeadNode.NoOfKeys--;
-
- /* delete the key from the node */
- if(( rc = RemoveKeyFromNode( CurNode->CurKeyNo, CurNode )) != 0 )
- return rc;
-
- /* if root node, we are done */
- if( !( CurNode->NodeNo == HeadNode.StartNode )){
- /* if leaf node now empty */
- if( CurNode->Leaf.NoOfKeysThisNode == 0 ){
- TempNode = CurNode->PrevNode;
- TempNode->NextNode = NULL;
- UpdateDeleteList( CurNode );
- CurNode = TempNode;
- DeleteSibling( CurNode );
- ProcessDeleteList();
- }
-
- /* if last key of leaf updated, update key in parent node */
- /* this logic updates the correct parent key */
-
- else if( CurNode->CurKeyNo == CurNode->Leaf.NoOfKeysThisNode )
- UpdateParentKey( CurNode );
- }
-
- if(CurNode)
- CurDbfRec = GetDbfNo( CurNode->CurKeyNo, CurNode );
- else
- CurDbfRec = 0;
-
- if(( rc = PutHeadNode( &HeadNode, indexfp, 1 )) != 0 )
- return rc;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description
-/*!
- \param option
-*/
-#ifdef XBASE_DEBUG
-xbShort xbNdx::CheckIndexIntegrity( const xbShort option )
-{
- /* if option = 1, print out some stats */
- xbShort rc;
- xbLong ctr = 1L;
- while( ctr <= dbf->NoOfRecords()){
- if( option ) std::cout << "Checking Record " << ctr << std::endl;
- if(( rc = dbf->GetRecord(ctr++)) != XB_NO_ERROR )
- return rc;
- if(!dbf->RecordDeleted()){
- CreateKey( 0, 0 );
- rc = FindKey( KeyBuf, dbf->GetCurRecNo());
- if( rc != XB_FOUND ){
- if( option ){
- std::cout << "Record number " << dbf->GetCurRecNo()
- << " Not Found" << std::endl;
- std::cout << "Key = " << KeyBuf << std::endl;
- }
- return rc;
- }
- }
- }
- if( option )
- std::cout << std::endl << "Total records checked = "
- << ctr - 1 << std::endl;
- return XB_NO_ERROR;
-}
-#endif
-/***********************************************************************/
-//! Short description
-/*!
- \param statusFunc
-*/
-xbShort xbNdx::ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems))
-{
- /* this method assumes the index has been locked in exclusive mode */
- xbLong l;
- xbShort rc, i, saveAutoLock;
- xbNdxHeadNode TempHead;
- FILE *t;
- xbString TempName;
- memcpy( &TempHead, &HeadNode, sizeof( struct xbNdxHeadNode ));
- TempHead.NoOfKeys = 1L;
- TempHead.TotalNodes = 2L;
- TempHead.StartNode = 1L;
- rc = dbf->xbase->DirectoryExistsInName( GetFileName() );
- if( rc ){
- TempName.assign(GetFileName(), 0, rc);
- TempName += "TEMPFILE.NDX";
- } else
- TempName = "TEMPFILE.NDX";
-
- if(( t = fopen( TempName, "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-
- if(( rc = PutHeadNode( &TempHead, t, 0 )) != 0 ){
- fclose( t );
- remove(TempName);
- return rc;
- }
-
- for( i = 0; i < XB_NDX_NODE_SIZE; i++ ){
- if(( fwrite( "\x00", 1, 1, t )) != 1 ){
- fclose( t );
- remove(TempName);
- return XB_WRITE_ERROR;
- }
- }
- if( fclose( indexfp ) != 0 )
- return XB_CLOSE_ERROR;
- if( fclose( t ) != 0 )
- return XB_CLOSE_ERROR;
- if( remove( GetFileName() ) != 0 )
- return XB_CLOSE_ERROR;
- if( rename(TempName, GetFileName() ) != 0 )
- return XB_WRITE_ERROR;
- if(( indexfp = fopen( GetFileName(), "r+b" )) == NULL )
- return XB_OPEN_ERROR;
-
- saveAutoLock = dbf->GetAutoLock();
- dbf->AutoLockOff();
- for( l = 1; l <= dbf->PhysicalNoOfRecords(); l++ ){
- if(statusFunc && (l == 1 || !(l % 100) || l == dbf->PhysicalNoOfRecords()))
- statusFunc(l, dbf->PhysicalNoOfRecords());
- if(( rc = dbf->GetRecord(l)) != XB_NO_ERROR ){
- if(saveAutoLock)
- dbf->AutoLockOn();
- return rc;
- }
-
- if(!dbf->GetRealDelete() || !dbf->RecordDeleted()){
- /* Create the key */
- CreateKey( 0, 0 );
- /* add key to index */
- if(( rc = AddKey( l )) != XB_NO_ERROR ){
- if(saveAutoLock)
- dbf->AutoLockOn();
- return rc;
- }
- }
- }
- return rc;
-}
-
-/***********************************************************************/
-//! Short description
-/*!
- \param size
-*/
-void xbNdx::SetNodeSize(xbShort size)
-{
-#ifdef XB_VAR_NODESIZE
- if(size >= XB_DEFAULT_NDX_NODE_SIZE)
- {
- if(size % XB_NDX_NODE_MULTIPLE)
- NodeSize = ((size + XB_NDX_NODE_MULTIPLE) / XB_NDX_NODE_MULTIPLE) *
- XB_NDX_NODE_MULTIPLE;
- else
- NodeSize = size;
- }
- else
- NodeSize = XB_DEFAULT_NDX_NODE_SIZE;
-#endif
-}
-
-/***********************************************************************/
-//! Short description
-/*!
- \param buf
- \param len
-*/
-void xbNdx::GetExpression(char *buf, int len)
-{
- memcpy(buf, HeadNode.KeyExpression,
- len < XB_NDX_NODE_SIZE ? len : XB_NDX_NODE_SIZE - XB_NDX_NODE_BASESIZE);
-}
-
-const char* xbNdx::GetExtWithDot(bool lower)
-{
- return lower? ".ndx": ".NDX";
-}
-
-xbUShort xbNdx::GetKeyLen()
-{
- return HeadNode.KeyLen;
-}
-
-const char* xbNdx::GetKeyExpression()
-{
- return HeadNode.KeyExpression;
-}
-
-void xbNdx::FreeNodesMemory()
-{
- ReleaseNodeMemory(NodeChain, true);
- NodeChain = 0;
-// ReleaseNodeMemory(CloneChain, true);
-// CloneChain = 0;
- ReleaseNodeMemory(FreeNodeChain, true);
- FreeNodeChain = 0;
- ReleaseNodeMemory(DeleteChain, true);
- DeleteChain = 0;
-}
-
-#endif /* XB_INDEX_NDX */
diff --git a/xbase64/xbndx.h b/xbase64/xbndx.h
deleted file mode 100755
index 9f9d2d7..0000000
--- a/xbase64/xbndx.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/* xbndx.h
-
- Xbase64 project source code
-
- This file contains a header file for the xbNdx object, which is used
- for handling NDX type indices.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XB_NDX_H__
-#define __XB_NDX_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#include <xbase64/xbase64.h>
-#include <string.h>
-
-/*! \file xbndx.h
-*/
-
-//
-// Define the following to use inline versions of the respective methods.
-//
-#define XB_INLINE_GETDBFNO
-
-#define XB_NDX_NODE_BASESIZE 24 // size of base header data
-
-#define XB_VAR_NODESIZE // define to enable variable node sizes
-
-#ifndef XB_VAR_NODESIZE
-#define XB_NDX_NODE_SIZE 2048
-//#define XB_NDX_NODE_SIZE 512 // standard dbase node size
-#else
-#define XB_DEFAULT_NDX_NODE_SIZE 512
-#define XB_MAX_NDX_NODE_SIZE 4096
-#define XB_NDX_NODE_SIZE NodeSize
-#define XB_NDX_NODE_MULTIPLE 512
-#endif // XB_VAR_NODESIZE
-
-//! xbNdxHeadnode struct
-/*!
-*/
-
-struct XBDLLEXPORT xbNdxHeadNode { /* ndx header on disk */
- xbLong StartNode; /* header node is node 0 */
- xbLong TotalNodes; /* includes header node */
- xbLong NoOfKeys; /* actual count + 1 */
- /* not updated by borland dbe? */
- xbUShort KeyLen; /* length of key data */
- xbUShort KeysPerNode;
- xbUShort KeyType; /* 00 = Char, 01 = Numeric */
- xbLong KeySize; /* key len + 8 bytes */
- char Unknown2;
- char Unique;
-// char KeyExpression[488];
-#ifndef XB_VAR_NODESIZE
- char KeyExpression[XB_NDX_NODE_SIZE - 24];
-#else
- char KeyExpression[XB_MAX_NDX_NODE_SIZE - 24];
-#endif // XB_VAR_NODESIZE
-};
-
-//! xbNdxLeafNode struct
-/*!
-*/
-
-struct XBDLLEXPORT xbNdxLeafNode { /* ndx node on disk */
- xbLong NoOfKeysThisNode;
-#ifndef XB_VAR_NODESIZE
- char KeyRecs[XB_NDX_NODE_SIZE-4];
-#else
- char KeyRecs[XB_MAX_NDX_NODE_SIZE - 4];
-#endif // XB_VAR_NODESIZE
-};
-
-//! xbNdxNodeLink struct
-/*!
-*/
-
-struct XBDLLEXPORT xbNdxNodeLink { /* ndx node memory */
- xbNdxNodeLink * PrevNode;
- xbNdxNodeLink * NextNode;
- xbLong CurKeyNo; /* 0 - KeysPerNode-1 */
- xbLong NodeNo;
- struct xbNdxLeafNode Leaf;
-};
-
-//! xbNdx class
-/*!
-*/
-
-class XBDLLEXPORT xbNdx : public xbIndex
-{
- public:
- xbNdx();
- xbNdx(xbDbf *);
- virtual ~xbNdx();
-
-/* don't uncomment next line - it causes seg faults for some undiagnosed reason*/
-// ~NDX() { if( NdxStatus ) CloseIndex(); }
-
- xbShort CreateIndex( const char *IxName, const char *Exp,
- xbShort Unique, xbShort OverLay );
- xbLong GetTotalNodes();
- xbULong GetCurDbfRec() { return CurDbfRec; }
- xbShort CreateKey( xbShort, xbShort );
- xbShort GetCurrentKey(char *key);
- xbShort AddKey( xbLong );
- xbShort UniqueIndex() { return HeadNode.Unique; }
- xbShort DeleteKey( xbLong );
- xbShort KeyWasChanged();
- xbShort FindKey( const char *Key );
- xbShort FindKey();
- xbShort FindKey( xbDouble );
-#ifdef XBASE_DEBUG
- void DumpHdrNode( xbShort Option );
- void DumpNodeRec( xbLong NodeNo );
- void DumpNodeChain();
- xbShort CheckIndexIntegrity( xbShort Option );
-#endif
- //! Short description.
- /*!
- */
- xbShort GetNextKey() { return GetNextKey( 1 ); }
- //! Short description.
- /*!
- */
- xbShort GetLastKey() { return GetLastKey( 0, 1 ); }
- //! Short description.
- /*!
- */
- xbShort GetFirstKey() { return GetFirstKey( 1 ); }
- //! Short description.
- /*!
- */
- xbShort GetPrevKey() { return GetPrevKey( 1 ); }
- xbShort ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0);
- xbShort KeyExists( const char * Key ) { return FindKey( Key, strlen( Key ), 0 ); }
- xbShort KeyExists( xbDouble );
-
- virtual void SetNodeSize(xbShort size);
-
- virtual void GetExpression(char *buf, int len);
- virtual const char* GetExtWithDot(bool lower);
-
- protected:
- virtual xbUShort GetKeyLen();
- virtual const char* GetKeyExpression();
- virtual void FreeNodesMemory();
-
- protected:
- xbNdxHeadNode HeadNode;
- xbNdxLeafNode LeafNode;
- xbLong xbNodeLinkCtr;
- xbLong ReusedxbNodeLinks;
-
-#ifndef XB_VAR_NODESIZE
- char Node[XB_NDX_NODE_SIZE];
-#else
- char Node[XB_MAX_NDX_NODE_SIZE];
-#endif // XB_VAR_NODESIZE
-
- xbNdxNodeLink * NodeChain; /* pointer to node chain of index nodes */
- xbNdxNodeLink * FreeNodeChain; /* pointer to chain of free index nodes */
- xbNdxNodeLink * CurNode; /* pointer to current node */
- xbNdxNodeLink * DeleteChain; /* pointer to chain to delete */
-// xbNdxNodeLink * CloneChain; /* pointer to node chain copy (add dup) */
-
-/* private functions */
- xbLong GetLeftNodeNo( xbShort, xbNdxNodeLink * );
-
-
- // in line functions for performance reasons
- //! Short description.
- /*!
- */
- inline xbShort CompareKey( const char *Key1, const char *Key2, xbShort Klen )
- {
- xbDouble d1, d2;
- int c;
-
- if(!( Key1 && Key2 )) return -1;
-
- if( Klen > HeadNode.KeyLen ) Klen = HeadNode.KeyLen;
-
- if( HeadNode.KeyType == 0 )
- {
- c = memcmp(Key1, Key2, Klen);
- if(c < 0)
- return 2;
- else if(c > 0)
- return 1;
- return 0;
- }
- else /* key is numeric */
- {
- d1 = dbf->xbase->GetDouble( Key1 );
- d2 = dbf->xbase->GetDouble( Key2 );
- if( d1 == d2 ) return 0;
- else if( d1 > d2 ) return 1;
- else return 2;
- }
- }
-
-#ifndef XB_INLINE_GETDBFNO
- xbLong GetDbfNo( xbShort, xbNdxNodeLink * );
-#else
- //! Short description.
- /*!
- */
- inline xbLong GetDbfNo( xbShort RecNo, xbNdxNodeLink *n )
- {
- xbNdxLeafNode *temp;
- char *p;
- if( !n ) return 0L;
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode - 1 )) return 0L;
- p = temp->KeyRecs + 4;
- p += RecNo * ( 8 + HeadNode.KeyLen );
- return( dbf->xbase->GetLong( p ));
- }
-#endif
- char * GetKeyData( xbShort, xbNdxNodeLink * );
- xbUShort GetKeysPerNode();
- virtual xbShort GetHeadNode();
- xbShort GetLeafNode( xbLong, xbShort );
- xbNdxNodeLink * GetNodeMemory();
- void ReleaseNodeMemory(xbNdxNodeLink *n, xbBool doFree = false);
- xbShort BSearchNode(const char *key, xbShort klen,
- const xbNdxNodeLink *node, xbShort *comp);
- xbLong GetLeafFromInteriorNode( const char *Tkey, xbShort Klen );
- xbShort CalcKeyLen();
- xbShort PutKeyData( xbShort, xbNdxNodeLink * );
- xbShort PutLeftNodeNo( xbShort, xbNdxNodeLink *, xbLong );
- xbShort PutLeafNode( xbLong, xbNdxNodeLink * );
- xbShort PutHeadNode( xbNdxHeadNode *, FILE *, xbShort );
- xbShort PutDbfNo( xbShort, xbNdxNodeLink *, xbLong );
- xbShort PutKeyInNode( xbNdxNodeLink *, xbShort, xbLong, xbLong, xbShort );
- xbShort SplitLeafNode( xbNdxNodeLink *, xbNdxNodeLink *, xbShort, xbLong );
- xbShort SplitINode( xbNdxNodeLink *, xbNdxNodeLink *, xbLong );
- xbShort AddToIxList();
- xbShort RemoveFromIxList();
- xbShort RemoveKeyFromNode( xbShort, xbNdxNodeLink * );
- xbShort FindKey( const char *Tkey, xbShort Klen, xbShort RetrieveSw );
- xbShort UpdateParentKey( xbNdxNodeLink * );
- xbShort GetFirstKey( xbShort );
- xbShort GetNextKey( xbShort );
- xbShort GetLastKey( xbLong, xbShort );
- xbShort GetPrevKey( xbShort );
- void UpdateDeleteList( xbNdxNodeLink * );
- void ProcessDeleteList();
- xbNdxNodeLink * LeftSiblingHasSpace( xbNdxNodeLink * );
- xbNdxNodeLink * RightSiblingHasSpace( xbNdxNodeLink * );
- xbShort DeleteSibling( xbNdxNodeLink * );
- xbShort MoveToLeftNode( xbNdxNodeLink *, xbNdxNodeLink * );
- xbShort MoveToRightNode( xbNdxNodeLink *, xbNdxNodeLink * );
- xbShort FindKey( const char *Tkey, xbLong DbfRec ); /* for a specific dbf no */
-};
-#endif /* __XB_NDX_H__ */
diff --git a/xbase64/xbnode.cpp b/xbase64/xbnode.cpp
deleted file mode 100755
index 5e688c1..0000000
--- a/xbase64/xbnode.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "xbNode.h"
-
-void xbNodeLink::AddNode(xbNodeLink* node)
-{
- nextNode_=node;
-}
diff --git a/xbase64/xbnode.h b/xbase64/xbnode.h
deleted file mode 100755
index b1c3fdf..0000000
--- a/xbase64/xbnode.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef xbNode_h
-#define xbNode_h
-
-class xbNodeLink
-{
- public:
- xbNodeLink(): nextNode_(0) {}
- void AddNode(xbNodeLink* node);
- xbNodeLink* GetNext() {return nextNode_;}
-
- private:
- xbNodeLink(const xbNodeLink&);
- xbNodeLink& operator=(const xbNodeLink&);
-
- private:
- xbNodeLink* nextNode_;
-};
-
-#endif
diff --git a/xbase64/xbntx.cpp b/xbase64/xbntx.cpp
deleted file mode 100755
index 673aa68..0000000
--- a/xbase64/xbntx.cpp
+++ /dev/null
@@ -1,2604 +0,0 @@
-/* xbntx.xpp
-
- Xbase64 project source code
-
- NTX (Clipper) indexing routines for X-Base
-
- Copyright (C) 1999 SynXis Corp., Bob Cotton
- email - bob@synxis.com
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbntx.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-#ifdef XB_INDEX_NTX
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <ctype.h>
-#include <sys/stat.h>
-
-//#include <xbase64/xbexcept.h>
-
-/*! \file xbntx.cpp
-*/
-
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-/* This routine dumps the node chain to stdout */
-#ifdef XBASE_DEBUG
-void xbNtx::DumpNodeChain( void )
-{
- xbNodeLink *n;
- std::cout << "*************************" << std::endl;
- std::cout << "NodeLinkCtr = " << NodeLinkCtr << std::endl;
- std::cout << "Reused = " << ReusedNodeLinks << std::endl;
-
- n = NodeChain;
- while(n){
- std::cout << "xbNodeLink Chain" << n->NodeNo << std::endl;
- n = n->NextNode;
- }
- n = FreeNodeChain;
- while(n){
- std::cout << "FreeNodeLink Chain" << n->NodeNo << std::endl;
- n = n->NextNode;
- }
- n = DeleteChain;
- while(n){
- std::cout << "DeleteLink Chain" << n->NodeNo << std::endl;
- n = n->NextNode;
- }
-}
-#endif
-/***********************************************************************/
-//! Short description.
-/*!
- \param n
-*/
-/* This routine returns a chain of one or more index nodes back to the */
-/* free node chain */
-
-void xbNtx::ReleaseNodeMemory( xbNodeLink * n, xbBool doFree )
-{
- xbNodeLink *temp;
-
- if(doFree){
- while(n){
- temp = n->NextNode;
- if(n->offsets)
- free(n->offsets);
- free(n);
- n = temp;
- }
- } else {
- if(!FreeNodeChain )
- FreeNodeChain = n;
- else { /* put this list at the end */
- temp = FreeNodeChain;
- while( temp->NextNode )
- temp = temp->NextNode;
- temp->NextNode = n;
- }
- }
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-/* This routine returns a node from the free chain if available, */
-/* otherwise it allocates new memory for the requested node */
-
-xbNodeLink * xbNtx::GetNodeMemory( void )
-{
- xbNodeLink * temp;
- if( FreeNodeChain ){
- temp = FreeNodeChain;
- temp->offsets = FreeNodeChain->offsets;
- FreeNodeChain = temp->NextNode;
- ReusedNodeLinks++;
- memset( temp->Leaf.KeyRecs, 0x00, XB_NTX_NODE_SIZE );
- temp->Leaf.NoOfKeysThisNode = 0;
- temp->PrevNode = 0x00;
- temp->NextNode = 0x00;
- temp->CurKeyNo = 0L;
- temp->NodeNo = 0L;
-
- for (int i = 0; i < HeadNode.KeysPerNode + 1; i++){
- temp->offsets[i] = 2 + ((HeadNode.KeysPerNode + 1) * 2) + (HeadNode.KeySize * i);
- }
- } else {
- temp = (xbNodeLink *) malloc( sizeof( xbNodeLink ));
- if(temp==NULL) return NULL;
- memset( temp, 0x00, sizeof( xbNodeLink ));
- temp->offsets = (xbUShort *)malloc( (HeadNode.KeysPerNode + 1) * sizeof(xbUShort));
- if (temp->offsets==NULL) {
- free(temp);
- return NULL;
- };
- NodeLinkCtr++;
- }
- return temp;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-#ifdef XBASE_DEBUG
-void xbNtx::DumpHdrNode( xbShort Option )
-{
- if( Option == 0 ){
- std::cout << "Signature = " << HeadNode.Signature << std::endl;
- std::cout << "Version = " << HeadNode.Version << std::endl;
- std::cout << "StartPahe = " << HeadNode.StartNode << std::endl;
- std::cout << "UnusedOffset = " << HeadNode.UnusedOffset << std::endl;
- std::cout << "KeySize = " << HeadNode.KeySize << std::endl;
- std::cout << "KeyLen = " << HeadNode.KeyLen << std::endl;
- std::cout << "DecimalCount = " << HeadNode.DecimalCount << std::endl;
- std::cout << "KeysPerNode = " << HeadNode.KeysPerNode << std::endl;
- std::cout << "HalfKeysPerPage = " << HeadNode.HalfKeysPerNode << std::endl;
- std::cout << "KeyExpression = " << HeadNode.KeyExpression << std::endl;
- std::cout << "Unique = " << HeadNode.Unique << std::endl;
- } else
- std::cout << "Print Hdr Node option not implemented yet" << std::endl;
-}
-#endif
-/***********************************************************************/
-//! Constructor
-/*!
-*/
-xbNtx::xbNtx() : xbIndex()
-{
-}
-/***********************************************************************/
-//! Constructor
-/*!
- \param pdbf
-*/
-xbNtx::xbNtx( xbDbf * pdbf ) : xbIndex (pdbf)
-{
- memset( Node, 0x00, XB_NTX_NODE_SIZE );
- memset( &HeadNode, 0x00, sizeof( NtxHeadNode ));
- NodeChain = NULL;
-// CloneChain = NULL;
- FreeNodeChain = NULL;
- DeleteChain = NULL;
- CurNode = NULL;
- NodeLinkCtr = 0L;
- ReusedNodeLinks = 0L;
-}
-/***********************************************************************/
-//! Destructor
-/*!
-*/
-xbNtx::~xbNtx()
-{
- CloseIndex();
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbNtx::GetHeadNode( void )
-{
- char *p;
- if( !IsOpen() )
- return XB_NOT_OPEN;
- if( _fseek( indexfp, 0, SEEK_SET ))
- return XB_SEEK_ERROR;
- if(( fread( Node, XB_NTX_NODE_SIZE, 1, indexfp )) != 1 )
- return XB_READ_ERROR;
-
- /* load the head node structure */
- p = Node;
- HeadNode.Signature = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);
- HeadNode.Version = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);
- HeadNode.StartNode = dbf->xbase->GetULong( p ); p += sizeof(xbULong);
- HeadNode.UnusedOffset = dbf->xbase->GetULong( p ); p += sizeof(xbULong);
- HeadNode.KeySize = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);
- HeadNode.KeyLen = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);
- HeadNode.DecimalCount = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);
- HeadNode.KeysPerNode = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);
- HeadNode.HalfKeysPerNode = dbf->xbase->GetShort( p ); p += sizeof(xbUShort);
- strncpy(HeadNode.KeyExpression, p, 256); p+= 256;
-// HeadNode.Unique = *p++; ++ is unused code 8/19/03 - gkunkel
- HeadNode.Unique = *p;
-
- p = HeadNode.KeyExpression;
- while (*p){
- *p = toupper(*p);
- p++;
- }
- return 0;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param NodeNo
- \param SetNodeChain
-*/
-/* This routine reads a leaf node from disk */
-/* */
-/* If SetNodeChain 2, then the node is not appended to the node chain */
-/* but the CurNode pointer points to the node read */
-/* If SetNodeChain 1, then the node is appended to the node chain */
-/* If SetNodeChain 0, then record is only read to Node memory */
-
-xbShort xbNtx::GetLeafNode( xbLong NodeNo, xbShort SetNodeChain )
-{
- xbNodeLink *n;
- char *p;
-
- if( !IsOpen() )
- return XB_NOT_OPEN;
-
- if( _fseek( indexfp, (xbOffT)NodeNo, SEEK_SET ))
- return XB_SEEK_ERROR;
-
- if(( fread( Node, XB_NTX_NODE_SIZE, 1, indexfp )) != 1 )
- return XB_READ_ERROR;
-
- if( !SetNodeChain ) return 0;
-
- if(( n = GetNodeMemory()) == NULL )
- return XB_NO_MEMORY;
-
- n->NodeNo = NodeNo;
- n->CurKeyNo = 0L;
- n->NextNode = NULL;
-
- // The offsets at the head of each leaf are not necessarly in order.
- p = Node + 2;
- for( int i = 0; i < HeadNode.KeysPerNode + 1; i++){
- n->offsets[i] = dbf->xbase->GetShort( p );
- p += 2;
- }
-
- // Do the edian translation correctly
- n->Leaf.NoOfKeysThisNode = dbf->xbase->GetShort( Node );
- memcpy( n->Leaf.KeyRecs, Node, XB_NTX_NODE_SIZE );
-
- /* put the node in the chain */
- if( SetNodeChain == 1 ){
- if( NodeChain == NULL ){ /* first one ? */
- NodeChain = n;
- CurNode = n;
- CurNode->PrevNode = NULL;
- } else {
- n->PrevNode = CurNode;
- CurNode->NextNode = n;
- CurNode = n;
- }
- }
- else
- CurNode = n;
-
- return 0;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param n
-*/
-#ifdef XBASE_DEBUG
-void xbNtx::DumpNodeRec( xbLong n )
-{
- char *p;
- xbShort NoOfKeys;
- xbLong LeftBranch, RecNo;
- xbShort i,j;
-
- GetLeafNode( n, 0 );
- NoOfKeys = dbf->xbase->GetShort( Node );
- p = Node + 4; /* go past no of keys */
-std::cout << "-----------------------------------------------" << std::endl;
- std::cout << "Node # " << n;
- std::cout << "Number of keys = " << NoOfKeys << std::endl;
- std::cout << " Key Left Rec Key" << std::endl;
- std::cout << "Number Branch Number Data" << std::endl;
-
- for( i = 0; i < GetKeysPerNode()+1 /*NoOfKeys*/; i++ ){
- LeftBranch = dbf->xbase->GetLong( p );
- p+=4;
- RecNo = dbf->xbase->GetLong( p );
- p+=4;
- std::cout << i << " "
- << LeftBranch << " "
- << RecNo << " " << std::endl;
- for( j = 0; j < HeadNode.KeyLen; j++ ) std::cout << *p++;
- }
-}
-#endif
-/***********************************************************************/
-//! Short description.
-/*!
- \param RecNo
- \param n
-*/
-xbLong xbNtx::GetDbfNo( xbShort RecNo, xbNodeLink * n )
-{
- NtxLeafNode *temp;
- char *p;
- xbUShort itemOffset;
-
- if( !n ) return 0L;
- temp = &n->Leaf;
- p = temp->KeyRecs;
- if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode )) return 0L;
- itemOffset = GetItemOffset(RecNo, n, 0);
- // ItemOffset is from the beginning of the record.
- p += itemOffset;
- p += 4;
- return( dbf->xbase->GetLong( p ));
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param RecNo
- \param n
-*/
-xbLong xbNtx::GetLeftNodeNo( xbShort RecNo, xbNodeLink * n )
-{
- NtxLeafNode *temp;
- char *p;
- xbUShort itemOffset;
-
- if( !n ) return 0L;
- temp = &n->Leaf;
- p = temp->KeyRecs;
- if( RecNo < 0 || RecNo > temp->NoOfKeysThisNode ) return 0L;
- itemOffset = GetItemOffset(RecNo, n, 0);
- // ItemOffset is from the beginning of the record.
- p += itemOffset;
- return( dbf->xbase->GetULong( p ));
-}
-
-/***********************************************************************/
-//! Short description.
-/*!
- \param RecNo
- \param n
-*/
-char * xbNtx::GetKeyData( xbShort RecNo, xbNodeLink * n )
-{
- NtxLeafNode *temp;
- char *p;
- xbUShort itemOffset;
- if( !n ) return 0L;
- temp = &n->Leaf;
- p = temp->KeyRecs;
- if( RecNo < 0 || RecNo > ( temp->NoOfKeysThisNode )) return 0L;
- itemOffset = GetItemOffset(RecNo, n, 0);
- // ItemOffset is from the beginning of the record.
- p += itemOffset + 8;
- return( p );
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param RecNo
- \param n
- \param
-*/
-xbUShort
-xbNtx::GetItemOffset(xbShort RecNo, xbNodeLink *n, xbShort) {
- if( RecNo > (this->HeadNode.KeysPerNode + 1) ){
- std::cout << "RecNo = " << RecNo << std::endl;
- std::cout << "this->HeadNode.KeysPerNode = "
- << this->HeadNode.KeysPerNode << std::endl;
- std::cout << "********************* BUG ***********************"
- << std::endl;
- // ;-)
- exit(1);
- }
-
- return n->offsets[RecNo];
-}
-
-//! Short description.
-/*!
- \param pos
- \param n
-*/
-xbUShort
-xbNtx::InsertKeyOffset(xbShort pos, xbNodeLink *n)
-{
- xbUShort temp;
-
- // save the new offset
- temp = n->offsets[n->Leaf.NoOfKeysThisNode + 1];
-
- for( int i = n->Leaf.NoOfKeysThisNode + 1; i > pos; i-- ){
- n->offsets[i] = n->offsets[i-1];
- }
- n->offsets[pos] = temp;
-
- return n->offsets[pos];
-}
-
-//! Short description.
-/*!
- \param pos
- \param n
-*/
-xbUShort
-xbNtx::DeleteKeyOffset(xbShort pos, xbNodeLink *n)
-{
- xbUShort temp;
- xbShort i;
- // save the old offset
- temp = n->offsets[pos];
-
- for( i = pos; i < n->Leaf.NoOfKeysThisNode; i++ ){
- n->offsets[i] = n->offsets[i+1];
- }
- n->offsets[i] = temp;
- return n->offsets[i];
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbLong xbNtx::GetTotalNodes( void )
-{
-// if( &HeadNode )
-// return HeadNode.TotalNodes;
-// else
- return 0L;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbUShort xbNtx::GetKeysPerNode( void )
-{
- if( &HeadNode )
- return HeadNode.KeysPerNode;
- else
- return 0L;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param RetrieveSw
-*/
-xbShort xbNtx::GetFirstKey( xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the first index pointer */
-
- xbLong TempNodeNo;
- xbShort rc;
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// if((rc = LockIndex( XB_LOCK )) != 0)
-// return rc;
-#endif
-
- /* initialize the node chain */
- if( NodeChain ){
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL;
- }
-
- if(( rc = GetHeadNode()) != 0 ){
- CurDbfRec = 0L;
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
- /* get a node and add it to the link */
-
- if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
-/* traverse down the left side of the tree */
- while( GetLeftNodeNo( 0, CurNode )){
- TempNodeNo = GetLeftNodeNo( 0, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
- CurNode->CurKeyNo = 0;
- }
- CurDbfRec = GetDbfNo( 0, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param RetrieveSw
-*/
-xbShort xbNtx::GetNextKey( xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the next index pointer */
-
- xbNodeLink * TempNodeLink;
- xbLong TempNodeNo;
- xbShort rc;
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
- // if((rc = LockIndex( XB_LOCK )) != 0)
- // return rc;
-#endif
-
- if( !IsOpen() ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return XB_NOT_OPEN;
- }
-
- if( !CurNode ){
- rc = GetFirstKey( RetrieveSw );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
- /* more keys on this node ? */
- if(( CurNode->Leaf.NoOfKeysThisNode -1 ) > CurNode->CurKeyNo ){
- CurNode->CurKeyNo++;
- CurDbfRec = GetDbfNo( CurNode->CurKeyNo, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
- }
-
- /* if head node we are at eof */
- if( CurNode->NodeNo == HeadNode.StartNode ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_EOF;
- }
-
- /* this logic assumes that interior nodes have n+1 left node no's where */
- /* n is the number of keys in the node */
- /* pop up one node to the interior node level & free the leaf node */
- TempNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempNodeLink );
-
- /* while no more right keys && not head node, pop up one node */
- while(( CurNode->CurKeyNo >= CurNode->Leaf.NoOfKeysThisNode ) &&
- ( CurNode->NodeNo != HeadNode.StartNode )){
- TempNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempNodeLink );
- }
-
- /* if head node && right most key, return end-of-file */
- if(( HeadNode.StartNode == CurNode->NodeNo ) &&
- ( CurNode->CurKeyNo >= CurNode->Leaf.NoOfKeysThisNode )){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_EOF;
- }
-
- /* move one to the right */
- CurNode->CurKeyNo++;
- TempNodeNo = GetLeftNodeNo( CurNode->CurKeyNo, CurNode );
-
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
-/* traverse down the left side of the tree */
- while( GetLeftNodeNo( 0, CurNode )){
- TempNodeNo = GetLeftNodeNo( 0, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
- CurNode->CurKeyNo = 0;
- }
- CurDbfRec = GetDbfNo( 0, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param NodeNo
- \param RetrieveSw
-*/
-xbShort xbNtx::GetLastKey( xbLong NodeNo, xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the last index pointer */
-
-/* If NodeNo = 0, start at head node, otherwise start at NodeNo */
-
- xbLong TempNodeNo;
- xbShort rc;
-
-// TODO
-// NTX files keep no TotalNode count.
-// if( NodeNo < 0 || NodeNo > HeadNode.TotalNodes )
-// return XB_INVALID_NODE_NO;
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// if((rc = LockIndex( XB_LOCK )) != 0)
-// return rc;
-#endif
-
- /* initialize the node chain */
- if( NodeChain ){
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL;
- }
- if( NodeNo == 0L )
- if(( rc = GetHeadNode()) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
-
- /* get a node and add it to the link */
- if( NodeNo == 0L ){
- if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK);
-#endif
- CurDbfRec = 0L;
- return rc;
- }
- } else {
- if(( rc = GetLeafNode( NodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
- }
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
-
-/* traverse down the right side of the tree */
- while( GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode )){
- TempNodeNo = GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- }
- CurNode->CurKeyNo--; /* leaf node has one fewer ix recs */
- CurDbfRec = GetDbfNo( CurNode->Leaf.NoOfKeysThisNode-1, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param RetrieveSw
-*/
-xbShort xbNtx::GetPrevKey( xbShort RetrieveSw )
-{
-/* This routine returns 0 on success and sets CurDbfRec to the record */
-/* corresponding to the previous index pointer */
-
- xbNodeLink * TempNodeLink;
- xbLong TempNodeNo;
- xbShort rc;
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// if((rc = LockIndex( XB_LOCK )) != 0)
-// return rc;
-#endif
-
- if( !IsOpen() ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return XB_NOT_OPEN;
- }
-
- if( !CurNode ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return GetFirstKey( RetrieveSw );
- }
-
- /* more keys on this node ? */
- if( CurNode->CurKeyNo > 0 ){
- CurNode->CurKeyNo--;
- CurDbfRec = GetDbfNo( CurNode->CurKeyNo, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
- }
-
- /* this logic assumes that interior nodes have n+1 left node no's where */
- /* n is the number of keys in the node */
- /* pop up one node to the interior node level & free the leaf node */
-
- if( !CurNode->PrevNode ){ /* michael - make sure prev node exists */
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_EOF;
- }
-
- TempNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempNodeLink );
-
- /* while no more left keys && not head node, pop up one node */
- while(( CurNode->CurKeyNo == 0 ) &&
- ( CurNode->NodeNo != HeadNode.StartNode )){
- TempNodeLink = CurNode;
- CurNode = CurNode->PrevNode;
- CurNode->NextNode = NULL;
- ReleaseNodeMemory( TempNodeLink );
- }
-
- /* if head node && left most key, return end-of-file */
- if(( HeadNode.StartNode == CurNode->NodeNo ) &&
- ( CurNode->CurKeyNo == 0 )){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_EOF;
- }
-
- /* move one to the left */
- CurNode->CurKeyNo--;
- TempNodeNo = GetLeftNodeNo( CurNode->CurKeyNo, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
- if( GetLeftNodeNo( 0, CurNode )) /* if interior node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- else /* leaf node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode -1;
-
-/* traverse down the right side of the tree */
- while( GetLeftNodeNo( 0, CurNode )){ /* while interior node */
- TempNodeNo = GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode );
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
- if( GetLeftNodeNo( 0, CurNode )) /* if interior node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- else /* leaf node */
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode -1;
- }
- CurDbfRec = GetDbfNo( CurNode->Leaf.NoOfKeysThisNode -1, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw )
- return dbf->GetRecord( CurDbfRec );
- else
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param Key1
- \param Key2
- \param Klen
-*/
-xbShort xbNtx::CompareKey( const char * Key1, const char * Key2, xbShort Klen )
-{
-/* if key1 = key2 --> return 0 */
-/* if key1 > key2 --> return 1 */
-/* if key1 < key2 --> return 2 */
-
- const char *k1, *k2;
- xbShort i;
-
- if( Klen > HeadNode.KeyLen ) Klen = HeadNode.KeyLen;
- k1 = Key1;
- k2 = Key2;
- for( i = 0; i < Klen; i++ ){
- if( *k1 > *k2 ) return 1;
- if( *k1 < *k2 ) return 2;
- k1++;
- k2++;
- }
- return 0;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param Key1
- \param Key2
-*/
-xbShort xbNtx::CompareKey( const char * Key1, const char * Key2)
-{
-/* if key1 = key2 --> return 0 */
-/* if key1 > key2 --> return 1 */
-/* if key1 < key2 --> return 2 */
-
- int rc;
- rc = strcmp(Key1, Key2);
- if( rc < 0 )
- return 2;
- else if( rc > 0 )
- return 1;
- else
- return 0;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param Tkey
- \param
-*/
-xbULong xbNtx::GetLeafFromInteriorNode( const char * Tkey, xbShort )
-{
- /* This function scans an interior node for a key and returns the */
- /* correct interior leaf node no */
-
- xbShort rc, p;
-
- /* if Tkey > any keys in node, return right most key */
- p = CurNode->Leaf.NoOfKeysThisNode -1 ;
- if( CompareKey( Tkey, GetKeyData( p, CurNode )) == 1 ){
- CurNode->CurKeyNo = CurNode->Leaf.NoOfKeysThisNode;
- return GetLeftNodeNo( CurNode->Leaf.NoOfKeysThisNode, CurNode );
- }
-
- /* otherwise, start at the beginning and scan up */
- p = 0;
- while( p < CurNode->Leaf.NoOfKeysThisNode){
- rc = CompareKey( Tkey, GetKeyData( p, CurNode ) );
- if (rc == 2) break;
- else if (rc == 0){
- CurNode->CurKeyNo = p;
- CurDbfRec = GetDbfNo( p, CurNode );
- return 0;
- }
- p++;
- }
-
- CurNode->CurKeyNo = p;
- return GetLeftNodeNo( p, CurNode );
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbShort xbNtx::KeyExists( xbDouble d )
-{
- char buf[9];
- memset( buf, 0x00, 9 );
- dbf->xbase->PutDouble( buf, d );
- return FindKey( buf, 8, 0 );
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param d
-*/
-xbShort xbNtx::FindKey( xbDouble d )
-{
- char buf[9];
- memset( buf, 0x00, 9 );
- dbf->xbase->PutDouble( buf, d );
- return FindKey( buf, 8, 1 );
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param Key
-*/
-xbShort xbNtx::FindKey( const char * Key )
-{
- return FindKey( Key, strlen( Key ), 1 );
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param Tkey
- \param DbfRec
-*/
-xbShort xbNtx::FindKey( const char * Tkey, xbLong DbfRec )
-{
- /* find a key with a specifc xbDbf record number */
- xbShort rc;
- xbLong CurDbfRecNo;
- xbLong CurNtxDbfNo;
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// if((rc = LockIndex( XB_LOCK )) != 0)
-// return rc;
-#endif
-
- /* if we are already on the correct key, return XB_FOUND */
- if( CurNode ){
- CurDbfRecNo = dbf->GetCurRecNo();
- CurNtxDbfNo = GetDbfNo( CurNode->CurKeyNo, CurNode );
- if( CurDbfRecNo == CurNtxDbfNo ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_FOUND;
- }
- }
-
- rc = FindKey( Tkey, HeadNode.KeyLen, 0 );
-
- while( rc == 0 || rc == XB_FOUND ){
- if( strncmp( Tkey, GetKeyData( CurNode->CurKeyNo, CurNode ),
- HeadNode.KeyLen ) == 0 ){
- if( DbfRec == GetDbfNo( CurNode->CurKeyNo, CurNode )){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
- // LockIndex( XB_UNLOCK );
-#endif
- return XB_FOUND;
- } else
- rc = GetNextKey( 0 );
- } else {
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_NOT_FOUND;
- }
- }
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_NOT_FOUND;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbNtx::FindKey( void )
-{
- /* if no paramaters given, use KeyBuf */
- return( FindKey( KeyBuf, HeadNode.KeyLen, 0 ));
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param Tkey
- \param Klen
- \param RetrieveSw
-*/
-xbShort xbNtx::FindKey( const char * Tkey, xbShort Klen, xbShort RetrieveSw )
-{
- /* This routine sets the current key to the found key */
- /* if RetrieveSw is true, the method positions the dbf record */
-
- xbShort rc,i;
- xbLong TempNodeNo;
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// if((rc = LockIndex( XB_LOCK )) != 0)
-// return rc;
-#endif
- if( NodeChain ){
- ReleaseNodeMemory( NodeChain );
- NodeChain = NULL;
- }
-
- if(( rc = GetHeadNode()) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
-
- // If the index is empty
- if( HeadNode.StartNode == 0){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_NOT_FOUND;
- }
-
- /* load first node */
- if(( rc = GetLeafNode( HeadNode.StartNode, 1 )) != 0 ){
- CurDbfRec = 0L;
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
- /* traverse down the tree until it hits a leaf */
- while( GetLeftNodeNo( 0, CurNode )){ /* while interior node */
- TempNodeNo = GetLeafFromInteriorNode( Tkey, Klen );
-
-#if 1
- // GetLeafFromInteriorNode will return 0 if the key is found on
- // an inode. But the leftNodeNo will not be 0.
- if (TempNodeNo == 0 && GetLeftNodeNo( 0, CurNode ) != 0){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw ) dbf->GetRecord( CurDbfRec );
- return XB_FOUND;
- }
-#endif
-
- if(( rc = GetLeafNode( TempNodeNo, 1 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- CurDbfRec = 0L;
- return rc;
- }
- }
-
- /* leaf level */
- for( i = 0; i < CurNode->Leaf.NoOfKeysThisNode; i++ ){
- rc = CompareKey( Tkey, GetKeyData( i, CurNode ) );
- if( rc == 0 ){
- CurNode->CurKeyNo = i;
- CurDbfRec = GetDbfNo( i, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw ) dbf->GetRecord( CurDbfRec );
- return XB_FOUND;
- } else if( rc == 2 ) {
- CurNode->CurKeyNo = i;
- CurDbfRec = GetDbfNo( i, CurNode );
- if( RetrieveSw ) dbf->GetRecord( CurDbfRec );
- // If key is lessthan, without length involved,
- // Check to see if the substring match
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if(CompareKey( Tkey, GetKeyData( i, CurNode ), Klen ) == 0)
- return XB_FOUND;
- else
- return XB_NOT_FOUND;
- }
- }
- CurNode->CurKeyNo = i;
- CurDbfRec = GetDbfNo( i, CurNode );
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- if( RetrieveSw ) dbf->GetRecord( CurDbfRec );
- return XB_NOT_FOUND;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbNtx::CalcKeyLen( void )
-{
- xbShort rc;
- xbExpNode * TempNode;
- char FieldName[11];
- char Type;
- TempNode = IxExp->GetFirstTreeNode();
-
- if( !TempNode ) return 0;
- if( TempNode->Type == 'd' ) return TempNode->ResultLen;
- if( TempNode->Type == 'D' ) {
- memset( FieldName, 0x00, 11 );
- memcpy( FieldName, TempNode->NodeText, TempNode->Len );
- Type = dbf->GetFieldType( dbf->GetFieldNo( FieldName ));
- if( Type == 'N' || Type == 'F' )
- return TempNode->ResultLen;
- }
-
- if(( rc = IxExp->ProcessExpression()) != XB_NO_ERROR )
- return 0;
-
- TempNode = (xbExpNode *) IxExp->Pop();
- if( !TempNode ) return 0;
- rc = TempNode->DataLen;
-
-// if( !TempNode->InTree ) dbf->xbase->FreeExpNode( TempNode );
- if( !TempNode->InTree ) delete TempNode;
- return rc;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param IxName
- \param Exp
- \param Unique
- \param Overlay
-*/
-xbShort xbNtx::CreateIndex(const char * IxName, const char * Exp, xbShort Unique, xbShort Overlay )
-{
- xbShort i, KeyLen, rc;
-
- if( IsOpen()) CloseIndex();
- if( strlen( Exp ) > 255 ) return XB_INVALID_KEY_EXPRESSION;
- if( dbf->GetDbfStatus() == 0 ) return XB_NOT_OPEN;
-
- /* Get the index file name and store it in the class */
- SetFileName(IxName);
-
- /* check if the file already exists */
- if(((indexfp = fopen( GetFileName(), "r" )) != NULL ) && !Overlay ){
- fclose( indexfp );
- return XB_FILE_EXISTS;
- }
- else if( indexfp ) fclose( indexfp );
-
- if(( indexfp = fopen( GetFileName(), "w+b" )) == NULL ){
- return XB_OPEN_ERROR;
- }
-
-#ifdef XB_LOCKING_ON
- /*
- ** Must turn off buffering when multiple programs may be accessing
- ** index files.
- */
- setbuf( indexfp, NULL );
-#endif
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// if((rc = LockIndex( XB_LOCK )) != 0)
-// return rc;
-#endif
-
- /* parse the expression */
- IxExp = new xbExpn( dbf->xbase );
- if(( rc = IxExp->BuildExpressionTree( Exp, strlen( Exp ), dbf )) != XB_NO_ERROR )
- return rc;
-
-// ExpressionTree = dbf->xbase->GetTree();
-// dbf->xbase->SetTreeToNull();
-
- /* build the header record */
- memset( &HeadNode, 0x00, sizeof( NtxHeadNode ));
- HeadNode.Signature = 0x6; // Clipper 5.x
- HeadNode.Version = 1;
- HeadNode.StartNode = 1024L;
- KeyLen = CalcKeyLen();
-
- // TODO
- // What is the Clipper key length limit?
- if( KeyLen == 0 || KeyLen > 100 ){ /* 100 byte key length limit */
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return XB_INVALID_KEY;
- } else {
- HeadNode.KeyLen = KeyLen;
- }
-
- // This is not the algorithm that Clipper uses. I cant figure out
- // what they use from looking at the examples.
- // This is correct tho.
- HeadNode.KeysPerNode = (xbUShort)
- (( XB_NTX_NODE_SIZE - (2 * sizeof( xbUShort ))) / (HeadNode.KeyLen + 10 )) - 1;
- if( HeadNode.KeysPerNode % 2 )
- HeadNode.KeysPerNode--;
-
- HeadNode.HalfKeysPerNode = (xbUShort) HeadNode.KeysPerNode / 2;
- HeadNode.KeySize = HeadNode.KeyLen + 8;
-// while(( HeadNode.KeySize % 4 ) != 0 ) HeadNode.KeySize++; /* multiple of 4*/
- HeadNode.Unique = Unique;
- strncpy( HeadNode.KeyExpression, Exp, 255 );
-
- rc=AllocKeyBufs();
- if(rc) {
- fclose(indexfp);
- return rc;
- };
-
- if(( rc = PutHeadNode( &HeadNode, indexfp, 0 )) != 0 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
- /* write node #1 all 0x00 */
- for( i = 0; i < XB_NTX_NODE_SIZE; i++ ){
- if(( fwrite( "\x00", 1, 1, indexfp )) != 1 ){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- fclose( indexfp );
- return XB_WRITE_ERROR;
- }
- }
-
- if((rc = GetLeafNode(HeadNode.StartNode, 1)) != 0){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
- for( i = 0; i < HeadNode.KeysPerNode + 1; i++ )
- CurNode->offsets[i] = (i * HeadNode.KeySize) +
- 2 + (2 * (HeadNode.KeysPerNode + 1));
-
- if((rc = PutLeafNode(HeadNode.StartNode, CurNode )) != 0){
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return rc;
- }
-
-#ifdef XB_LOCKING_ON
-// if( dbf->GetAutoLock() )
-// LockIndex( XB_UNLOCK );
-#endif
- return dbf->AddIndexToIxList( index, GetFileName());
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param RecNo
- \param n
- \param NodeNo
-*/
-xbShort xbNtx::PutLeftNodeNo( xbShort RecNo, xbNodeLink *n, xbLong NodeNo )
-{
- /* This routine sets n node's leftnode number */
- NtxLeafNode *temp;
- char *p;
- xbUShort itemOffset;
- if( !n ) return XB_INVALID_NODELINK;
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > HeadNode.KeysPerNode)
- return XB_INVALID_KEY;
- p = temp->KeyRecs;
- itemOffset = GetItemOffset(RecNo, n, 1);
- p += itemOffset;
- dbf->xbase->PutLong( p, NodeNo );
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param RecNo
- \param n
- \param DbfNo
-*/
-xbShort xbNtx::PutDbfNo( xbShort RecNo, xbNodeLink *n, xbLong DbfNo )
-{
- /* This routine sets n node's dbf number */
-
- NtxLeafNode *temp;
- char *p;
- xbUShort itemOffset;
- if( !n ) return XB_INVALID_NODELINK;
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode))
- return XB_INVALID_KEY;
- itemOffset = GetItemOffset(RecNo, n, 1);
- p = temp->KeyRecs;
- p += itemOffset;
- p += 4;
- dbf->xbase->PutLong( p, DbfNo );
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param l
- \param n
-*/
-xbShort xbNtx::PutLeafNode( xbLong l, xbNodeLink *n )
-{
- NtxLeafNode *temp;
- char *p;
-
- if(( _fseek( indexfp, (xbOffT)l , SEEK_SET )) != 0 ){
- fclose( indexfp );
- return XB_SEEK_ERROR;
- }
-
- temp = &n->Leaf;
- p = temp->KeyRecs;
- dbf->xbase->PutShort( p, temp->NoOfKeysThisNode );
-
- // The offsets at the head of each leaf are not necessarly in order.
- p += 2;
- for( int i = 0; i < HeadNode.KeysPerNode + 1; i++){
- dbf->xbase->PutShort( p, n->offsets[i] );
- p += 2;
- }
-
- if(( fwrite( &n->Leaf.KeyRecs, XB_NTX_NODE_SIZE, 1, indexfp )) != 1 ){
- fclose( indexfp );
- return XB_WRITE_ERROR;
- }
-
- PutHeadNode(&HeadNode, indexfp, 1);
- return 0;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param Head
- \param f
- \param UpdateOnly
-*/
-xbShort xbNtx::PutHeadNode( NtxHeadNode * Head, FILE * f, xbShort UpdateOnly )
-{
- char buf[4];
- char *p;
-
- if(( _fseek( f, 0L, SEEK_SET )) != 0 ){
- fclose( f );
- return XB_SEEK_ERROR;
- }
-
- memset( buf, 0x00, 2 );
- dbf->xbase->PutUShort( buf, Head->Signature );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 2 );
- dbf->xbase->PutUShort( buf, Head->Version );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 4 );
- dbf->xbase->PutULong( buf, Head->StartNode );
- if(( fwrite( &buf, 4, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 4 );
- dbf->xbase->PutULong( buf, Head->UnusedOffset );
- if(( fwrite( &buf, 4, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- if( UpdateOnly ){
- fflush(indexfp);
- return XB_NO_ERROR;
- }
-
- memset( buf, 0x00, 2 );
- dbf->xbase->PutUShort( buf, Head->KeySize );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 2 );
- dbf->xbase->PutUShort( buf, Head->KeyLen );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 2 );
- dbf->xbase->PutUShort( buf, Head->DecimalCount );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 2 );
- dbf->xbase->PutUShort( buf, Head->KeysPerNode );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 2 );
- dbf->xbase->PutUShort( buf, Head->HalfKeysPerNode );
- if(( fwrite( &buf, 2, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- p = HeadNode.KeyExpression;
- while(*p){
- *p = tolower(*p);
- p++;
- }
-
- if(( fwrite( &Head->KeyExpression, 256, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- memset( buf, 0x00, 1 );
- buf[0] = Head->Unique;
- if(( fwrite( &buf, 1, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
-
- if(( fwrite( &Head->NotUsed, 745, 1, f )) != 1 ){
- fclose( f );
- return XB_WRITE_ERROR;
- }
- return 0;
-}
-
-xbShort xbNtx::TouchIndex( void )
-{
- xbShort rc;
- if (( rc = GetHeadNode()) != XB_NO_ERROR) return rc;
- HeadNode.Version++;
- if (( rc = PutHeadNode(&HeadNode, indexfp, 1)) != XB_NO_ERROR) return rc;
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param RecNo
- \param n
-*/
-xbShort xbNtx::PutKeyData( xbShort RecNo, xbNodeLink *n )
-{
- /* This routine copies the KeyBuf data into xbNodeLink n */
- NtxLeafNode *temp;
- char *p;
- xbShort i;
- xbUShort itemOffset;
- if( !n ) return XB_INVALID_NODELINK;
- temp = &n->Leaf;
- if( RecNo < 0 || RecNo > (HeadNode.KeysPerNode))
- return XB_INVALID_KEY;
- itemOffset = GetItemOffset(RecNo, n, 1);
- p = temp->KeyRecs;
- p += itemOffset;
- p += 8;
- for( i = 0; i < HeadNode.KeyLen; i++ ){
- *p = KeyBuf[i];
- p++;
- }
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param n
- \param pos
- \param d
- \param l
- \param w
-*/
-xbShort xbNtx::PutKeyInNode( xbNodeLink * n, xbShort pos, xbLong d, xbLong l, xbShort w )
-{
- /* check the node */
- if( !n ) return XB_INVALID_NODELINK;
- if( pos < 0 || pos > HeadNode.KeysPerNode ) return XB_INVALID_RECORD;
- if( n->Leaf.NoOfKeysThisNode >= HeadNode.KeysPerNode ) return XB_NODE_FULL;
-
- InsertKeyOffset(pos, n);
- PutKeyData( pos, n );
- PutDbfNo( pos, n, d );
- PutLeftNodeNo( pos, n, l );
- n->Leaf.NoOfKeysThisNode++;
- if( w )
- return PutLeafNode( n->NodeNo, n );
- else
- return 0;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param n1
- \param n2
- \param pos
- \param d
-*/
-xbShort xbNtx::SplitLeafNode( xbNodeLink *n1, xbNodeLink *n2, xbShort pos, xbLong d )
-{
- xbShort i,j,rc;
- xbShort temp;
- xbShort start;
- xbShort end;
-// xbShort length;
-
- if( !n1 || !n2 ) return XB_INVALID_NODELINK;
- if( pos < 0 || pos > HeadNode.KeysPerNode ) return XB_INVALID_RECORD;
-
-// length = strlen(KeyBuf);
-
- // If the new key goes in the first node.
- if( pos < HeadNode.HalfKeysPerNode ){
- // Setup key to insert into parent
- memcpy(PushItem.Key,
- GetKeyData(HeadNode.HalfKeysPerNode -1, n1), HeadNode.KeyLen);
- PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode -1, n1);
- PushItem.Node = 0L;
- start = pos;
- end = HeadNode.HalfKeysPerNode - 1;
- temp = n1->offsets[end];
- for( i = end; i > start; i--)
- n1->offsets[i] = n1->offsets[i-1];
-
- n1->offsets[start] = temp;
- // Insert new key
- PutKeyData( start , n1 );
- PutDbfNo ( start , n1, d );
- } else {
- // If the passed-in key IS median key, just copy it.
- if( pos == HeadNode.HalfKeysPerNode ){
- memcpy(PushItem.Key, KeyBuf, HeadNode.KeyLen);
- PushItem.RecordNumber = d;
- start = pos;
- end = pos;
- } else {
- // Otherwise, the median key will be middle key because the
- // new key will be inserted somewhere above the middle.
- memcpy( PushItem.Key,
- GetKeyData(HeadNode.HalfKeysPerNode, n1),
- HeadNode.KeyLen);
- PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode, n1);
- start = HeadNode.HalfKeysPerNode ;
- end = pos -1;
- }
- temp = n1->offsets[start];
- for( i = start; i < end; i++)
- n1->offsets[i] = n1->offsets[i+1];
-
- n1->offsets[end] = temp;
-
- // Insert new key
- PutKeyData( pos -1 , n1 );
- PutDbfNo ( pos -1 , n1, d );
- }
-
- // Dup the node data
- memcpy(n2->Leaf.KeyRecs, n1->Leaf.KeyRecs, XB_NTX_NODE_SIZE);
-
- // Dup the offsets
- for( i = 0; i < HeadNode.KeysPerNode +1; i++)
- n2->offsets[i] = n1->offsets[i];
-
- // Setup the second node
- for(j=0, i=HeadNode.HalfKeysPerNode; i < HeadNode.KeysPerNode; i++, j++ ){
- temp = n2->offsets[j];
- n2->offsets[j] = n2->offsets[i];
- n2->offsets[i] = temp;
- }
-
- // Get the last offset for both nodes
- temp = n2->offsets[j];
- n2->offsets[j] = n2->offsets[HeadNode.KeysPerNode];
- n2->offsets[HeadNode.KeysPerNode] = temp;
-
- // Set the new count of both nodes
- n2->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;
- n1->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;
-
- if(( rc = PutLeafNode( n1->NodeNo, n1 )) != 0 )
- return rc;
- if(( rc = PutLeafNode( n2->NodeNo, n2 )) != 0 )
- return rc;
- return 0;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param n1
- \param n2
- \param
-*/
-xbShort xbNtx::SplitINode( xbNodeLink *n1, xbNodeLink *n2, xbLong )
- /* parent, tempnode, tempnodeno */
-{
- xbShort i,j,rc;
- xbShort temp;
- xbShort pos = n1->CurKeyNo;
- xbShort start;
- xbShort end;
- xbLong n1LastNodeNo = 0;
-
- NtxItem oldPushItem;
- oldPushItem.Node = PushItem.Node;
- oldPushItem.RecordNumber = PushItem.RecordNumber;
- memcpy(oldPushItem.Key, PushItem.Key, sizeof(PushItem.Key));
-
- // n2->NodeNo = HeadNode.TotalNodes++;
- n2->NodeNo = GetNextNodeNo();
-
- // If the new key goes in the first node.
- if( pos < HeadNode.HalfKeysPerNode ){
- // Setup key to insert into parent
- memcpy(PushItem.Key,
- GetKeyData(HeadNode.HalfKeysPerNode -1, n1), HeadNode.KeyLen);
- PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode -1, n1);
- PushItem.Node = n2->NodeNo;
- n1LastNodeNo = GetLeftNodeNo(HeadNode.HalfKeysPerNode -1, n1);
- start = pos;
- end = HeadNode.HalfKeysPerNode - 1;
-
- // Insert the new key.
- temp = n1->offsets[end];
- for( i = end; i > start; i--)
- n1->offsets[i] = n1->offsets[i-1];
- n1->offsets[start] = temp;
- } else {
- // If the passed-in key IS median key, just copy it.
- if( pos == HeadNode.HalfKeysPerNode ){
- PutLeftNodeNo(0, n2, oldPushItem.Node);
- // PushItem should remain the same, except for its left pointer
- PushItem.Node = n2->NodeNo;
-// start = pos; unused code
-// end = pos; unused code
- } else {
- // Otherwise, the median key will be middle key becasue the
- // new key will be inserted somewhere above the middle.
- memcpy( PushItem.Key,
- GetKeyData(HeadNode.HalfKeysPerNode, n1),
- HeadNode.KeyLen);
- PushItem.RecordNumber = GetDbfNo(HeadNode.HalfKeysPerNode, n1);
- PushItem.Node = n2->NodeNo;
- n1LastNodeNo = GetLeftNodeNo(HeadNode.HalfKeysPerNode, n1);
-
-// start = HeadNode.HalfKeysPerNode + 1;
- start = HeadNode.HalfKeysPerNode;
- end = pos -1;
-
- // Insert the new key.
- temp = n1->offsets[start];
- for( i = start; i < end; i++)
- n1->offsets[i] = n1->offsets[i+1];
- n1->offsets[end] = temp;
- pos--;
- }
- }
-
- /* restore original key */
- memcpy( KeyBuf, oldPushItem.Key, HeadNode.KeyLen + 1);
-
- // Insert new key
- PutKeyData( pos, n1 );
- PutDbfNo ( pos, n1, oldPushItem.RecordNumber);
- PutLeftNodeNo( pos, n1, GetLeftNodeNo (pos + 1, n1));
- PutLeftNodeNo( pos + 1 /* +1 ?*/, n1, oldPushItem.Node /* t */ );
-
- // Dup the node data into the new page
- memcpy(n2->Leaf.KeyRecs, n1->Leaf.KeyRecs, XB_NTX_NODE_SIZE);
-
- // Dup the offsets
- for( i = 0; i < HeadNode.KeysPerNode +1; i++){
- n2->offsets[i] = n1->offsets[i];
- }
-
- // Setup the second node
- for( j = 0, i = HeadNode.HalfKeysPerNode; i<HeadNode.KeysPerNode; i++,j++ ){
- temp = n2->offsets[j];
- n2->offsets[j] = n2->offsets[i];
- n2->offsets[i] = temp;
- }
-
- // Get the last offset for both nodes
- temp = n2->offsets[j];
- n2->offsets[j] = n2->offsets[HeadNode.KeysPerNode];
- n2->offsets[HeadNode.KeysPerNode] = temp;
- PutLeftNodeNo(HeadNode.HalfKeysPerNode, n1, n1LastNodeNo);
-
- // Set the new count of both nodes
- n2->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;
- n1->Leaf.NoOfKeysThisNode = HeadNode.HalfKeysPerNode;
-
- if((rc = PutLeafNode( n1->NodeNo,n1 )) != 0) return rc;
- if((rc = PutLeafNode( n2->NodeNo,n2 )) != 0) return rc;
- return 0;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param RecBufSw
- \param KeyBufSw
-*/
-xbShort xbNtx::CreateKey( xbShort RecBufSw, xbShort KeyBufSw )
-{
- /* RecBufSw 0 Use RecBuf */
- /* 1 Use RecBuf2 */
- /* KeyBufSw 0 Use KeyBuf */
- /* 1 Use KeyBuf2 */
-
- xbShort rc;
- xbExpNode * TempNode;
-
- if(( rc = IxExp->ProcessExpression( RecBufSw )) != XB_NO_ERROR )
- return rc;
- TempNode = (xbExpNode *) IxExp->Pop();
- if( !TempNode ) return XB_INVALID_KEY;
-
- if( KeyBufSw ){
- memset( KeyBuf2, 0x00, HeadNode.KeyLen + 1 );
- memcpy( KeyBuf2, TempNode->StringResult, XB_MIN(HeadNode.KeyLen + 1, TempNode->DataLen) );
- } else {
- memset( KeyBuf, 0x00, HeadNode.KeyLen + 1 );
- memcpy( KeyBuf, TempNode->StringResult, XB_MIN(HeadNode.KeyLen + 1, TempNode->DataLen) );
- }
-// if( !TempNode->InTree ) dbf->xbase->FreeExpNode( TempNode );
- if( !TempNode->InTree ) delete TempNode;
- return 0;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param key
-*/
-xbShort
-xbNtx::GetCurrentKey(char *key)
-{
- CreateKey(0, 0);
- memcpy(key, KeyBuf, HeadNode.KeyLen + 1);
- return 0;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param DbfRec
-*/
-xbShort xbNtx::AddKey( xbLong DbfRec )
-{
- /* This routine assumes KeyBuf contains the contents of the index to key */
-
- xbShort i,rc;
- xbNodeLink * TempNode;
- xbNodeLink * Tparent;
- xbLong TempNodeNo; /* new, unattached leaf node no */
-
- /* find node key belongs in */
- rc = FindKey( KeyBuf, HeadNode.KeyLen, 0 );
- if( rc == XB_FOUND && HeadNode.Unique )
- return XB_KEY_NOT_UNIQUE;
-
- /************************************************/
- /* section A - if room in node, add key to node */
- /************************************************/
-
- if( CurNode->Leaf.NoOfKeysThisNode < HeadNode.KeysPerNode ){
- if(( rc = PutKeyInNode( CurNode,CurNode->CurKeyNo,DbfRec,0L,1)) != 0)
- return rc;
- if(( rc = PutHeadNode( &HeadNode, indexfp, 1 )) != 0)
- return rc;
- return XB_NO_ERROR;
- }
-
- /***********************************************************************/
- /* section B - split leaf node if full and put key in correct position */
- /***********************************************************************/
-
- TempNode = GetNodeMemory();
- // Create a new page
- TempNode->NodeNo = GetNextNodeNo();
-
- rc = SplitLeafNode( CurNode, TempNode, CurNode->CurKeyNo, DbfRec );
- if( rc ) return rc;
-
- /* TempNode is on disk, now we have to point someone above to
- that node. Keep the NodeNo of the on disk new node.
- */
- TempNodeNo = TempNode->NodeNo;
- ReleaseNodeMemory( TempNode );
-
- /*
- PushItem also contains the key to put into the parent
- PushItem should point at TempNode
- */
- PushItem.Node = TempNodeNo;
-
- /*****************************************************/
- /* section C go up tree splitting nodes as necessary */
- /*****************************************************/
-
- Tparent = CurNode->PrevNode;
-
- while( Tparent && Tparent->Leaf.NoOfKeysThisNode >= HeadNode.KeysPerNode ){
- TempNode = GetNodeMemory();
- if( !TempNode )
- return XB_NO_MEMORY;
-
- rc = SplitINode( Tparent, TempNode, TempNodeNo );
- if( rc ) return rc;
- TempNodeNo = TempNode->NodeNo;
- ReleaseNodeMemory( TempNode );
- ReleaseNodeMemory( CurNode );
- CurNode = Tparent;
- CurNode->NextNode = NULL;
- Tparent = CurNode->PrevNode;
- }
-
- /************************************************************/
- /* Section D if CurNode is split root, create new root */
- /************************************************************/
-
- /* at this point
- CurNode = The node that was just split
- TempNodeNo = The new node split off from CurNode */
-
- if(CurNode->NodeNo == HeadNode.StartNode ){
- TempNode = GetNodeMemory();
- if( !TempNode )
- return XB_NO_MEMORY;
-
- memcpy( KeyBuf, PushItem.Key, HeadNode.KeyLen );
- PutKeyData( 0, TempNode );
- PutDbfNo ( 0, TempNode, PushItem.RecordNumber );
- PutLeftNodeNo( 0, TempNode, CurNode->NodeNo );
- PutLeftNodeNo( 1, TempNode, PushItem.Node );
- TempNode->NodeNo = GetNextNodeNo();
- TempNode->Leaf.NoOfKeysThisNode++;
- HeadNode.StartNode = TempNode->NodeNo;
- rc = PutLeafNode( TempNode->NodeNo, TempNode );
- if( rc ) return rc;
- rc = PutHeadNode( &HeadNode, indexfp, 1 );
- if( rc ) return rc;
- ReleaseNodeMemory( TempNode );
- return XB_NO_ERROR;
- }
- /**********************************/
- /* Section E make room in parent */
- /**********************************/
- InsertKeyOffset(Tparent->CurKeyNo, Tparent);
-
- /* put key in parent */
-
- i = Tparent->CurKeyNo;
- memcpy( KeyBuf, PushItem.Key, HeadNode.KeyLen);
- PutKeyData( i, Tparent );
-
- PutDbfNo( i, Tparent, PushItem.RecordNumber);
- PutLeftNodeNo( i , Tparent, CurNode->NodeNo );
- PutLeftNodeNo( i + 1 , Tparent, TempNodeNo );
- Tparent->Leaf.NoOfKeysThisNode++;
-
- rc = PutLeafNode( Tparent->NodeNo, Tparent );
- if( rc ) return rc;
- rc = PutHeadNode( &HeadNode, indexfp, 1 );
- if( rc ) return rc;
-
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param n
-*/
-xbShort xbNtx::UpdateParentKey( xbNodeLink * n )
-{
-/* this routine goes backwards thru the node chain looking for a parent
- node to update */
-
- xbNodeLink * TempNode;
-
- if( !n ) return XB_INVALID_NODELINK;
- if( !GetDbfNo( 0, n )){
- std::cout << "Fatal index error - Not a leaf node" << n->NodeNo << std::endl;
-// exit(0);
- return XB_NOT_LEAFNODE;
- }
- TempNode = n->PrevNode;
-
- while( TempNode ){
- if( TempNode->CurKeyNo < TempNode->Leaf.NoOfKeysThisNode ){
- memcpy(KeyBuf,GetKeyData(n->Leaf.NoOfKeysThisNode-1,n),HeadNode.KeyLen);
- PutKeyData( TempNode->CurKeyNo, TempNode );
- return PutLeafNode( TempNode->NodeNo, TempNode );
- }
- TempNode = TempNode->PrevNode;
- }
- return XB_NO_ERROR;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param n
-*/
-/* This routine queues up a list of nodes which have been emptied */
-void xbNtx::UpdateDeleteList( xbNodeLink *n )
-{
- n->NextNode = DeleteChain;
- DeleteChain = n;
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-/* Delete nodes from the node list - for now we leave the empty nodes */
-/* dangling in the file. Eventually we will remove nodes from the file */
-
-void xbNtx::ProcessDeleteList( void )
-{
- if( DeleteChain ){
- ReleaseNodeMemory( DeleteChain );
- DeleteChain = NULL;
- }
-}
-/***********************************************************************/
-//! Short description.
-/*!
-*/
-xbShort xbNtx::KeyWasChanged( void )
-{
- CreateKey( 0, 0 ); /* use KeyBuf, RecBuf */
- CreateKey( 1, 1 ); /* use KeyBuf2, RecBuf2 */
- if( CompareKey( KeyBuf, KeyBuf2, HeadNode.KeyLen ) != 0 )
- return 1;
- else
- return 0;
-}
-/***********************************************************************/
-//! Short description.
-/*!
- \param DbfRec
-*/
-xbShort xbNtx::DeleteKey( xbLong DbfRec )
-{
-/* this routine assumes the key to be deleted is in KeyBuf */
-
- xbShort rc;
-
- // FindKey will set CurNodeNo on evey page down to the
- // key being deleted. This is important. Plus we
- // need to be able to find the key to delete it.
- CurNode = NULL;
- if(( rc = FindKey( KeyBuf, DbfRec )) != XB_FOUND )
- return rc;
-
- // Then delete it
- // next sentence modified 8/20/03 - gkunkel
- if(( rc = DeleteKeyFromNode( CurNode->CurKeyNo, CurNode )) != XB_NO_ERROR )
- return rc;
-
- CurDbfRec = GetDbfNo( CurNode->CurKeyNo, CurNode );
- if(( rc = PutHeadNode( &HeadNode, indexfp, 1 )) != 0 )
- return rc;
- return XB_NO_ERROR;
-}
-
-//! Short description.
-/*!
- \param pos
- \param n
-*/
-xbShort
-xbNtx::DeleteKeyFromNode(xbShort pos, xbNodeLink *n )
-{
- xbNodeLink *TempNode;
- xbShort rc;
-
- // Check to see if this is an inode
- if( GetLeftNodeNo( 0 , n ) != 0 ){
- // Copy the rightmost key from the left node.
- TempNode = n;
- GetLeafNode ( GetLeftNodeNo (n->CurKeyNo, n), 1);
- while(( rc = GetLeftNodeNo( 0, CurNode )) != 0 )
- GetLeafNode ( GetLeftNodeNo (CurNode->Leaf.NoOfKeysThisNode, CurNode), 1);
-
- // Get the key Data
- strcpy (KeyBuf , GetKeyData( CurNode->Leaf.NoOfKeysThisNode -1, CurNode));
- PutKeyData( pos, TempNode );
-
- // Get the xbDbf no
- PutDbfNo (pos, TempNode, GetDbfNo( CurNode->Leaf.NoOfKeysThisNode -1, CurNode) );
-
- // We don't change the LeftNodeNo. determined later
- // Write the changed node
- PutLeafNode( TempNode->NodeNo, TempNode );
-
- // Now delete the key from the child
- TempNode = CurNode;
-
- if((rc = PutLeafNode( n->NodeNo,n )) != 0) return rc;
-
- return DeleteKeyFromNode( TempNode->Leaf.NoOfKeysThisNode -1, TempNode);
- } else {
- return RemoveKeyFromNode(pos, n);
- }
-}
-
-//! Short description.
-/*!
- \param pos
- \param n
-*/
-xbShort xbNtx::RemoveKeyFromNode( xbShort pos, xbNodeLink *n )
-{
- xbNodeLink *TempNode;
- xbNodeLink *sibling;
- xbNodeLink *parent;
- xbShort rc;
- xbLong newHeadNode = 0;
- xbBool harvest = false;
-
- // Here we are a leaf node..
-
- if( n->NodeNo == HeadNode.StartNode && n->Leaf.NoOfKeysThisNode == 1)
- // we are about to delete the last node from the head node.
- newHeadNode = GetLeftNodeNo( 0 , n );
-
- // Remove the key from the current node.
- DeleteKeyOffset(pos, n);
- n->Leaf.NoOfKeysThisNode--;
-
- // Check to see if the number of keys left is less then
- // 1/2 KeysPerNode
- if( ! ( n->NodeNo == HeadNode.StartNode )
- && n->Leaf.NoOfKeysThisNode < HeadNode.HalfKeysPerNode){
- // This observed clipper behavior.
- // If less then 1/2 keys per node, then merge with right sibling.
- // If no right sibling, merge with left sibling.
- parent = n->PrevNode;
-
- // If the parents cur key is the last key, then take the left node
- if( parent->CurKeyNo == parent->Leaf.NoOfKeysThisNode ){
- TempNode = CurNode;
- GetLeafNode( GetLeftNodeNo(parent->CurKeyNo -1, parent), 2 );
- sibling = CurNode;
- CurNode = TempNode;
-
- rc = JoinSiblings(parent, parent->CurKeyNo -1, sibling, n);
-
- // Harvest the empty node, if necessary Clipper keeps the old key
- // count on the node, to we can't set it to 0
- if( rc == XB_HARVEST_NODE )
- harvest = true;
-
- if((rc = PutLeafNode( n->NodeNo,n )) != 0) return rc;
- if((rc = PutLeafNode( sibling->NodeNo,sibling )) != 0) return rc;
- if((rc = PutLeafNode( parent->NodeNo,parent )) != 0) return rc;
-
- if(harvest){
- HeadNode.UnusedOffset = n->NodeNo;
- // Save the empty xbNodeLink
- // ReleaseNodeMemory(n);
- // We may have to delete a node from the parent
- return RemoveKeyFromNode( parent->CurKeyNo, parent);
- }
- } else {
- // Take the right node
- TempNode = CurNode;
- GetLeafNode( GetLeftNodeNo(parent->CurKeyNo + 1, parent), 2 );
- sibling = CurNode;
- CurNode = TempNode;
-
- rc = JoinSiblings(parent, parent->CurKeyNo, n, sibling);
- // Harvest the empty node, if necessary Clipper keeps the old key
- // count on the node, to we can't set it to 0
- if( rc == XB_HARVEST_NODE )
- harvest = true;
-
- if((rc = PutLeafNode( n->NodeNo,n )) != 0) return rc;
- if((rc = PutLeafNode( sibling->NodeNo,sibling )) != 0) return rc;
- if((rc = PutLeafNode( parent->NodeNo,parent )) != 0) return rc;
-
- if( harvest ){
- HeadNode.UnusedOffset = sibling->NodeNo;
- // Save the empty xbNodeLink
- ReleaseNodeMemory( sibling );
-
- // Now the parents->CurKeyNo+1 left pointer is empty, and
- // we are about to delete the parent. So move the left node no
- // from the parents->CurKeyNo+1 to the parent->CurNodeNo
- PutLeftNodeNo( parent->CurKeyNo +1 , parent,
- GetLeftNodeNo( parent->CurKeyNo, parent ));
- // We may have to delete a node from the parent
- return RemoveKeyFromNode( parent->CurKeyNo, parent);
- }
- }
- } else {
- if( n->NodeNo == HeadNode.StartNode && n->Leaf.NoOfKeysThisNode == 0 ){
- // we are about to delete the last node from the head node.
- HeadNode.UnusedOffset = HeadNode.StartNode;
- HeadNode.StartNode = newHeadNode;
- }
-
- if((rc = PutLeafNode( n->NodeNo,n )) != 0) return rc;
- // If more then 1/2 keys per node -> done.
- return XB_NO_ERROR;
- }
- return XB_NO_ERROR;
-}
-
-//! Short description.
-/*!
- \param parent
- \param parentPos
- \param n1
- \param n2
-*/
-xbShort
-xbNtx::JoinSiblings(xbNodeLink *parent, xbShort parentPos, xbNodeLink *n1, xbNodeLink* n2)
-{
- // ASSUMES: keys in n1 are less then keys in n2
- //
- // Here, the contents of n1 need to be merged with n2. If n1 + parent_key
- // + n2 can all fit in n1, then leave n2 empty, and remove the key from the
- // parent.
- // Otherwise evenly distribute the keys from n1 and n2 over both, resetting
- // the parent.
-
- xbShort i, j;
- int totalKeys;
- int median;
-
- // if n1 has exactly (it will never have less) 1/2 keys per node
- // then put everything into n1.
- if((n1->Leaf.NoOfKeysThisNode + n2->Leaf.NoOfKeysThisNode + 1) <= HeadNode.KeysPerNode){
- int n1LastNodeNo = GetLeftNodeNo(n2->Leaf.NoOfKeysThisNode, n2);
- // Bring down the parent
- strcpy(KeyBuf, GetKeyData( parentPos, parent ));
- PutKeyData( n1->Leaf.NoOfKeysThisNode , n1);
- PutDbfNo ( n1->Leaf.NoOfKeysThisNode, n1, GetDbfNo( parentPos, parent ) );
- n1->Leaf.NoOfKeysThisNode++;
-
- // Copy over the rest of the keys
- for(i = n1->Leaf.NoOfKeysThisNode, j = 0; j < n2->Leaf.NoOfKeysThisNode; i++, j++){
- strcpy(KeyBuf, GetKeyData( j, n2 ));
- PutKeyData( i, n1);
- PutLeftNodeNo( i, n1, GetLeftNodeNo( j, n2) );
- PutDbfNo ( i , n1, GetDbfNo( j, n2 ) );
- }
- n1->Leaf.NoOfKeysThisNode += j;
- PutLeftNodeNo(n1->Leaf.NoOfKeysThisNode, n1, n1LastNodeNo);
-
- // We need a way to signal that this node will be harvested.
- // Clipper keeps the KeyCount on harvested nodes, it does NOT
- // set them to 0.
- return XB_HARVEST_NODE;
- } else {
- // Distribute the keys evenly. Of off by one, the extra
- // goes to n1.
-
- // If n1 contains the greater than keys, then at this point we
- // know that n1 has more than 1/2MKPN. therefore we copy
- // over untill we get to median. All the while removing
- // keys from n2. Then
-
- totalKeys = n1->Leaf.NoOfKeysThisNode + n2->Leaf.NoOfKeysThisNode + 1;
- median = (int) totalKeys/2;
-
- // If n1 has more keys then n2, then we need to copy the last keys
- // of n1 to the beginning of n2.
- // Leave HalfKeysPerNode+1 keys in n1, then the last key will
- // be copied up to the parent.
- if( n1->Leaf.NoOfKeysThisNode > HeadNode.HalfKeysPerNode ){
- // Bring down the parent
- InsertKeyOffset(0, n2);
- strcpy(KeyBuf, GetKeyData( parentPos, parent ));
- PutKeyData( 0 , n2);
- PutDbfNo ( 0, n2, GetDbfNo( parentPos, parent ) );
- n2->Leaf.NoOfKeysThisNode++;
- PutLeftNodeNo(0, n2, GetLeftNodeNo(n1->Leaf.NoOfKeysThisNode, n1));
- for( i = n1->Leaf.NoOfKeysThisNode -1; i > median; i-- ){
- // Put the key in n2
- InsertKeyOffset(0, n2);
- strcpy(KeyBuf, GetKeyData( i, n1 ));
- PutKeyData( 0, n2);
- PutLeftNodeNo( 0, n2, GetLeftNodeNo( i, n1) );
- PutDbfNo ( 0 , n2, GetDbfNo( i, n1 ) );
-
- // Remove the key from the current node.
- n1->Leaf.NoOfKeysThisNode--;
- n2->Leaf.NoOfKeysThisNode++;
- }
- // Copy up the last key from n1, that will become the new parent key.
- strcpy(KeyBuf, GetKeyData( n1->Leaf.NoOfKeysThisNode -1 , n1 ));
- PutKeyData( parentPos, parent);
- PutDbfNo ( parentPos , parent, GetDbfNo( n1->Leaf.NoOfKeysThisNode -1, n1) );
- n1->Leaf.NoOfKeysThisNode--;
- } else {
- xbLong n1LastLeftNodeNo;
- xbShort medianOffset = n2->Leaf.NoOfKeysThisNode - median -1;
- // Bring down the parent
- strcpy(KeyBuf, GetKeyData( parentPos, parent ));
- PutKeyData( n1->Leaf.NoOfKeysThisNode , n1);
- PutDbfNo ( n1->Leaf.NoOfKeysThisNode, n1, GetDbfNo( parentPos, parent ) );
- n1->Leaf.NoOfKeysThisNode++;
-
-// 8/20/03 gkunkel n1LastLeftNodeNo = GetLeftNodeNo(medianOffset, n2);
- PutLeftNodeNo( n1->Leaf.NoOfKeysThisNode, n1, GetLeftNodeNo(medianOffset, n2));
-
- // Moving the median to the parent may have to occur
- // before moving the other keys to n1. This we would have
- // to calcualte the correct offset from the median
- // Copy up the first key from n2 (the median),
- // that will become the new parent key.
- strcpy(KeyBuf, GetKeyData( medianOffset, n2 ));
- PutKeyData( parentPos, parent);
- PutDbfNo ( parentPos , parent, GetDbfNo(medianOffset, n2 ) );
- n1LastLeftNodeNo = GetLeftNodeNo(medianOffset, n2);
-
-// Still investigating the -1 thing with clipper, If anyone has clues,
-// please let me know - bob@synxis.com
-// if ( n1->Leaf.NoOfKeysThisNode >= (median - 1))
-// {
-// // Clipper, don't know why
-// PutLeftNodeNo(0, n2 , -1 );
-// std::cout << "Clipper hack" << std::endl;
-// }
-
- DeleteKeyOffset(medianOffset, n2);
- n2->Leaf.NoOfKeysThisNode--;
-
-// xbShort clipperMessedUpIndex = n1->Leaf.NoOfKeysThisNode;
- for( i = n1->Leaf.NoOfKeysThisNode, j = 0; j < medianOffset; i++, j++ ){
- strcpy(KeyBuf, GetKeyData( 0, n2 ));
- PutKeyData( i, n1);
- PutLeftNodeNo( i, n1, GetLeftNodeNo( 0, n2) );
- PutDbfNo ( i , n1, GetDbfNo( 0, n2 ) );
-
-// if( i == clipperMessedUpIndex){
-// // Clipper, don't know why
-// PutLeftNodeNo(0, n2 , -1 );
-// std::cout << "Clipper hack in loop i = " << i << std::endl;
-// }
-
- // Remove the key from the current node.
- DeleteKeyOffset(0, n2);
- n2->Leaf.NoOfKeysThisNode--;
- n1->Leaf.NoOfKeysThisNode++;
- }
- PutLeftNodeNo(n1->Leaf.NoOfKeysThisNode, n1, n1LastLeftNodeNo);
-
- }
- }
- return XB_NO_ERROR;
-}
-/************************************************************************/
-//! Short description.
-/*!
- \param option
-*/
-#ifdef XBASE_DEBUG
-xbShort xbNtx::CheckIndexIntegrity( const xbShort option )
-{
- /* if option = 1, print out some stats */
-
- xbShort rc;
- xbLong ctr = 1L;
-
- if ( option ) std::cout << "Checking NTX " << GetFileName() << std::endl;
- rc = dbf->GetRecord( ctr );
- while( ctr < dbf->NoOfRecords() ){
- ctr++;
- if( option ) std::cout << "Checking Record " << ctr << std::endl;
- if( !dbf->RecordDeleted() ){
- CreateKey( 0, 0 );
- rc = FindKey( KeyBuf, dbf->GetCurRecNo());
- if( rc != XB_FOUND ){
- if( option ){
- std::cout << "Record number " << dbf->GetCurRecNo()
- << " Not Found" << std::endl;
- std::cout << "Key = " << KeyBuf << std::endl;
- }
- return rc;
- }
- }
- if(( rc = dbf->GetRecord( ctr )) != XB_NO_ERROR )
- return rc;
- }
-
- if( option )
- std::cout << "Exiting with rc = " << rc << std::endl;
- return XB_NO_ERROR;
-}
-#endif
-/***********************************************************************/
-//! Short description.
-/*!
- \param statusFunc
-*/
-xbShort xbNtx::ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems))
-{
- /* this method assumes the index has been locked in exclusive mode */
- xbLong l;
- xbShort rc, i, saveAutoLock;
- NtxHeadNode TempHead;
- FILE *t, *temp;
- xbString TempName;
-
- memcpy( &TempHead, &HeadNode, sizeof( struct NtxHeadNode ));
- TempHead.StartNode = 1024L;
- rc = dbf->xbase->DirectoryExistsInName( GetFileName() );
- if( rc ) {
- TempName.assign(GetFileName(), 0, rc);
- TempName += "TEMPFILE.NTX";
- } else
- TempName = "TEMPFILE.NTX";
-
- if(( t = fopen( TempName, "w+b" )) == NULL )
- return XB_OPEN_ERROR;
-
- if(( rc = PutHeadNode( &TempHead, t, 0 )) != 0 ){
- fclose( t );
- remove( TempName );
- return rc;
- }
-
- for( i = 0; i < XB_NTX_NODE_SIZE; i++ ){
- if(( fwrite( "\x00", 1, 1, t )) != 1 ){
- fclose( t );
- remove( TempName );
- return XB_WRITE_ERROR;
- }
- }
-
- temp = indexfp;
- indexfp = t;
-
- if(( rc = GetLeafNode(TempHead.StartNode, 1)) != 0 )
- return rc;
-
- for(i = 0; i < TempHead.KeysPerNode + 1; i++)
- CurNode->offsets[i] = (i * HeadNode.KeySize) +
- 2 + (2 * (HeadNode.KeysPerNode + 1));
-
- HeadNode.StartNode = TempHead.StartNode;
- if((rc = PutLeafNode(TempHead.StartNode, CurNode )) != 0)
- return rc;
-
- indexfp = temp;
-
- if( fclose( indexfp ) != 0 )
- return XB_CLOSE_ERROR;
-
- if( fclose( t ) != 0 )
- return XB_CLOSE_ERROR;
-
- if( remove( GetFileName() ) != 0 )
- return XB_CLOSE_ERROR;
-
- if( rename( TempName, GetFileName()) != 0 )
- return XB_WRITE_ERROR;
-
- if(( indexfp = fopen( GetFileName(), "r+b" )) == NULL )
- return XB_OPEN_ERROR;
-
- saveAutoLock = dbf->GetAutoLock();
- dbf->AutoLockOff();
-
- for( l = 1; l <= dbf->NoOfRecords(); l++ ){
- if(statusFunc)
- statusFunc(l, dbf->NoOfRecords());
-
- if(( rc = dbf->GetRecord(l)) != XB_NO_ERROR )
- return rc;
-
- if(!dbf->GetRealDelete() || !dbf->RecordDeleted()){
- /* Create the key */
- CreateKey( 0, 0 );
-
- /* add key to index */
- if(( rc = AddKey( l )) != XB_NO_ERROR )
- return rc;
- }
- }
- if(saveAutoLock)
- dbf->AutoLockOn();
-
- return XB_NO_ERROR;
-}
-
-//! Short description.
-/*!
-*/
-xbLong
-xbNtx::GetNextNodeNo()
-{
- struct stat FileStat;
- int rc;
- xbULong FileSize;
-
- if( HeadNode.UnusedOffset != 0){
- FileSize = HeadNode.UnusedOffset;
- HeadNode.UnusedOffset = 0;
- PutHeadNode(&HeadNode, indexfp, 1);
- return FileSize;
- }
-
- rc = fstat(fileno(indexfp), &FileStat);
- if( rc != 0 )
- return 0;
-
-
- FileSize = (xbULong)FileStat.st_size;
- // File offset is zero based, so the file size will be the
- // offset of the next page.
- return FileSize;
-}
-
-//! Short description.
-/*!
- \param buf
- \param len
-*/
-void xbNtx::GetExpression(char *buf, int len)
-{
- memcpy(buf, HeadNode.KeyExpression, len < 256 ? len : 256);
-}
-
-const char* xbNtx::GetExtWithDot(bool lower)
-{
- return lower? ".ntx": ".NTX";
-}
-
-xbUShort xbNtx::GetKeyLen()
-{
- return HeadNode.KeyLen;
-}
-
-const char* xbNtx::GetKeyExpression()
-{
- return HeadNode.KeyExpression;
-}
-
-void xbNtx::FreeNodesMemory()
-{
- ReleaseNodeMemory(NodeChain, true);
- NodeChain = 0;
-// ReleaseNodeMemory(CloneChain, true);
-// CloneChain = 0;
- ReleaseNodeMemory(FreeNodeChain, true);
- FreeNodeChain = 0;
- ReleaseNodeMemory(DeleteChain, true);
- DeleteChain = 0;
-}
-
-#endif /* XB_INDEX_NTX */
diff --git a/xbase64/xbntx.h b/xbase64/xbntx.h
deleted file mode 100755
index daa1aa7..0000000
--- a/xbase64/xbntx.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* xbntx.h
-
- Xbase64 project source code
-
- This file contains a header file for the xbNdx object, which is used
- for handling xbNdx type indices.
-
- Copyright (C) 1997,2003 Bob Cotton
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XB_NTX_H__
-#define __XB_NTX_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#include <xbase64/xbase64.h>
-#include <string.h>
-
-/*! \file xbntx.h
-*/
-
-#define XB_NTX_NODE_SIZE 1024
-
-//! xbNtxHeadNode struct
-/*!
-*/
-
-struct NtxHeadNode { /* ntx header on disk */
- xbUShort Signature; /* Clipper 5.x or Clipper 87 */
- xbUShort Version; /* Compiler Version */
- /* Also turns out to be a last modified counter */
- xbLong StartNode; /* Offset in file for first index */
- xbULong UnusedOffset; /* First free page offset */
- xbUShort KeySize; /* Size of items (KeyLen + 8) */
- xbUShort KeyLen; /* Size of the Key */
- xbUShort DecimalCount; /* Number of decimal positions */
- xbUShort KeysPerNode; /* Max number of keys per page */
- xbUShort HalfKeysPerNode; /* Min number of keys per page */
- char KeyExpression[256]; /* Null terminated key expression */
- unsigned Unique; /* Unique Flag */
- char NotUsed[745];
-};
-
-//! xbNtxLeafNode struct
-/*!
-*/
-
-struct NtxLeafNode { /* ndx node on disk */
- xbUShort NoOfKeysThisNode;
- char KeyRecs[XB_NTX_NODE_SIZE];
-};
-
-
-//! xbNtxItem struct
-/*!
-*/
-
-struct NtxItem
-{
- xbULong Node;
- xbULong RecordNumber;
- char Key[256];
-};
-
-//! xbNtxNodeLink struct
-/*!
-*/
-
-struct xbNodeLink { /* ndx node memory */
- xbNodeLink * PrevNode;
- xbNodeLink * NextNode;
- xbUShort CurKeyNo; /* 0 - KeysPerNode-1 */
- xbLong NodeNo;
- struct NtxLeafNode Leaf;
- xbUShort * offsets;
-};
-
-//! xbNtx class
-/*!
-*/
-
-class XBDLLEXPORT xbNtx : public xbIndex
-{
-protected:
- NtxHeadNode HeadNode;
- NtxLeafNode LeafNode;
- xbLong NodeLinkCtr;
- xbLong ReusedNodeLinks;
- char Node[XB_NTX_NODE_SIZE];
- xbNodeLink * NodeChain; /* pointer to node chain of index nodes */
- xbNodeLink * FreeNodeChain; /* pointer to chain of free index nodes */
- xbNodeLink * CurNode; /* pointer to current node */
- xbNodeLink * DeleteChain; /* pointer to chain to delete */
-// xbNodeLink * CloneChain; /* pointer to node chain copy (add dup) */
- NtxItem PushItem;
-
-/* private functions */
- xbLong GetLeftNodeNo( xbShort, xbNodeLink * );
- xbShort CompareKey( const char *, const char *, xbShort );
- xbShort CompareKey( const char *, const char * );
- xbLong GetDbfNo( xbShort, xbNodeLink * );
- char * GetKeyData( xbShort, xbNodeLink * );
- xbUShort GetItemOffset ( xbShort, xbNodeLink *, xbShort );
- xbUShort InsertKeyOffset ( xbShort, xbNodeLink * );
- xbUShort GetKeysPerNode();
- virtual xbShort GetHeadNode();
- xbShort GetLeafNode( xbLong, xbShort );
- xbNodeLink * GetNodeMemory();
- xbLong GetNextNodeNo();
- void ReleaseNodeMemory(xbNodeLink *n, xbBool doFree = false);
- xbULong GetLeafFromInteriorNode( const char *, xbShort );
- xbShort CalcKeyLen();
- xbShort PutKeyData( xbShort, xbNodeLink * );
- xbShort PutLeftNodeNo( xbShort, xbNodeLink *, xbLong );
- xbShort PutLeafNode( xbLong, xbNodeLink * );
- xbShort PutHeadNode( NtxHeadNode *, FILE *, xbShort );
- xbShort TouchIndex();
- xbShort PutDbfNo( xbShort, xbNodeLink *, xbLong );
- xbShort PutKeyInNode( xbNodeLink *, xbShort, xbLong, xbLong, xbShort );
- xbShort SplitLeafNode( xbNodeLink *, xbNodeLink *, xbShort, xbLong );
- xbShort SplitINode( xbNodeLink *, xbNodeLink *, xbLong );
- xbShort AddToIxList();
- xbShort RemoveFromIxList();
- xbShort RemoveKeyFromNode( xbShort, xbNodeLink * );
- xbShort DeleteKeyFromNode( xbShort, xbNodeLink * );
- xbShort JoinSiblings(xbNodeLink *, xbShort, xbNodeLink *, xbNodeLink *);
- xbUShort DeleteKeyOffset( xbShort, xbNodeLink *);
- xbShort FindKey( const char *, xbShort, xbShort );
- xbShort UpdateParentKey( xbNodeLink * );
- xbShort GetFirstKey( xbShort );
- xbShort GetNextKey( xbShort );
- xbShort GetLastKey( xbLong, xbShort );
- xbShort GetPrevKey( xbShort );
- void UpdateDeleteList( xbNodeLink * );
- void ProcessDeleteList();
- xbShort FindKey( const char *, xbLong ); /* for a specific dbf no */
-
-public:
- xbNtx();
- xbNtx(xbDbf *);
- virtual ~xbNtx();
-
-/* note to gak - don't uncomment next line - it causes seg faults */
-// ~NTX() { if( NtxStatus ) CloseIndex(); }
-
- void DumpHdrNode ( xbShort Option );
- void DumpNodeRec ( xbLong );
- xbShort CreateIndex( const char *, const char *, xbShort, xbShort );
- xbLong GetTotalNodes();
- xbULong GetCurDbfRec() { return CurDbfRec; }
- void DumpNodeChain();
- xbShort CreateKey( xbShort, xbShort );
- xbShort GetCurrentKey(char *key);
- xbShort AddKey( xbLong );
- xbShort UniqueIndex() { return HeadNode.Unique; }
- xbShort DeleteKey( xbLong DbfRec );
- xbShort KeyWasChanged();
- xbShort FindKey( const char * );
- xbShort FindKey();
- xbShort FindKey( xbDouble );
- xbShort GetNextKey() { return GetNextKey( 1 ); }
- xbShort GetLastKey() { return GetLastKey( 0, 1 ); }
- xbShort GetFirstKey() { return GetFirstKey( 1 ); }
- xbShort GetPrevKey() { return GetPrevKey( 1 ); }
- xbShort ReIndex(void (*statusFunc)(xbLong itemNum, xbLong numItems) = 0) ;
- xbShort KeyExists( char * Key ) { return FindKey( Key, strlen( Key ), 0 ); }
- xbShort KeyExists( xbDouble );
- virtual void GetExpression(char *buf, int len);
-#ifdef XBASE_DEBUG
- xbShort CheckIndexIntegrity( xbShort Option );
-#endif
-
- virtual const char* GetExtWithDot(bool lower);
-
- protected:
- virtual xbUShort GetKeyLen();
- virtual const char* GetKeyExpression();
- virtual void FreeNodesMemory();
-};
-#endif /* __XB_NTX_H__ */
diff --git a/xbase64/xbretcod.h b/xbase64/xbretcod.h
deleted file mode 100755
index dd0748a..0000000
--- a/xbase64/xbretcod.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* xbretcod.h
-
- Xbase64 project source code
-
- This file contains a listing of all the Xbase return codes.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-/*! \file xbretcod.h
-*/
-
-#ifndef __XB_RETCODES_H__
-#define __XB_RETCODES_H__
-
-/***********************************************/
-/* Return Codes and Error Messages */
-
-#define XB_NO_ERROR 0
-#define XB_EOF -100
-#define XB_BOF -101
-#define XB_NO_MEMORY -102
-#define XB_FILE_EXISTS -103
-#define XB_OPEN_ERROR -104
-#define XB_WRITE_ERROR -105
-#define XB_UNKNOWN_FIELD_TYPE -106
-#define XB_ALREADY_OPEN -107
-#define XB_NOT_XBASE -108
-#define XB_INVALID_RECORD -109
-#define XB_INVALID_OPTION -110
-#define XB_NOT_OPEN -111
-#define XB_SEEK_ERROR -112
-#define XB_READ_ERROR -113
-#define XB_NOT_FOUND -114
-#define XB_FOUND -115
-#define XB_INVALID_KEY -116
-#define XB_INVALID_NODELINK -117
-#define XB_KEY_NOT_UNIQUE -118
-#define XB_INVALID_KEY_EXPRESSION -119
-#define XB_DBF_FILE_NOT_OPEN -120
-#define XB_INVALID_KEY_TYPE -121
-#define XB_INVALID_NODE_NO -122
-#define XB_NODE_FULL -123
-#define XB_INVALID_FIELDNO -124
-#define XB_INVALID_DATA -125
-#define XB_NOT_LEAFNODE -126
-#define XB_LOCK_FAILED -127
-#define XB_CLOSE_ERROR -128
-#define XB_INVALID_SCHEMA -129
-#define XB_INVALID_NAME -130
-#define XB_INVALID_BLOCK_SIZE -131
-#define XB_INVALID_BLOCK_NO -132
-#define XB_NOT_MEMO_FIELD -133
-#define XB_NO_MEMO_DATA -134
-#define XB_EXP_SYNTAX_ERROR -135
-#define XB_PARSE_ERROR -136
-#define XB_NO_DATA -137
-#define XB_UNKNOWN_TOKEN_TYPE -138
-#define XB_INVALID_FIELD -140
-#define XB_INSUFFICIENT_PARMS -141
-#define XB_TOO_MANY_PARMS -142
-#define XB_INVALID_FUNCTION -143
-#define XB_INVALID_FIELD_LEN -144
-#define XB_HARVEST_NODE -145
-#define XB_INVALID_DATE -146
-#define XB_INVALID_LOCK_OPTION -147
-#endif /* __XB_RETCODES_H__ */
-
diff --git a/xbase64/xbstring.cpp b/xbase64/xbstring.cpp
deleted file mode 100755
index 419014f..0000000
--- a/xbase64/xbstring.cpp
+++ /dev/null
@@ -1,1041 +0,0 @@
-/* xbstring.cpp
-
- Xbase64 project source code
-
- This file contains the xbString object methods
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifdef __GNU LesserG__
- #pragma implementation "xbstring.h"
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <xbase64/xbase64.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#ifdef STDC_HEADERS
-#include <stdarg.h>
-#endif
-
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-
-#include <xbase64/xbstring.h>
-//#include <xbase64/xbexcept.h>
-
-//#define free(x)
-
-/*! \file xbstring.cpp
-*/
-
-const char * xbString::NullString = "";
-
-//! Short description.
-/*!
-*/
-xbString::xbString() {
- ctor(NULL);
-}
-
-//! Short description.
-/*!
- \param size
-*/
-xbString::xbString(size_t size) {
- data = (char *)calloc(1, size);
- this->size = size;
-}
-
-//! Short description.
-/*!
- \param c
-*/
-xbString::xbString(char c) {
- ctor(NULL);
- *this = c;
-}
-
-//! Short description.
-/*!
- \param s
-*/
-xbString::xbString(const char *s) {
- ctor(s);
-}
-
-//! Short description.
-/*!
- \param s
-*/
-xbString::xbString(const xbString &s) {
- ctor((const char *)s);
-}
-
-//! Short description.
-/*!
- \param s
- \param maxlen
-*/
-xbString::xbString(const char *s, size_t maxlen) {
-#if 0
- size_t len = strlen(s);
-
- if(len < maxlen)
- maxlen = len;
-#endif
-
- size = maxlen + 1;
- data = (char *)calloc(1, size);
- strncpy(data, s, maxlen);
- data[maxlen] = 0;
-}
-
-//! Short description.
-/*!
-*/
-xbString::~xbString() {
- if (data != NULL)
- free(data);
-}
-
-//! Short description.
-/*!
- \param s
-*/
-void xbString::ctor(const char *s) {
- if (s == NULL) {
- data = NULL;
- size = 0;
- return;
- }
-
- size = strlen(s) + 1;
-
- data = (char *)calloc(1, size);
- strcpy(data, s);
-}
-
-//! Short description.
-/*!
- \param s
- \param maxlen
-*/
-void xbString::ctor(const char *s, size_t maxlen) {
-
- if (s == NULL) {
- data = NULL;
- size =0;
- return;
- }
- size = maxlen + 1;
- data = (char *)calloc(1, size);
- strncpy(data, s, maxlen);
- data[maxlen] = 0;
-}
-
-//! Short description.
-/*!
-*/
-xbString &xbString::operator=(char c) {
- if (data != NULL)
- free(data);
-
- data = (char *)calloc(1, 2);
- data[0] = c;
- data[1] = 0;
-
- size = 2;
-
- return (*this);
-}
-
-//! Short description.
-/*!
-*/
-xbString &xbString::operator=(const xbString &s) {
- if (data != NULL)
- free(data);
-
- const char *sd = s;
- if (sd == NULL) {
- data = NULL;
- size = 0;
- return (*this);
- }
-
- data = (char *)calloc(1, strlen(s) + 1);
- strcpy(data, s);
-
- size = strlen(data)+1;
-
- return (*this);
-}
-
-//! Short description.
-/*!
-*/
-xbString &xbString::operator=(const char *s) {
- if(data != NULL)
- free(data);
-
- if(s == NULL) {
- data = NULL;
- size = 0;
- return (*this);
- }
- data = (char *)calloc(1, strlen(s) + 1);
- strcpy(data, s);
- size = strlen(data) + 1;
- return (*this);
-}
-
-//! Short description.
-/*!
- \param size
-*/
-void xbString::resize(size_t size) {
- data = (char *)realloc(data, size);
- if( size > 0 )
- data[size-1] = 0;
- this->size = size;
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::isNull() const {
- return( data == NULL );
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::isEmpty() const {
- if( data == NULL )
- return true;
- if( data[0] == 0 )
- return true;
- return false;
-}
-
-//! Short description.
-/*!
-*/
-size_t xbString::len() const {
- return( data ? strlen(data) : 0 );
-}
-
-//! Short description.
-/*!
-*/
-size_t xbString::length() const {
- return len();
-}
-
-//! Short description.
-/*!
-*/
-xbString xbString::copy() const {
- return( *this );
-}
-
-//! Short description.
-/*!
- \param format
-*/
-xbString &xbString::sprintf(const char *format, ...) {
- va_list ap;
- va_start(ap, format);
-
- if (size < 256)
- resize(256); // make string big enough
-
-#ifdef HAVE_VSNPRINTF
- if (vsnprintf(data, size, format, ap) == -1)
- data[size-1] = 0;
-#else
-# if HAVE_VSPRINTF
- vsprintf(data, format, ap);
-# else
-# error "You have neither vsprintf nor vsnprintf!!!"
-# endif
-#endif
-
- resize(strlen(data)+1); // truncate
- va_end(ap);
- return (*this);
-}
-
-//! Short description.
-/*!
-*/
-xbString::operator const char *() const {
- return (data != NULL) ? data : NullString;
-}
-
-//! Short description.
-/*!
-*/
-xbString &xbString::operator-=(const char *s) {
- if( s == NULL ) return (*this);
- int len = strlen(s);
- int oldlen = this->len();
-
- data = (char *)realloc(data, oldlen+len+1);
- if( oldlen == 0 ) data[0] = 0;
-
- // looking for an occurence of space in the first string
- char *lftspc = strchr(data,' ');
- if( lftspc==NULL ) { // left string has no spaces
- strcat(data,s);
- } else { // left string has one or more spaces
- int numspc = strlen(lftspc);
- strcpy(lftspc,s);
- while( numspc-- > 0 ) strcat(lftspc," ");
- }
-
- size += len;
- return (*this);
-}
-
-//! Short description.
-/*!
-*/
-xbString &xbString::operator+=(const char *s) {
- if (s == NULL)
- return (*this);
- int len = strlen(s);
- int oldlen = this->len();
-
- data = (char *)realloc(data, oldlen+len+1);
- if (oldlen == 0)
- data[0] = 0;
- strcat(data, s);
-
- size += len;
- return (*this);
-}
-
-//! Short description.
-/*!
-*/
-xbString &xbString::operator+=(char c) {
- int len = 1;
- int oldlen = this->len();
-
- data = (char *)realloc(data, oldlen+len+1);
- data[oldlen] = c;
- data[oldlen+1] = 0;
-
- size++;
-
- return (*this);
-}
-
-//! Short description.
-/*!
-*/
-const char *xbString::getData() const {
- return data ? data : NullString;
-}
-
-//! Short description.
-/*!
-*/
-const char *xbString::c_str() const {
- return data ? data : NullString;
-}
-
-//! Short description.
-/*!
-*/
-void xbString::toLowerCase() {
- int len = this->len();
- for (int i=0;i<len;i++)
- data[i] = (char)tolower(data[i]);
-}
-
-
-//! Short description.
-/*!
-*/
-void xbString::toUpperCase() {
- int len = this->len();
- for (int i=0;i<len;i++)
- data[i] = (char)toupper(data[i]);
-}
-
-
-//! Short description.
-/*!
- \param c
-*/
-int xbString::pos(char c) {
- if (data == NULL)
- return (-1);
-
- const char *p = strchr(data, c);
-
- if (p == NULL)
- return (-1);
-
- return p-data;
-}
-
-//! Short description.
-/*!
- \param s
-*/
-int xbString::pos(const char* s) {
- if (data == NULL)
- return (-1);
-
- const char *p = strstr(data, s);
-
- if (p == NULL)
- return (-1);
-
- return p-data;
-}
-
-//! Short description.
-/*!
- \param num
-*/
-void xbString::setNum(long num) {
- sprintf("%ld", num);
-}
-
-//! Short description.
-/*!
- \param fmt
- \param num
-*/
-
-void xbString::setNum( char * fmt, double num) {
- xbString f;
- f = "%";
- f += fmt;
- f += "f";
- sprintf( f.getData(), num);
-}
-
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbBool operator==(const xbString &s1, const char *s2) {
- if (s2 == NULL) {
- if (s1.getData() == NULL)
- return true;
- return false;
- }
-
- if ((s2[0] == 0) && s1.getData() == NULL)
- return true;
-
- if (s1.getData() == NULL)
- return false;
-
- return (strcmp(s1, s2) == 0);
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbBool operator!=(const xbString &s1, const char *s2) {
- if (s2 == NULL) {
- if (s1.getData() == NULL)
- return false;
- return true;
- }
-
- if ((s2[0] == 0) && s1.getData() == NULL)
- return false;
-
- if (s1.getData() == NULL)
- return true;
-
- return (strcmp(s1, s2) != 0);
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::operator==( const xbString &s2 ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s2.data == NULL || s2.data[0] == 0 ) return true; // NULL == NULL
- return false; // NULL == !NULL
- } else {
- if( s2.data == NULL || s2.data[0] == 0 ) return false; // !NULL == NULL
- return strcmp(data,s2.data) == 0; //!NULL == !NULL
- }
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::operator!=( const xbString &s2 ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s2.data == NULL || s2.data[0] == 0 ) return false; // NULL != NULL
- return true; // NULL != !NULL
- } else {
- if( s2.data == NULL || s2.data[0] == 0 ) return true; // !NULL != NULL
- return strcmp(data,s2.data) != 0; //!NULL != !NULL
- }
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::operator< ( const xbString &s2 ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s2.data == NULL || s2.data[0] == 0 ) return false; // NULL < NULL
- return true; // NULL < !NULL
- } else {
- if( s2.data == NULL || s2.data[0] == 0 ) return false; // !NULL < NULL
- return strcmp(data,s2.data) < 0; //!NULL < !NULL
- }
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::operator> ( const xbString &s2 ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s2.data == NULL || s2.data[0] == 0 ) return false; // NULL > NULL
- return false; // NULL > !NULL
- } else {
- if( s2.data == NULL || s2.data[0] == 0 ) return true; // !NULL > NULL
- return strcmp(data,s2.data) > 0; //!NULL > !NULL
- }
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::operator<=( const xbString &s2 ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s2.data == NULL || s2.data[0] == 0 ) return true; // NULL <= NULL
- return true; // NULL <= !NULL
- } else {
- if( s2.data == NULL || s2.data[0] == 0 ) return false; // !NULL <= NULL
- return strcmp(data,s2.data) <= 0; //!NULL <= !NULL
- }
-}
-
-//! Short description.
-/*!
-*/
-xbBool xbString::operator>=( const xbString &s2 ) const {
- if( data == NULL || data[0] == 0 ) {
- if( s2.data == NULL || s2.data[0] == 0 ) return true; // NULL >= NULL
- return false; // NULL >= !NULL
- } else {
- if( s2.data == NULL || s2.data[0] == 0 ) return true; // !NULL >= NULL
- return strcmp(data,s2.data) >= 0; //!NULL >= !NULL
- }
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT std::ostream& operator<< ( std::ostream& os,
- const xbString& xbs ) {
- return os << xbs.data;
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbString operator-(const xbString &s1, const xbString &s2) {
- xbString tmp(s1.getData());
- tmp -= s2;
- return tmp;
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbString operator+(const xbString &s1, const xbString &s2) {
- xbString tmp(s1.getData());
- tmp += s2;
- return tmp;
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbString operator+(const xbString &s1, const char *s2) {
- xbString tmp(s1.getData());
- tmp += s2;
- return tmp;
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbString operator+(const char *s1, const xbString &s2) {
- xbString tmp(s1);
- tmp += s2;
- return tmp;
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbString operator+(const xbString &s1, char c2) {
- xbString tmp(s1.getData());
- tmp += c2;
- return tmp;
-}
-
-//! Short description.
-/*!
-*/
-XBDLLEXPORT xbString operator+(char c1, const xbString &s2) {
- xbString tmp(c1);
- tmp += s2;
- return tmp;
-}
-
-//! Short description.
-/*!
- \param pos
- \param c
-*/
-void xbString::putAt(size_t pos, char c) {
- if (pos>len())
- return;
-
- data[pos] = c;
-}
-
-//! Short description.
-/*!
- \param str
- \param pos
- \param n
-*/
-xbString& xbString::assign(const xbString& str, size_t pos, int n)
-{
- if(data){
- free(data);
- data = 0;
- }
-
- if(str.len() <= pos){
- size = 0;
- return (*this);
- }
-
- if(str.len() < pos + n){
- n = str.len() - pos;
- }
-
- const char *d = str;
-
- if (n == -1){
-// data = (char *)malloc(str.len()-pos+1); ms win/nt bug fix
- data = (char *)calloc(str.len()-pos+1, sizeof( char ));
- strcpy(data, d+pos);
- size = str.len()-pos+1;
- }
- else
- {
-// data = (char *)malloc(n); ms win/nt bug fix
-// boundschecker flags the next line as a memory leak
-// but this is a valid memory allocation
- data = (char *)calloc(n + 1, sizeof(char));
- strncpy(data, d + pos, n);
- data[n] = '\0';
- size = n + 1;
- }
-
- return (*this);
-}
-
-//! Short description.
-/*!
- \param str
- \param n
-*/
-xbString& xbString::assign(char* str, int n)
-{
- if(data)
- {
- free(data);
- data = 0;
- }
-
- data = (char *)calloc(n + 1, sizeof(char));
- strncpy(data, str, n);
- data[n] = 0;
- size = n + 1;
-
- return (*this);
-}
-
-//! Short description.
-/*!
-*/
-void xbString::trim() {
- int l = len()-1;
-
- for (;;) {
- if (data[l] != ' ')
- break;
- data[l] = 0;
- if (l == 0)
- break;
- l--;
- }
-}
-
-//! Short description.
-/*!
- \param pos
- \param n
-*/
-xbString &xbString::remove(size_t pos, int n) {
- if (data == NULL)
- return (*this);
- if (data[0] == 0)
- return (*this);
-
- size_t l = len();
-
- if (pos>l)
- return (*this);
- if (n == 0)
- return (*this);
- if (n > int(l-pos))
- n = l-pos;
- if (n<0)
- n = l-pos;
- memcpy(data+pos, data+pos+n, l-pos-n+1);
-
- return (*this);
-}
-
-//! Short description.
-/*!
- \param pos
- \param n
-*/
-xbString xbString::mid(size_t pos, int n) const {
- if (data == NULL)
- return (*this);
- if (data[0] == 0)
- return (*this);
-
- size_t l = len();
-
- if (pos>l)
- return (*this);
- if (n == 0)
- return (*this);
- if (n > int(l-pos))
- n = l-pos;
- if (n<0)
- n = l-pos;
-
- xbString s;
- s.data = (char *)malloc(n+1);
- strncpy(s.data, data+pos, n);
- s.data[n] = 0;
-
- return s;
-}
-
-//! Short description.
-/*!
- \param from
- \param to
-*/
-void xbString::swapChars( char from, char to )
-{
- size_t i;
- for( i = 0; i < size; i++ )
- if( data[i] == from )
- data[i] = to;
-}
-
-//! Short description.
-/*!
- \param c
-*/
-void xbString::zapChar( char c )
-{
- /* routine zaps every occurrence of a given character from the string */
- int p;
- size_t s;
- p = pos( c );
- while( p != -1 ){
- for( s = (size_t) p; s < size; s++ )
- putAt( s, data[s+1]);
- resize( size-1 );
- p = pos( c );
- }
-}
-
-//! Short description.
-/*!
- \param c
-*/
-int xbString::countChar( char c ) const
-{
- int i,j;
-
- for( i = 0,j = 0; i < (int) size; i++ )
- if( data[i] == c )
- j++;
-
- return j;
-}
-
-
-//! Short description.
-/*!
- \param c
-*/
-
-void xbString::addBackSlash( char c )
-{
- /* prefixes all char "c" with a backslash */
- int i, t, cnt;
- xbString ws;
-
- cnt = countChar( c );
- if( !cnt )
- return;
-
- ws.resize( size+cnt );
- for( i = 0, t = 0; i < (int)size; i++ ){
- if( data[i] == c )
- ws.putAt( t++, '\\' );
- ws.putAt( t++, data[i] );
- }
- ws.putAt( t, 0 );
- *this = ws.getData();
-}
-
-//! Short description.
-/*!
- \param cnt
-*/
-void xbString::lTrunc( size_t cnt )
-{
- /* left truncate cnt butes */
-
- char * ndata;
- char * p;
- if( cnt >= size ){
- ctor(0);
- return;
- }
- ndata = (char *) malloc( size - cnt );
- p = data;
- p += cnt;
- strcpy( ndata, p );
- free( data );
- data = ndata;
- size = size - cnt;
-}
-
-
-//! Short description.
-/*!
- \param c
-*/
-void xbString::zapLeadingChar( char c )
-{
- /* left truncate all of character c */
-
- int len = 0;
- char *p;
- p = data;
- while( *p && *p == c ){
- len++;
- p++;
- }
- if( len )
- lTrunc( len );
-}
-
-
-//! Short description.
-/*!
-*/
-xbBool xbString::hasAlphaChars() const
-{
- for( int i = 0; i < (int) size; i++ )
- if( isalpha( data[i] ))
- return 1;
- return 0;
-}
-
-
-//! Short description.
-/*!
- \param out
-*/
-
-int xbString::cvtHexChar( char & out )
-{
- /* this routine converts a four byte string in the format of 0x00
- to a one byte char value
-
- the first four bytes of the string must be in the format 0x00
- anything past the first four bytes is disregarded
-
- returns -1 on error
- 0 on success
- */
-
- int j, k;
- char c;
-
- if( len() < 4 || data[0] != '0' || (data[1]!='X' && data[1]!='x' ))
- return -1;
-
- c = toupper( data[2] );
- j = ( c > '9' ? c - 'A' + 10 : c - '0' );
- c = toupper( data[3] );
- k = ( c > '9' ? c - 'A' + 10 : c - '0' );
- j = ( j << 4 ) + k;
-
- out = ( char ) j;
- return 0;
-}
-
-//! Short description.
-/*!
- \param out
-*/
-int xbString::cvtHexString( xbString & out )
-{
- /* this routine converts a string of four byte format of 0x00
- to a string of one byte chars
-
- returns -1 on error
- 0 on success
- */
-
- char c;
- xbString ws;
- ws = data;
- out = "";
- while( ws.len()){
- if( ws.cvtHexChar( c ))
- return -1;
- out += c;
- ws.lTrunc( 4 );
- }
- return 0;
-}
-//! Short description.
-/*!
- \param src
- \param delim
- \param skipcnt
- \param opt
-*/
-int xbString::setFromDelimitedInput( const char * src,
- char delim, int skipcnt, int opt )
-{
- /* opt values
-
- 1 - ignore delimiters between quotes
- 2 - treat crlf characters as delimters
- 3 - both options 1 and 2
- */
-
- int len;
- int curpos = 0;
- int quotesw = 0;
- const char * s;
- const char * anchor;
-
- /* skip past skipcnt delimiters */
- s = src;
- while( *s && curpos < skipcnt ){
- if( *s == delim && !quotesw )
- curpos++;
- else if (( opt == 1 || opt == 3 ) && *s == '"' )
- quotesw = (quotesw) ? 0 : 1;
- s++;
- }
- /* at the beginning of the field */
- anchor = s;
- while( *s && ( *s != delim || ( *s == delim && quotesw ))){
- if( *s == '"' )
- quotesw = (quotesw) ? 0 : 1;
- s++;
- }
- len = s - anchor;
-
- /* copy data */
- data = (char *) realloc( data, len+1 );
- memcpy( data, anchor, len );
- data[len] = 0;
- this->size = len+1;
-
- if( opt == 2 || opt == 3 ){
- zapChar( 0x0a );
- zapChar( 0x0c );
- zapChar( 0x0d );
- }
-
- return len;
-}
-
diff --git a/xbase64/xbstring.h b/xbase64/xbstring.h
deleted file mode 100755
index 9896cdc..0000000
--- a/xbase64/xbstring.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* xbstring.h
-
- Xbase64 project source code
-
- This file contains the Class definition for a xbString object.
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XBSTRING_H__
-#define __XBSTRING_H__
-
-#ifdef __GNU LesserG__
-#pragma interface
-#endif
-
-#ifdef __WIN32__
-#include <xbase64/xbwincfg.h>
-#else
-#include <xbase64/xbconfig.h>
-#endif
-
-#include <stdlib.h>
-#include <iostream>
-
-/*! \file xbstring.h
-*/
-
-//! xbString class
-/*!
-*/
-class XBDLLEXPORT xbString {
-public:
- enum {npos = -1};
-
- xbString();
- xbString(size_t size);
- xbString(char c);
- xbString(const char *s);
- xbString(const char *s, size_t maxlen);
- xbString(const xbString &s);
- virtual ~xbString();
-
- operator const char *() const;
- char operator[](int n) { return data[n]; }
-
- xbString &operator=(const xbString &s);
- xbString &operator=(const char *s);
- xbString &operator=(char c);
- xbString &operator+=(const char *s);
- xbString &operator+=(char c);
- xbString &operator-=(const char *s);
-
- xbBool operator == ( const xbString& ) const;
- xbBool operator != ( const xbString& ) const;
- xbBool operator < ( const xbString& ) const;
- xbBool operator > ( const xbString& ) const;
- xbBool operator <= ( const xbString& ) const;
- xbBool operator >= ( const xbString& ) const;
-
- friend XBDLLEXPORT std::ostream& operator << ( std::ostream&,
- const xbString& );
- void addBackSlash( char c );
- xbString &assign(const xbString& str, size_t pos = 0, int n = npos);
- xbString &assign(char* str, int n);
- xbString copy() const;
- const char *c_str() const;
- int countChar( char c ) const;
- int cvtHexChar( char & out );
- int cvtHexString( xbString & out );
- char getCharacter( int n ) const { return data[n]; }
- const char *getData() const;
- xbBool hasAlphaChars() const;
- xbBool isEmpty() const;
- xbBool isNull() const;
- size_t len() const;
- size_t length() const;
- xbString mid(size_t pos = 0, int n = npos) const;
- void lTrunc( size_t cnt );
- int pos(char c);
- int pos(const char* s);
- void putAt(size_t pos, char c);
- xbString &remove(size_t pos = 0, int n = npos);
- void resize(size_t size);
- void setNum(long num);
- void setNum(char * fmt, double num);
- xbString &sprintf(const char *format, ...);
- void swapChars( char from, char to );
- void toLowerCase();
- void toUpperCase();
- void trim();
- void zapChar( char c );
- void zapLeadingChar( char c );
- int setFromDelimitedInput(const char *,char, int, int );
-
-protected:
- void ctor(const char *s);
- void ctor(const char *s, size_t maxlen);
- char *data;
- size_t size;
- static const char * NullString;
-};
-
-XBDLLEXPORT xbString operator-(const xbString &s1, const xbString &s2);
-XBDLLEXPORT xbString operator+(const xbString &s1, const xbString &s2);
-XBDLLEXPORT xbString operator+(const xbString &s1, const char *s2);
-XBDLLEXPORT xbString operator+(const char *s1, const xbString &s2);
-XBDLLEXPORT xbString operator+(const xbString &s1, char c2);
-XBDLLEXPORT xbString operator+(char c1, const xbString &s2);
-XBDLLEXPORT xbBool operator==(const xbString &s1, const char *s2);
-XBDLLEXPORT xbBool operator!=(const xbString &s1, const char *s2);
-
-#endif
-
diff --git a/xbase64/xbtypes.h b/xbase64/xbtypes.h
deleted file mode 100755
index de5f08c..0000000
--- a/xbase64/xbtypes.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* xbtypes.h
-
- Xbase64 project source code
-
- Copyright (C) 1997,2003 Gary A Kunkel
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- Contact:
-
- Email:
-
- xdb-devel@lists.sourceforge.net
- xdb-users@lists.sourceforge.net
-
-
- Regular Mail:
-
- XBase Support
- 149C South Main St
- Keller Texas, 76248
- USA
-
-*/
-
-#ifndef __XB_XTYPES_H__
-#define __XB_XTYPES_H__
-
-#include <stdio.h>
-
-/*! \file xbtypes.h
-*/
-
-//! xbULong type
-/*!
-*/
-typedef unsigned long int xbULong;
-
-//! xbUShort type
-/*!
-*/
-typedef unsigned short int xbUShort;
-
-//! xbShort type
-/*!
-*/
-typedef short int xbShort;
-typedef long xbLong;
-
-
-//! xbFloat type
-/*!
-*/
-typedef float xbFloat;
-
-
-//! xbDouble type
-/*!
-*/
-typedef double xbDouble;
-
-//! xbBool type
-/*!
-*/
-typedef short int xbBool;
-
-//! xbOffT type
-/*!
-*/
-#ifdef XB_LOCKING_ON
-#ifdef __WIN32__
-#else
-#endif
-#endif // XB_LOCKING_ON
-#endif // __XB_XTYPES_H__
-
-// 64 bit file processing
-#if defined(HAVE_FSEEKO) && defined(HAVE_FTELLO) && defined(XB_LARGEFILE_SUPPORT)
- #define _ftell ftello
- #define _fseek fseeko
- typedef off_t xbOffT;
-#else
- #define _ftell ftell
- #define _fseek fseek
- typedef long xbOffT;
-#endif
diff --git a/xbase64/xbwincfg.h b/xbase64/xbwincfg.h
deleted file mode 100755
index df2d187..0000000
--- a/xbase64/xbwincfg.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* config file for windows environments */
-
-/* Name of package */
-#define PACKAGE "xbase64"
-
-/* Version number of package */
-#define VERSION "3.1.2"
-
-/* Define if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define if you have io.h */
-#define HAVE_IO_H 1
-
-/* Define if you need to have .ndx indexes */
-#define XB_INDEX_NDX 1
-
-/* Define if you need to have .ntx indexes */
-#define XB_INDEX_NTX 1
-
-/* Define if you need to have .cdx indexes */
-#define XB_INDEX_CDX 1
-
-/* Define if you need to support memo fields */
-#define XB_MEMO_FIELDS 1
-
-/* Define if you need expressions */
-#define XB_EXPRESSIONS 1
-
-/* Define if you need locking support */
-#undef XB_LOCKING_ON
-
-/* Define if you need to turn on XBase specific debug */
-#define XBASE_DEBUG 1
-
-/* Define if using real deletes */
-#define XB_REAL_DELETE 1
-
-/* Define if need filters */
-#define XB_FILTERS 1
-
-/* Define if you have the fcntl function. */
-#define HAVE_FCNTL 1
-
-/* Define if you have the vsnprintf function. */
-//#define HAVE_VSNPRINTF 1
-
-/* Define if you have the vsprintf function. */
-#define HAVE_VSPRINTF 1
-
-/* Define if you have the <ctype.h> header file. */
-#define HAVE_CTYPE_H 1
-
-/* Define if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Should we include generic index support? */
-#if defined(XB_INDEX_NDX) || defined(XB_INDEX_NTX)
-#define XB_INDEX_ANY 1
-#endif
-
-/* expressions required for indexes */
-#if defined(XB_INDEX_ANY) && !defined(XB_EXPRESSIONS)
-#define XB_EXPRESSIONS 1
-#endif
-
-/* default memo block size */
-#define XB_DBT_BLOCK_SIZE 512
-
-/* filename path separator */
-#define PATH_SEPARATOR '/'
-
-/* MS uses WIN32, Borland uses __WIN32__ */
-#ifdef WIN32
- #ifndef __WIN32__
- #define __WIN32__
- #endif
-#endif
-