diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2022-12-07 13:17:14 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2022-12-07 13:17:14 +0100 |
commit | 4875a3dd9b183dcd2256e2abfc4ccf7484c233b4 (patch) | |
tree | 0abbea881ded030851014ffdd60fbf71fead8f65 /xbase64 | |
parent | daf17154bf13139d9375f48525d19d6aaba08155 (diff) |
New upstream version 4.0.2upstream/4.0.2
Diffstat (limited to 'xbase64')
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 - |