Compare commits
5 Commits
tags/commi
...
NoRDFResou
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd0616d861 | ||
|
|
65efc2a867 | ||
|
|
0f42597e40 | ||
|
|
4b45375ab4 | ||
|
|
fe44c577bf |
@@ -1,816 +0,0 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Stephen Lamm
|
||||
# Benjamin Smedberg <bsmedberg@covad.net>
|
||||
# Chase Phillips <chase@mozilla.org>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
# Build a mozilla application.
|
||||
#
|
||||
# To checkout and build a tree,
|
||||
# 1. cvs co mozilla/client.mk
|
||||
# 2. cd mozilla
|
||||
# 3. create your .mozconfig file with
|
||||
# mk_add_options MOZ_CO_PROJECT=suite,browser,mail,minimo,xulrunner
|
||||
# 4. gmake -f client.mk
|
||||
#
|
||||
# This script will pick up the CVSROOT from the CVS/Root file. If you wish
|
||||
# to use a different CVSROOT, you must set CVSROOT in your environment:
|
||||
#
|
||||
# export CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
|
||||
# export CVSROOT=:pserver:username%somedomain.org@cvs.mozilla.org:/cvsroot
|
||||
#
|
||||
# You must specify which products/modules you wish to checkout, with
|
||||
# MOZ_CO_PROJECT, MOZ_CO_MODULE, and BUILD_MODULES variables.
|
||||
#
|
||||
# MOZ_CO_PROJECT possibilities include the following:
|
||||
# suite (Seamonkey suite)
|
||||
# browser (aka Firefox)
|
||||
# mail (aka Thunderbird)
|
||||
# minimo (small browser for devices)
|
||||
# composer (standalone composer, aka NVU)
|
||||
# calendar (aka Sunbird, use this to build the calendar extensions also)
|
||||
# xulrunner
|
||||
# macbrowser (aka Camino)
|
||||
#
|
||||
# Other common MOZ_CO_MODULE options include the following:
|
||||
# mozilla/other-licenses/libart_lgpl
|
||||
# mozilla/other-licenses/bsdiff
|
||||
# mozilla/tools/codesighs
|
||||
#
|
||||
# Other targets (gmake -f client.mk [targets...]),
|
||||
# checkout
|
||||
# build
|
||||
# clean (realclean is now the same as clean)
|
||||
# distclean
|
||||
#
|
||||
# See http://www.mozilla.org/build/ for more information.
|
||||
#
|
||||
# Options:
|
||||
# MOZ_OBJDIR - Destination object directory
|
||||
# MOZ_CO_DATE - Date tag to use for checkout (default: none)
|
||||
# MOZ_CO_MODULE - Module to checkout
|
||||
# MOZ_CVS_FLAGS - Flags to pass cvs (default: -q -z3)
|
||||
# MOZ_CO_FLAGS - Flags to pass after 'cvs co' (default: -P)
|
||||
# MOZ_MAKE_FLAGS - Flags to pass to $(MAKE)
|
||||
# MOZ_CO_LOCALES - localizations to pull (MOZ_CO_LOCALES="de-DE,pt-BR")
|
||||
# MOZ_LOCALE_DIRS - directories which contain localizations
|
||||
# LOCALES_CVSROOT - CVSROOT to use to pull localizations
|
||||
#
|
||||
|
||||
AVAILABLE_PROJECTS = \
|
||||
all \
|
||||
suite \
|
||||
toolkit \
|
||||
browser \
|
||||
mail \
|
||||
minimo \
|
||||
composer \
|
||||
calendar \
|
||||
xulrunner \
|
||||
macbrowser \
|
||||
$(NULL)
|
||||
|
||||
MODULES_core := \
|
||||
SeaMonkeyAll \
|
||||
mozilla/browser/config/version.txt \
|
||||
mozilla/mail/config/version.txt \
|
||||
mozilla/ipc/ipcd \
|
||||
mozilla/modules/libpr0n \
|
||||
mozilla/modules/libmar \
|
||||
mozilla/modules/libbz2 \
|
||||
mozilla/accessible \
|
||||
mozilla/security/manager \
|
||||
mozilla/toolkit \
|
||||
mozilla/storage \
|
||||
mozilla/db/sqlite3 \
|
||||
$(NULL)
|
||||
|
||||
LOCALES_core := \
|
||||
netwerk \
|
||||
dom \
|
||||
$(NULL)
|
||||
|
||||
MODULES_toolkit := \
|
||||
$(MODULES_core) \
|
||||
mozilla/chrome \
|
||||
$(NULL)
|
||||
|
||||
LOCALES_toolkit := \
|
||||
$(LOCALES_core) \
|
||||
toolkit \
|
||||
security/manager \
|
||||
$(NULL)
|
||||
|
||||
MODULES_suite := \
|
||||
$(MODULES_core) \
|
||||
mozilla/suite \
|
||||
$(NULL)
|
||||
|
||||
LOCALES_suite := \
|
||||
$(LOCALES_core) \
|
||||
$(NULL)
|
||||
|
||||
MODULES_browser := \
|
||||
$(MODULES_toolkit) \
|
||||
mozilla/browser \
|
||||
mozilla/other-licenses/branding/firefox \
|
||||
mozilla/other-licenses/7zstub/firefox \
|
||||
$(NULL)
|
||||
|
||||
LOCALES_browser := \
|
||||
$(LOCALES_toolkit) \
|
||||
browser \
|
||||
other-licenses/branding/firefox \
|
||||
$(NULL)
|
||||
|
||||
BOOTSTRAP_browser := mozilla/browser/config/mozconfig
|
||||
|
||||
MODULES_minimo := \
|
||||
$(MODULES_toolkit) \
|
||||
mozilla/minimo \
|
||||
$(NULL)
|
||||
|
||||
MODULES_mail := \
|
||||
$(MODULES_toolkit) \
|
||||
mozilla/mail \
|
||||
mozilla/other-licenses/branding/thunderbird \
|
||||
mozilla/other-licenses/7zstub/thunderbird \
|
||||
$(NULL)
|
||||
|
||||
LOCALES_mail := \
|
||||
$(LOCALES_toolkit) \
|
||||
mail \
|
||||
other-licenses/branding/thunderbird \
|
||||
editor/ui \
|
||||
$(NULL)
|
||||
|
||||
BOOTSTRAP_mail := mozilla/mail/config/mozconfig
|
||||
|
||||
MODULES_composer := \
|
||||
$(MODULES_toolkit) \
|
||||
mozilla/composer \
|
||||
$(NULL)
|
||||
|
||||
MODULES_calendar := \
|
||||
$(MODULES_toolkit) \
|
||||
mozilla/storage \
|
||||
mozilla/db/sqlite3 \
|
||||
mozilla/calendar \
|
||||
$(NULL)
|
||||
|
||||
BOOTSTRAP_calendar := mozilla/calendar/sunbird/config/mozconfig
|
||||
|
||||
MODULES_xulrunner := \
|
||||
$(MODULES_toolkit) \
|
||||
mozilla/xulrunner \
|
||||
$(NULL)
|
||||
|
||||
LOCALES_xulrunner := \
|
||||
$(LOCALES_toolkit) \
|
||||
$(NULL)
|
||||
|
||||
BOOTSTRAP_xulrunner := mozilla/xulrunner/config/mozconfig
|
||||
|
||||
MODULES_macbrowser := \
|
||||
$(MODULES_core) \
|
||||
mozilla/camino \
|
||||
$(NULL)
|
||||
|
||||
BOOTSTRAP_macbrowser := mozilla/camino/config/mozconfig
|
||||
|
||||
MODULES_all := \
|
||||
mozilla/other-licenses/bsdiff \
|
||||
mozilla/other-licenses/libart_lgpl \
|
||||
mozilla/tools/trace-malloc \
|
||||
mozilla/tools/jprof \
|
||||
mozilla/tools/codesighs \
|
||||
mozilla/tools/update-packaging \
|
||||
mozilla/other-licenses/branding \
|
||||
mozilla/other-licenses/7zstub \
|
||||
$(NULL)
|
||||
|
||||
#######################################################################
|
||||
# Checkout Tags
|
||||
#
|
||||
# For branches, uncomment the MOZ_CO_TAG line with the proper tag,
|
||||
# and commit this file on that tag.
|
||||
MOZ_CO_TAG = MOZILLA_1_8_BRANCH
|
||||
NSPR_CO_TAG = MOZILLA_1_8_BRANCH
|
||||
NSS_CO_TAG = MOZILLA_1_8_BRANCH
|
||||
LDAPCSDK_CO_TAG = MOZILLA_1_8_BRANCH
|
||||
LOCALES_CO_TAG = MOZILLA_1_8_BRANCH
|
||||
|
||||
BUILD_MODULES = all
|
||||
|
||||
#######################################################################
|
||||
# Defines
|
||||
#
|
||||
CVS = cvs
|
||||
comma := ,
|
||||
|
||||
CWD := $(shell pwd)
|
||||
|
||||
ifeq "$(CWD)" "/"
|
||||
CWD := /.
|
||||
endif
|
||||
|
||||
ifneq (, $(wildcard client.mk))
|
||||
# Ran from mozilla directory
|
||||
ROOTDIR := $(shell dirname $(CWD))
|
||||
TOPSRCDIR := $(CWD)
|
||||
else
|
||||
# Ran from mozilla/.. directory (?)
|
||||
ROOTDIR := $(CWD)
|
||||
TOPSRCDIR := $(CWD)/mozilla
|
||||
endif
|
||||
|
||||
# on os2, TOPSRCDIR may have two forward slashes in a row, which doesn't
|
||||
# work; replace first instance with one forward slash
|
||||
TOPSRCDIR := $(shell echo "$(TOPSRCDIR)" | sed -e 's%//%/%')
|
||||
|
||||
ifndef TOPSRCDIR_MOZ
|
||||
TOPSRCDIR_MOZ=$(TOPSRCDIR)
|
||||
endif
|
||||
|
||||
# if ROOTDIR equals only drive letter (i.e. "C:"), set to "/"
|
||||
DIRNAME := $(shell echo "$(ROOTDIR)" | sed -e 's/^.://')
|
||||
ifeq ($(DIRNAME),)
|
||||
ROOTDIR := /.
|
||||
endif
|
||||
|
||||
AUTOCONF := autoconf
|
||||
MKDIR := mkdir
|
||||
SH := /bin/sh
|
||||
ifndef MAKE
|
||||
MAKE := gmake
|
||||
endif
|
||||
|
||||
CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
|
||||
ifdef CONFIG_GUESS_SCRIPT
|
||||
CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
|
||||
else
|
||||
_IS_FIRST_CHECKOUT := 1
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS
|
||||
|
||||
# Add the CVS root to CVS_FLAGS if needed
|
||||
CVS_ROOT_IN_TREE := $(shell cat $(TOPSRCDIR)/CVS/Root 2>/dev/null)
|
||||
ifneq ($(CVS_ROOT_IN_TREE),)
|
||||
ifneq ($(CVS_ROOT_IN_TREE),$(CVSROOT))
|
||||
CVS_FLAGS := -d $(CVS_ROOT_IN_TREE)
|
||||
endif
|
||||
endif
|
||||
|
||||
CVS_CO_DATE_FLAGS = $(if $(MOZ_CO_DATE),-D "$(MOZ_CO_DATE)")
|
||||
CVSCO = $(CVS) $(CVS_FLAGS) co $(MOZ_CO_FLAGS) $(if $(MOZ_CO_TAG),-r $(MOZ_CO_TAG)) $(CVS_CO_DATE_FLAGS)
|
||||
|
||||
CVSCO_LOGFILE := $(ROOTDIR)/cvsco.log
|
||||
CVSCO_LOGFILE := $(shell echo $(CVSCO_LOGFILE) | sed s%//%/%)
|
||||
|
||||
# if LOCALES_CVSROOT is not specified, set it here
|
||||
# (and let mozconfig override it)
|
||||
LOCALES_CVSROOT ?= :pserver:anonymous@cvs-mirror.mozilla.org:/l10n
|
||||
|
||||
####################################
|
||||
# Load mozconfig Options
|
||||
|
||||
# See build pages, http://www.mozilla.org/build/ for how to set up mozconfig.
|
||||
|
||||
MOZCONFIG_LOADER := mozilla/build/autoconf/mozconfig2client-mk
|
||||
MOZCONFIG_FINDER := mozilla/build/autoconf/mozconfig-find
|
||||
MOZCONFIG_MODULES := mozilla/build/unix/modules.mk mozilla/build/unix/uniq.pl
|
||||
run_for_side_effects := \
|
||||
$(shell cd $(ROOTDIR); \
|
||||
if test "$(_IS_FIRST_CHECKOUT)"; then \
|
||||
$(CVSCO) $(MOZCONFIG_FINDER) $(MOZCONFIG_LOADER) $(MOZCONFIG_MODULES); \
|
||||
else true; \
|
||||
fi; \
|
||||
$(MOZCONFIG_LOADER) $(TOPSRCDIR) mozilla/.mozconfig.mk > mozilla/.mozconfig.out)
|
||||
include $(TOPSRCDIR)/.mozconfig.mk
|
||||
include $(TOPSRCDIR)/build/unix/modules.mk
|
||||
|
||||
####################################
|
||||
# Options that may come from mozconfig
|
||||
|
||||
MOZ_PROJECT_LIST := $(subst $(comma), ,$(MOZ_CO_PROJECT))
|
||||
|
||||
ifneq (,$(filter-out $(AVAILABLE_PROJECTS),$(MOZ_PROJECT_LIST)))
|
||||
$(error MOZ_CO_PROJECT contains an unrecognized project.)
|
||||
endif
|
||||
|
||||
ifeq (all,$(filter all,$(MOZ_PROJECT_LIST)))
|
||||
MOZ_PROJECT_LIST := $(AVAILABLE_PROJECTS)
|
||||
endif
|
||||
|
||||
MOZ_MODULE_LIST := $(subst $(comma), ,$(MOZ_CO_MODULE)) $(foreach project,$(MOZ_PROJECT_LIST),$(MODULES_$(project)))
|
||||
LOCALE_DIRS := $(MOZ_LOCALE_DIRS) $(foreach project,$(MOZ_PROJECT_LIST),$(LOCALES_$(project)))
|
||||
|
||||
MOZCONFIG_MODULES += $(foreach project,$(MOZ_PROJECT_LIST),$(BOOTSTRAP_$(project)))
|
||||
|
||||
# Using $(sort) here because it also removes duplicate entries.
|
||||
MOZ_MODULE_LIST := $(sort $(MOZ_MODULE_LIST))
|
||||
LOCALE_DIRS := $(sort $(LOCALE_DIRS))
|
||||
MOZCONFIG_MODULES := $(sort $(MOZCONFIG_MODULES))
|
||||
|
||||
# Change CVS flags if anonymous root is requested
|
||||
ifdef MOZ_CO_USE_MIRROR
|
||||
CVS_FLAGS := -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
|
||||
endif
|
||||
|
||||
# MOZ_CVS_FLAGS - Basic CVS flags
|
||||
ifeq "$(origin MOZ_CVS_FLAGS)" "undefined"
|
||||
CVS_FLAGS := $(CVS_FLAGS) -q -z 3
|
||||
else
|
||||
CVS_FLAGS := $(MOZ_CVS_FLAGS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_OBJDIR
|
||||
OBJDIR := $(MOZ_OBJDIR)
|
||||
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS) -C $(OBJDIR)
|
||||
else
|
||||
OBJDIR := $(TOPSRCDIR)
|
||||
MOZ_MAKE := $(MAKE) $(MOZ_MAKE_FLAGS)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for NSS
|
||||
#
|
||||
NSS_CO_MODULE = \
|
||||
mozilla/security/nss \
|
||||
mozilla/security/coreconf \
|
||||
$(NULL)
|
||||
|
||||
NSS_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
NSS_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
NSS_CO_FLAGS := $(NSS_CO_FLAGS) $(if $(NSS_CO_TAG),-r $(NSS_CO_TAG),-A)
|
||||
|
||||
# Cannot pull static tags by date
|
||||
ifeq ($(NSS_CO_TAG),NSS_CLIENT_TAG)
|
||||
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(NSS_CO_MODULE)
|
||||
else
|
||||
CVSCO_NSS = $(CVS) $(CVS_FLAGS) co $(NSS_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSS_CO_MODULE)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for NSPR
|
||||
#
|
||||
NSPR_CO_MODULE = mozilla/nsprpub
|
||||
NSPR_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
NSPR_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
NSPR_CO_FLAGS := $(NSPR_CO_FLAGS) $(if $(NSPR_CO_TAG),-r $(NSPR_CO_TAG),-A)
|
||||
|
||||
# Cannot pull static tags by date
|
||||
ifeq ($(NSPR_CO_TAG),NSPRPUB_CLIENT_TAG)
|
||||
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(NSPR_CO_MODULE)
|
||||
else
|
||||
CVSCO_NSPR = $(CVS) $(CVS_FLAGS) co $(NSPR_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(NSPR_CO_MODULE)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# CVS defines for the C LDAP SDK
|
||||
#
|
||||
LDAPCSDK_CO_MODULE = mozilla/directory/c-sdk
|
||||
LDAPCSDK_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
LDAPCSDK_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
LDAPCSDK_CO_FLAGS := $(LDAPCSDK_CO_FLAGS) $(if $(LDAPCSDK_CO_TAG),-r $(LDAPCSDK_CO_TAG),-A)
|
||||
CVSCO_LDAPCSDK = $(CVS) $(CVS_FLAGS) co $(LDAPCSDK_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(LDAPCSDK_CO_MODULE)
|
||||
|
||||
####################################
|
||||
# CVS defines for standalone modules
|
||||
#
|
||||
ifeq ($(BUILD_MODULES),all)
|
||||
CHECKOUT_STANDALONE := true
|
||||
CHECKOUT_STANDALONE_NOSUBDIRS := true
|
||||
else
|
||||
STANDALONE_CO_MODULE := $(filter-out $(NSPRPUB_DIR) security directory/c-sdk, $(BUILD_MODULE_CVS))
|
||||
STANDALONE_CO_MODULE += allmakefiles.sh client.mk aclocal.m4 configure configure.in
|
||||
STANDALONE_CO_MODULE += Makefile.in
|
||||
|
||||
MOZ_MODULE_LIST += $(addprefix mozilla/,$(STANDALONE_CO_MODULE))
|
||||
NOSUBDIRS_MODULE := $(addprefix mozilla/,$(BUILD_MODULE_CVS_NS))
|
||||
|
||||
ifeq (,$(filter $(NSPRPUB_DIR), $(BUILD_MODULE_CVS))$(MOZ_CO_PROJECT))
|
||||
CVSCO_NSPR :=
|
||||
endif
|
||||
ifeq (,$(filter security security/manager, $(BUILD_MODULE_CVS))$(MOZ_CO_PROJECT))
|
||||
CVSCO_NSS :=
|
||||
endif
|
||||
ifeq (,$(filter directory/c-sdk, $(BUILD_MODULE_CVS))$(MOZ_CO_PROJECT))
|
||||
CVSCO_LDAPCSDK :=
|
||||
endif
|
||||
endif
|
||||
|
||||
####################################
|
||||
# Error on obsolete variables.
|
||||
#
|
||||
|
||||
ifdef MOZ_MAPINFO
|
||||
$(warning MOZ_MAPINFO is obsolete, use MOZ_CO_MODULE=mozilla/tools/codesighs instead.)
|
||||
MOZ_MODULE_LIST += mozilla/tools/codesighs
|
||||
endif
|
||||
ifdef MOZ_INTERNAL_LIBART_LGPL
|
||||
$(error MOZ_INTERNAL_LIBART_LGPL is obsolete, use MOZ_CO_MODULE=mozilla/other-licenses/libart_lgpl instead.)
|
||||
endif
|
||||
ifdef MOZ_PHOENIX
|
||||
$(warning MOZ_PHOENIX is obsolete.)
|
||||
MOZ_MODULE_LIST += $(MODULES_browser)
|
||||
# $(error MOZ_PHOENIX is obsolete, use MOZ_CO_PROJECT=browser and --enable-application=browser)
|
||||
endif
|
||||
ifdef MOZ_THUNDERBIRD
|
||||
$(warning MOZ_THUNDERBIRD is obsolete.)
|
||||
MOZ_MODULE_LIST += $(MODULES_mail)
|
||||
# $(error MOZ_THUNDERBIRD is obsolete, use MOZ_CO_PROJECT=mail and --enable-application=mail)
|
||||
endif
|
||||
|
||||
###################################
|
||||
# Checkout main modules
|
||||
#
|
||||
|
||||
# sort is used to remove duplicates. SeaMonkeyAll is special-cased to
|
||||
# checkout last, because if you check it out first, there is a sticky
|
||||
# tag left over from checking out the LDAP SDK, which causes files in
|
||||
# the root directory to be missed.
|
||||
MOZ_MODULE_LIST := $(sort $(filter-out SeaMonkeyAll,$(MOZ_MODULE_LIST))) $(firstword $(filter SeaMonkeyAll,$(MOZ_MODULE_LIST)))
|
||||
|
||||
MODULES_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
MODULES_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
MODULES_CO_FLAGS := $(MODULES_CO_FLAGS) $(if $(MOZ_CO_TAG),-r $(MOZ_CO_TAG),-A)
|
||||
|
||||
CVSCO_MODULES_NS = $(CVS) $(CVS_FLAGS) co $(MODULES_CO_FLAGS) $(CVS_CO_DATE_FLAGS) -l $(NOSUBDIRS_MODULE)
|
||||
|
||||
ifeq (,$(strip $(MOZ_MODULE_LIST)))
|
||||
FASTUPDATE_MODULES = $(error No modules or projects were specified. Use MOZ_CO_PROJECT to specify a project for checkout.)
|
||||
CHECKOUT_MODULES = $(error No modules or projects were specified. Use MOZ_CO_PROJECT to specify a project for checkout.)
|
||||
else
|
||||
FASTUPDATE_MODULES := fast_update $(CVS) $(CVS_FLAGS) co $(MODULES_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(MOZ_MODULE_LIST)
|
||||
CHECKOUT_MODULES := $(foreach module,$(MOZ_MODULE_LIST),cvs_co $(CVS) $(CVS_FLAGS) co $(MODULES_CO_FLAGS) $(CVS_CO_DATE_FLAGS) $(module);)
|
||||
endif
|
||||
ifeq (,$(NOSUBDIRS_MODULE))
|
||||
FASTUPDATE_MODULES_NS := true
|
||||
CHECKOUT_MODULES_NS := true
|
||||
else
|
||||
FASTUPDATE_MODULES_NS := fast_update $(CVSCO_MODULES_NS)
|
||||
CHECKOUT_MODULES_NS := cvs_co $(CVSCO_MODULES_NS)
|
||||
endif
|
||||
|
||||
###################################
|
||||
# CVS defines for locales
|
||||
#
|
||||
|
||||
LOCALES_CO_FLAGS := -P
|
||||
ifdef MOZ_CO_FLAGS
|
||||
LOCALES_CO_FLAGS := $(MOZ_CO_FLAGS)
|
||||
endif
|
||||
LOCALES_CO_FLAGS := $(LOCALES_CO_FLAGS) $(if $(LOCALES_CO_TAG),-r $(LOCALES_CO_TAG),-A)
|
||||
|
||||
ifndef MOZ_CO_LOCALES
|
||||
FASTUPDATE_LOCALES := true
|
||||
CHECKOUT_LOCALES := true
|
||||
else
|
||||
|
||||
override MOZ_CO_LOCALES := $(subst $(comma), ,$(MOZ_CO_LOCALES))
|
||||
|
||||
ifeq (all,$(MOZ_CO_LOCALES))
|
||||
MOZCONFIG_MODULES += $(foreach project,$(MOZ_PROJECT_LIST),mozilla/$(project)/locales/all-locales)
|
||||
|
||||
LOCALE_CO_DIRS := $(sort $(foreach project,$(MOZ_PROJECT_LIST),$(foreach locale,$(shell cat mozilla/$(project)/locales/all-locales),$(foreach dir,$(LOCALES_$(project)),l10n/$(locale)/$(dir)))))
|
||||
else # MOZ_CO_LOCALES != all
|
||||
LOCALE_CO_DIRS = $(sort $(foreach locale,$(MOZ_CO_LOCALES),$(foreach dir,$(LOCALE_DIRS),l10n/$(locale)/$(dir))))
|
||||
endif
|
||||
|
||||
CVSCO_LOCALES := $(CVS) $(CVS_FLAGS) -d $(LOCALES_CVSROOT) co $(LOCALES_CO_FLAGS) $(LOCALE_CO_DIRS)
|
||||
|
||||
FASTUPDATE_LOCALES := fast_update $(CVSCO_LOCALES)
|
||||
CHECKOUT_LOCALES := cvs_co $(CVSCO_LOCALES)
|
||||
endif #MOZ_CO_LOCALES
|
||||
|
||||
#######################################################################
|
||||
# Rules
|
||||
#
|
||||
|
||||
# Print out any options loaded from mozconfig.
|
||||
all build checkout clean depend distclean export libs install realclean::
|
||||
@if test -f .mozconfig.out; then \
|
||||
cat .mozconfig.out; \
|
||||
rm -f .mozconfig.out; \
|
||||
else true; \
|
||||
fi
|
||||
|
||||
ifdef _IS_FIRST_CHECKOUT
|
||||
all:: checkout build
|
||||
else
|
||||
all:: checkout alldep
|
||||
endif
|
||||
|
||||
# Windows equivalents
|
||||
pull_all: checkout
|
||||
build_all: build
|
||||
build_all_dep: alldep
|
||||
build_all_depend: alldep
|
||||
clobber clobber_all: clean
|
||||
pull_and_build_all: checkout alldep
|
||||
|
||||
# Do everything from scratch
|
||||
everything: checkout clean build
|
||||
|
||||
####################################
|
||||
# CVS checkout
|
||||
#
|
||||
checkout::
|
||||
# @: Backup the last checkout log.
|
||||
@if test -f $(CVSCO_LOGFILE) ; then \
|
||||
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo "Removing local configures" ; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
|
||||
mozilla/directory/c-sdk/configure
|
||||
endif
|
||||
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
|
||||
@echo '$(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/client.mk $(MOZCONFIG_MODULES)'; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(CVSCO) $(CVS_CO_DATE_FLAGS) mozilla/client.mk $(MOZCONFIG_MODULES)
|
||||
@cd $(ROOTDIR) && $(MAKE) -f mozilla/client.mk real_checkout
|
||||
|
||||
# Start the checkout. Split the output to the tty and a log file.
|
||||
|
||||
real_checkout:
|
||||
@set -e; \
|
||||
cvs_co() { set -e; echo "$$@" ; \
|
||||
"$$@" 2>&1 | tee -a $(CVSCO_LOGFILE); }; \
|
||||
cvs_co $(CVSCO_NSPR); \
|
||||
cvs_co $(CVSCO_NSS); \
|
||||
cvs_co $(CVSCO_LDAPCSDK); \
|
||||
$(CHECKOUT_MODULES) \
|
||||
$(CHECKOUT_MODULES_NS); \
|
||||
$(CHECKOUT_LOCALES);
|
||||
@echo "checkout finish: "`date` | tee -a $(CVSCO_LOGFILE)
|
||||
# update the NSS checkout timestamp
|
||||
@if test `egrep -c '^(U|C) mozilla/security/(nss|coreconf)' $(CVSCO_LOGFILE) 2>/dev/null` != 0; then \
|
||||
touch $(TOPSRCDIR)/security/manager/.nss.checkout; \
|
||||
fi
|
||||
# @: Check the log for conflicts. ;
|
||||
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
|
||||
if test "$$conflicts" ; then \
|
||||
echo "$(MAKE): *** Conflicts during checkout." ;\
|
||||
echo "$$conflicts" ;\
|
||||
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
|
||||
false; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo Generating configures using $(AUTOCONF) ; \
|
||||
cd $(TOPSRCDIR) && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
|
||||
endif
|
||||
|
||||
fast-update:
|
||||
# @: Backup the last checkout log.
|
||||
@if test -f $(CVSCO_LOGFILE) ; then \
|
||||
mv $(CVSCO_LOGFILE) $(CVSCO_LOGFILE).old; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo "Removing local configures" ; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(RM) -f mozilla/configure mozilla/nsprpub/configure \
|
||||
mozilla/directory/c-sdk/configure
|
||||
endif
|
||||
@echo "checkout start: "`date` | tee $(CVSCO_LOGFILE)
|
||||
@echo '$(CVSCO) mozilla/client.mk $(MOZCONFIG_MODULES)'; \
|
||||
cd $(ROOTDIR) && \
|
||||
$(CVSCO) mozilla/client.mk $(MOZCONFIG_MODULES)
|
||||
@cd $(TOPSRCDIR) && \
|
||||
$(MAKE) -f client.mk real_fast-update
|
||||
|
||||
# Start the update. Split the output to the tty and a log file.
|
||||
real_fast-update:
|
||||
@set -e; \
|
||||
fast_update() { set -e; config/cvsco-fast-update.pl $$@ 2>&1 | tee -a $(CVSCO_LOGFILE); }; \
|
||||
cvs_co() { set -e; echo "$$@" ; \
|
||||
"$$@" 2>&1 | tee -a $(CVSCO_LOGFILE); }; \
|
||||
fast_update $(CVSCO_NSPR); \
|
||||
cd $(ROOTDIR); \
|
||||
cvs_co $(CVSCO_NSS); \
|
||||
cd mozilla; \
|
||||
fast_update $(CVSCO_LDAPCSDK); \
|
||||
$(FASTUPDATE_MODULES); \
|
||||
$(FASTUPDATE_MODULES_NS); \
|
||||
$(FASTUPDATE_LOCALES);
|
||||
@echo "fast_update finish: "`date` | tee -a $(CVSCO_LOGFILE)
|
||||
# update the NSS checkout timestamp
|
||||
@if test `egrep -c '^(U|C) mozilla/security/(nss|coreconf)' $(CVSCO_LOGFILE) 2>/dev/null` != 0; then \
|
||||
touch $(TOPSRCDIR)/security/manager/.nss.checkout; \
|
||||
fi
|
||||
# @: Check the log for conflicts. ;
|
||||
@conflicts=`egrep "^C " $(CVSCO_LOGFILE)` ;\
|
||||
if test "$$conflicts" ; then \
|
||||
echo "$(MAKE): *** Conflicts during fast-update." ;\
|
||||
echo "$$conflicts" ;\
|
||||
echo "$(MAKE): Refer to $(CVSCO_LOGFILE) for full log." ;\
|
||||
false; \
|
||||
else true; \
|
||||
fi
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
@echo Generating configures using $(AUTOCONF) ; \
|
||||
cd $(TOPSRCDIR) && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/nsprpub && $(AUTOCONF) && \
|
||||
cd $(TOPSRCDIR)/directory/c-sdk && $(AUTOCONF)
|
||||
endif
|
||||
|
||||
####################################
|
||||
# Web configure
|
||||
|
||||
WEBCONFIG_FILE := $(HOME)/.mozconfig
|
||||
|
||||
MOZCONFIG2CONFIGURATOR := build/autoconf/mozconfig2configurator
|
||||
webconfig:
|
||||
@cd $(TOPSRCDIR); \
|
||||
url=`$(MOZCONFIG2CONFIGURATOR) $(TOPSRCDIR)`; \
|
||||
echo Running mozilla with the following url: ;\
|
||||
echo ;\
|
||||
echo $$url ;\
|
||||
mozilla -remote "openURL($$url)" || \
|
||||
netscape -remote "openURL($$url)" || \
|
||||
mozilla $$url || \
|
||||
netscape $$url ;\
|
||||
echo ;\
|
||||
echo 1. Fill out the form on the browser. ;\
|
||||
echo 2. Save the results to $(WEBCONFIG_FILE)
|
||||
|
||||
#####################################################
|
||||
# First Checkout
|
||||
|
||||
ifdef _IS_FIRST_CHECKOUT
|
||||
# First time, do build target in a new process to pick up new files.
|
||||
build::
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk build
|
||||
else
|
||||
|
||||
#####################################################
|
||||
# After First Checkout
|
||||
|
||||
|
||||
####################################
|
||||
# Configure
|
||||
|
||||
CONFIG_STATUS := $(wildcard $(OBJDIR)/config.status)
|
||||
CONFIG_CACHE := $(wildcard $(OBJDIR)/config.cache)
|
||||
|
||||
ifdef RUN_AUTOCONF_LOCALLY
|
||||
EXTRA_CONFIG_DEPS := \
|
||||
$(TOPSRCDIR)/aclocal.m4 \
|
||||
$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
|
||||
$(NULL)
|
||||
|
||||
$(TOPSRCDIR)/configure: $(TOPSRCDIR)/configure.in $(EXTRA_CONFIG_DEPS)
|
||||
@echo Generating $@ using autoconf
|
||||
cd $(TOPSRCDIR); $(AUTOCONF)
|
||||
endif
|
||||
|
||||
CONFIG_STATUS_DEPS := \
|
||||
$(TOPSRCDIR)/configure \
|
||||
$(TOPSRCDIR)/allmakefiles.sh \
|
||||
$(TOPSRCDIR)/.mozconfig.mk \
|
||||
$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
|
||||
$(wildcard $(TOPSRCDIR)/directory/c-sdk/configure) \
|
||||
$(wildcard $(TOPSRCDIR)/mailnews/makefiles) \
|
||||
$(wildcard $(TOPSRCDIR)/themes/makefiles) \
|
||||
$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
|
||||
$(wildcard $(TOPSRCDIR)/config/chrome-versions.sh) \
|
||||
$(NULL)
|
||||
|
||||
# configure uses the program name to determine @srcdir@. Calling it without
|
||||
# $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
|
||||
# path of $(TOPSRCDIR).
|
||||
ifeq ($(TOPSRCDIR),$(OBJDIR))
|
||||
CONFIGURE := ./configure
|
||||
else
|
||||
CONFIGURE := $(TOPSRCDIR)/configure
|
||||
endif
|
||||
|
||||
ifdef MOZ_TOOLS
|
||||
CONFIGURE := $(TOPSRCDIR)/configure
|
||||
endif
|
||||
|
||||
configure:
|
||||
@if test ! -d $(OBJDIR); then $(MKDIR) $(OBJDIR); else true; fi
|
||||
@echo cd $(OBJDIR);
|
||||
@echo $(CONFIGURE) $(CONFIGURE_ARGS)
|
||||
@cd $(OBJDIR) && $(CONFIGURE_ENV_ARGS) $(CONFIGURE) $(CONFIGURE_ARGS) \
|
||||
|| ( echo "*** Fix above errors and then restart with\
|
||||
\"$(MAKE) -f client.mk build\"" && exit 1 )
|
||||
@touch $(OBJDIR)/Makefile
|
||||
|
||||
$(OBJDIR)/Makefile $(OBJDIR)/config.status: $(CONFIG_STATUS_DEPS)
|
||||
@$(MAKE) -f $(TOPSRCDIR)/client.mk configure
|
||||
|
||||
ifdef CONFIG_STATUS
|
||||
$(OBJDIR)/config/autoconf.mk: $(TOPSRCDIR)/config/autoconf.mk.in
|
||||
cd $(OBJDIR); \
|
||||
CONFIG_FILES=config/autoconf.mk ./config.status
|
||||
endif
|
||||
|
||||
|
||||
####################################
|
||||
# Depend
|
||||
|
||||
depend:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
$(MOZ_MAKE) export && $(MOZ_MAKE) depend
|
||||
|
||||
####################################
|
||||
# Build it
|
||||
|
||||
build:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
$(MOZ_MAKE)
|
||||
|
||||
####################################
|
||||
# Profile-feedback build (gcc only)
|
||||
# To use this, you should set the following variables in your mozconfig
|
||||
# mk_add_options PROFILE_GEN_SCRIPT=/path/to/profile-script
|
||||
#
|
||||
# The profile script should exercise the functionality to be included
|
||||
# in the profile feedback.
|
||||
|
||||
profiledbuild:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
$(MOZ_MAKE) MOZ_PROFILE_GENERATE=1
|
||||
OBJDIR=${OBJDIR} $(PROFILE_GEN_SCRIPT)
|
||||
$(MOZ_MAKE) clobber_all
|
||||
$(MOZ_MAKE) MOZ_PROFILE_USE=1
|
||||
find $(OBJDIR) -name "*.da" -exec rm {} \;
|
||||
|
||||
####################################
|
||||
# Other targets
|
||||
|
||||
# Pass these target onto the real build system
|
||||
install export libs clean realclean distclean alldep:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
$(MOZ_MAKE) $@
|
||||
|
||||
cleansrcdir:
|
||||
@cd $(TOPSRCDIR); \
|
||||
if [ -f webshell/embed/gtk/Makefile ]; then \
|
||||
$(MAKE) -C webshell/embed/gtk distclean; \
|
||||
fi; \
|
||||
if [ -f Makefile ]; then \
|
||||
$(MAKE) distclean ; \
|
||||
else \
|
||||
echo "Removing object files from srcdir..."; \
|
||||
rm -fr `find . -type d \( -name .deps -print -o -name CVS \
|
||||
-o -exec test ! -d {}/CVS \; \) -prune \
|
||||
-o \( -name '*.[ao]' -o -name '*.so' \) -type f -print`; \
|
||||
build/autoconf/clean-config.sh; \
|
||||
fi;
|
||||
|
||||
# (! IS_FIRST_CHECKOUT)
|
||||
endif
|
||||
|
||||
echo_objdir:
|
||||
@echo $(OBJDIR)
|
||||
|
||||
.PHONY: checkout real_checkout depend build export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure
|
||||
305
mozilla/content/xul/content/src/nsRDFDOMNodeList.cpp
Normal file
305
mozilla/content/xul/content/src/nsRDFDOMNodeList.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Helper class to implement the nsIDOMNodeList interface.
|
||||
|
||||
XXX It's probably wrong in some sense, as it uses the "naked"
|
||||
content interface to look for kids. (I assume in general this is
|
||||
bad because there may be pseudo-elements created for presentation
|
||||
that aren't visible to the DOM.)
|
||||
|
||||
*/
|
||||
|
||||
#include "nsDOMCID.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIDOMScriptObjectFactory.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsRDFDOMNodeList.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// GUID definitions
|
||||
|
||||
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
|
||||
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
|
||||
static NS_DEFINE_IID(kIDOMScriptObjectFactoryIID, NS_IDOM_SCRIPT_OBJECT_FACTORY_IID);
|
||||
|
||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
class RDFHTMLCollectionImpl : public nsIDOMHTMLCollection
|
||||
{
|
||||
private:
|
||||
nsRDFDOMNodeList* mOuter;
|
||||
|
||||
public:
|
||||
RDFHTMLCollectionImpl(nsRDFDOMNodeList* aOuter);
|
||||
virtual ~RDFHTMLCollectionImpl();
|
||||
|
||||
// nsISupports interface
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aResult);
|
||||
|
||||
// nsIDOMHTMLCollection interface
|
||||
NS_DECL_IDOMHTMLCOLLECTION
|
||||
};
|
||||
|
||||
|
||||
RDFHTMLCollectionImpl::RDFHTMLCollectionImpl(nsRDFDOMNodeList* aOuter)
|
||||
: mOuter(aOuter)
|
||||
{
|
||||
}
|
||||
|
||||
RDFHTMLCollectionImpl::~RDFHTMLCollectionImpl(void)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
RDFHTMLCollectionImpl::AddRef(void)
|
||||
{
|
||||
return mOuter->AddRef();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
RDFHTMLCollectionImpl::Release(void)
|
||||
{
|
||||
return mOuter->Release();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RDFHTMLCollectionImpl::QueryInterface(REFNSIID aIID, void** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (aIID.Equals(nsIDOMHTMLCollection::GetIID())) {
|
||||
*aResult = NS_STATIC_CAST(nsIDOMHTMLCollection*, this);
|
||||
NS_ADDREF(this);
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
return mOuter->QueryInterface(aIID, aResult);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
RDFHTMLCollectionImpl::GetLength(PRUint32* aLength)
|
||||
{
|
||||
return mOuter->GetLength(aLength);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
RDFHTMLCollectionImpl::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
return mOuter->Item(aIndex, aReturn);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
RDFHTMLCollectionImpl::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("write me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// ctors & dtors
|
||||
|
||||
nsRDFDOMNodeList::nsRDFDOMNodeList(void)
|
||||
: mInner(nsnull),
|
||||
mElements(nsnull),
|
||||
mScriptObject(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsRDFDOMNodeList::~nsRDFDOMNodeList(void)
|
||||
{
|
||||
NS_IF_RELEASE(mElements);
|
||||
delete mInner;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRDFDOMNodeList::Create(nsRDFDOMNodeList** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsRDFDOMNodeList* list = new nsRDFDOMNodeList();
|
||||
if (! list)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = list->Init())) {
|
||||
delete list;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ADDREF(list);
|
||||
*aResult = list;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports interface
|
||||
|
||||
NS_IMPL_ADDREF(nsRDFDOMNodeList);
|
||||
NS_IMPL_RELEASE(nsRDFDOMNodeList);
|
||||
|
||||
nsresult
|
||||
nsRDFDOMNodeList::QueryInterface(REFNSIID aIID, void** aResult)
|
||||
{
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
||||
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (aIID.Equals(nsIDOMNodeList::GetIID()) ||
|
||||
aIID.Equals(kISupportsIID)) {
|
||||
*aResult = NS_STATIC_CAST(nsIDOMNodeList*, this);
|
||||
NS_ADDREF(this);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(kIScriptObjectOwnerIID)) {
|
||||
*aResult = NS_STATIC_CAST(nsIScriptObjectOwner*, this);
|
||||
NS_ADDREF(this);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (aIID.Equals(nsIDOMHTMLCollection::GetIID())) {
|
||||
// Aggregate this interface
|
||||
if (! mInner) {
|
||||
if (! (mInner = new RDFHTMLCollectionImpl(this)))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return mInner->QueryInterface(aIID, aResult);
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsIDOMNodeList interface
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFDOMNodeList::GetLength(PRUint32* aLength)
|
||||
{
|
||||
NS_ASSERTION(aLength != nsnull, "null ptr");
|
||||
if (! aLength)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aLength = mElements->Count();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFDOMNodeList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
NS_PRECONDITION(aReturn != nsnull, "null ptr");
|
||||
if (! aReturn)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_PRECONDITION(aIndex < (PRUint32) mElements->Count(), "invalid arg");
|
||||
if (aIndex >= (PRUint32) mElements->Count())
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// Cast is okay because we're in a closed system.
|
||||
*aReturn = (nsIDOMNode*) mElements->ElementAt(aIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsIScriptObjectOwner interface
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFDOMNodeList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsIScriptGlobalObject* global = aContext->GetGlobalObject();
|
||||
|
||||
if (nsnull == mScriptObject) {
|
||||
nsIDOMScriptObjectFactory *factory;
|
||||
|
||||
if (NS_SUCCEEDED(rv = nsServiceManager::GetService(kDOMScriptObjectFactoryCID,
|
||||
kIDOMScriptObjectFactoryIID,
|
||||
(nsISupports **)&factory))) {
|
||||
rv = factory->NewScriptHTMLCollection(aContext,
|
||||
(nsISupports*)(nsIDOMNodeList*)this,
|
||||
global,
|
||||
(void**)&mScriptObject);
|
||||
|
||||
nsServiceManager::ReleaseService(kDOMScriptObjectFactoryCID, factory);
|
||||
}
|
||||
}
|
||||
*aScriptObject = mScriptObject;
|
||||
|
||||
NS_RELEASE(global);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFDOMNodeList::SetScriptObject(void* aScriptObject)
|
||||
{
|
||||
mScriptObject = aScriptObject;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation methods
|
||||
|
||||
nsresult
|
||||
nsRDFDOMNodeList::Init(void)
|
||||
{
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = NS_NewISupportsArray(&mElements))) {
|
||||
NS_ERROR("unable to create elements array");
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRDFDOMNodeList::AppendNode(nsIDOMNode* aNode)
|
||||
{
|
||||
NS_PRECONDITION(aNode != nsnull, "null ptr");
|
||||
if (! aNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
return mElements->AppendElement(aNode);
|
||||
}
|
||||
58
mozilla/content/xul/content/src/nsRDFDOMNodeList.h
Normal file
58
mozilla/content/xul/content/src/nsRDFDOMNodeList.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsRDFDOMNodeList_h__
|
||||
#define nsRDFDOMNodeList_h__
|
||||
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
class nsIDOMNode;
|
||||
class nsISupportsArray;
|
||||
|
||||
class nsRDFDOMNodeList : public nsIDOMNodeList,
|
||||
public nsIScriptObjectOwner
|
||||
{
|
||||
private:
|
||||
nsISupports* mInner;
|
||||
nsISupportsArray* mElements;
|
||||
void* mScriptObject;
|
||||
|
||||
nsRDFDOMNodeList(void);
|
||||
nsresult Init(void);
|
||||
|
||||
public:
|
||||
static nsresult Create(nsRDFDOMNodeList** aResult);
|
||||
virtual ~nsRDFDOMNodeList(void);
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIDOMNodeList interface
|
||||
NS_DECL_IDOMNODELIST
|
||||
|
||||
// nsIScriptObjectOwner interface
|
||||
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
|
||||
NS_IMETHOD SetScriptObject(void* aScriptObject);
|
||||
|
||||
// Implementation methods
|
||||
nsresult AppendNode(nsIDOMNode* aNode);
|
||||
};
|
||||
|
||||
#endif // nsRDFDOMNodeList_h__
|
||||
|
||||
144
mozilla/content/xul/content/src/nsXULAttributes.cpp
Normal file
144
mozilla/content/xul/content/src/nsXULAttributes.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
A helper class used to implement attributes.
|
||||
|
||||
*/
|
||||
|
||||
#include "nsXULAttributes.h"
|
||||
#include "nsICSSParser.h"
|
||||
#include "nsIURL.h"
|
||||
|
||||
const PRUnichar kNullCh = PRUnichar('\0');
|
||||
|
||||
static void ParseClasses(const nsString& aClassString, nsClassList** aClassList)
|
||||
{
|
||||
NS_ASSERTION(nsnull == *aClassList, "non null start list");
|
||||
|
||||
nsAutoString classStr(aClassString); // copy to work buffer
|
||||
classStr.Append(kNullCh); // put an extra null at the end
|
||||
|
||||
PRUnichar* start = (PRUnichar*)(const PRUnichar*)classStr;
|
||||
PRUnichar* end = start;
|
||||
|
||||
while (kNullCh != *start) {
|
||||
while ((kNullCh != *start) && nsString::IsSpace(*start)) { // skip leading space
|
||||
start++;
|
||||
}
|
||||
end = start;
|
||||
|
||||
while ((kNullCh != *end) && (PR_FALSE == nsString::IsSpace(*end))) { // look for space or end
|
||||
end++;
|
||||
}
|
||||
*end = kNullCh; // end string here
|
||||
|
||||
if (start < end) {
|
||||
*aClassList = new nsClassList(NS_NewAtom(start));
|
||||
aClassList = &((*aClassList)->mNext);
|
||||
}
|
||||
|
||||
start = ++end;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULAttributes::GetClasses(nsVoidArray& aArray) const
|
||||
{
|
||||
aArray.Clear();
|
||||
const nsClassList* classList = mClassList;
|
||||
while (nsnull != classList) {
|
||||
aArray.AppendElement(classList->mAtom); // NOTE atom is not addrefed
|
||||
classList = classList->mNext;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULAttributes::HasClass(nsIAtom* aClass) const
|
||||
{
|
||||
const nsClassList* classList = mClassList;
|
||||
while (nsnull != classList) {
|
||||
if (classList->mAtom == aClass) {
|
||||
return NS_OK;
|
||||
}
|
||||
classList = classList->mNext;
|
||||
}
|
||||
return NS_COMFALSE;
|
||||
}
|
||||
|
||||
nsresult nsXULAttributes::UpdateClassList(const nsString& aValue)
|
||||
{
|
||||
if (mClassList != nsnull)
|
||||
{
|
||||
delete mClassList;
|
||||
mClassList = nsnull;
|
||||
}
|
||||
|
||||
if (aValue != "")
|
||||
ParseClasses(aValue, &mClassList);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXULAttributes::UpdateStyleRule(nsIURL* aDocURL, const nsString& aValue)
|
||||
{
|
||||
if (aValue == "")
|
||||
{
|
||||
// XXX: Removing the rule. Is this sufficient?
|
||||
NS_IF_RELEASE(mStyleRule);
|
||||
mStyleRule = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsICSSParser* css;
|
||||
nsresult result = NS_NewCSSParser(&css);
|
||||
if (NS_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIStyleRule* rule;
|
||||
result = css->ParseDeclarations(aValue, aDocURL, rule);
|
||||
//NS_IF_RELEASE(docURL);
|
||||
|
||||
if ((NS_OK == result) && (nsnull != rule)) {
|
||||
mStyleRule = rule; //Addrefed already during parse, so don't need to addref again.
|
||||
//result = SetHTMLAttribute(aAttribute, nsHTMLValue(rule), aNotify);
|
||||
}
|
||||
//else {
|
||||
// result = SetHTMLAttribute(aAttribute, nsHTMLValue(aValue), aNotify);
|
||||
//}
|
||||
NS_RELEASE(css);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXULAttributes::GetInlineStyleRule(nsIStyleRule*& aRule)
|
||||
{
|
||||
nsresult result = NS_ERROR_NULL_POINTER;
|
||||
if (mStyleRule != nsnull)
|
||||
{
|
||||
aRule = mStyleRule;
|
||||
NS_ADDREF(aRule);
|
||||
result = NS_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
128
mozilla/content/xul/content/src/nsXULAttributes.h
Normal file
128
mozilla/content/xul/content/src/nsXULAttributes.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
A helper class used to implement attributes.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef nsXULAttributes_h__
|
||||
#define nsXULAttributes_h__
|
||||
|
||||
#include "nsIStyleRule.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
class nsIURL;
|
||||
|
||||
struct nsClassList {
|
||||
nsClassList(nsIAtom* aAtom)
|
||||
: mAtom(aAtom),
|
||||
mNext(nsnull)
|
||||
{
|
||||
}
|
||||
nsClassList(const nsClassList& aCopy)
|
||||
: mAtom(aCopy.mAtom),
|
||||
mNext(nsnull)
|
||||
{
|
||||
NS_ADDREF(mAtom);
|
||||
if (nsnull != aCopy.mNext) {
|
||||
mNext = new nsClassList(*(aCopy.mNext));
|
||||
}
|
||||
}
|
||||
~nsClassList(void)
|
||||
{
|
||||
NS_RELEASE(mAtom);
|
||||
if (nsnull != mNext) {
|
||||
delete mNext;
|
||||
}
|
||||
}
|
||||
|
||||
nsIAtom* mAtom;
|
||||
nsClassList* mNext;
|
||||
};
|
||||
|
||||
struct nsXULAttribute
|
||||
{
|
||||
nsXULAttribute(PRInt32 aNameSpaceID, nsIAtom* aName, const nsString& aValue)
|
||||
{
|
||||
mNameSpaceID = aNameSpaceID;
|
||||
NS_IF_ADDREF(aName);
|
||||
mName = aName;
|
||||
mValue = aValue;
|
||||
}
|
||||
|
||||
~nsXULAttribute()
|
||||
{
|
||||
NS_IF_RELEASE(mName);
|
||||
}
|
||||
|
||||
PRInt32 mNameSpaceID;
|
||||
nsIAtom* mName;
|
||||
nsString mValue;
|
||||
};
|
||||
|
||||
class nsXULAttributes
|
||||
{
|
||||
public:
|
||||
nsXULAttributes()
|
||||
: mClassList(nsnull), mStyleRule(nsnull)
|
||||
{
|
||||
mAttributes = new nsVoidArray();
|
||||
}
|
||||
|
||||
~nsXULAttributes(void)
|
||||
{
|
||||
if (nsnull != mAttributes) {
|
||||
PRInt32 count = mAttributes->Count();
|
||||
PRInt32 index;
|
||||
for (index = 0; index < count; index++) {
|
||||
nsXULAttribute* attr = (nsXULAttribute*)mAttributes->ElementAt(index);
|
||||
delete attr;
|
||||
}
|
||||
}
|
||||
delete mAttributes;
|
||||
}
|
||||
|
||||
// VoidArray Helpers
|
||||
PRInt32 Count() { return mAttributes->Count(); };
|
||||
nsXULAttribute* ElementAt(PRInt32 i) { return (nsXULAttribute*)mAttributes->ElementAt(i); };
|
||||
void AppendElement(nsXULAttribute* aElement) { mAttributes->AppendElement((void*)aElement); };
|
||||
void RemoveElementAt(PRInt32 index) { mAttributes->RemoveElementAt(index); };
|
||||
|
||||
// Style Helpers
|
||||
nsresult GetClasses(nsVoidArray& aArray) const;
|
||||
nsresult HasClass(nsIAtom* aClass) const;
|
||||
|
||||
nsresult UpdateClassList(const nsString& aValue);
|
||||
nsresult UpdateStyleRule(nsIURL* aDocURL, const nsString& aValue);
|
||||
nsresult GetInlineStyleRule(nsIStyleRule*& aRule);
|
||||
|
||||
public:
|
||||
nsClassList* mClassList;
|
||||
nsIStyleRule* mStyleRule;
|
||||
nsVoidArray* mAttributes;
|
||||
};
|
||||
|
||||
|
||||
#endif // nsXULAttributes_h__
|
||||
|
||||
2600
mozilla/content/xul/content/src/nsXULElement.cpp
Normal file
2600
mozilla/content/xul/content/src/nsXULElement.cpp
Normal file
File diff suppressed because it is too large
Load Diff
71
mozilla/content/xul/content/src/nsXULElement.h
Normal file
71
mozilla/content/xul/content/src/nsXULElement.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsXULElement_h__
|
||||
#define nsXULElement_h__
|
||||
|
||||
#include "nsIDOMXULElement.h"
|
||||
class nsXULElement : public nsISupports
|
||||
{
|
||||
protected:
|
||||
nsIDOMXULElement* mOuter;
|
||||
nsXULElement(nsIDOMXULElement* aOuter) : mOuter(aOuter) {}
|
||||
|
||||
public:
|
||||
virtual ~nsXULElement() {};
|
||||
|
||||
// nsISupports interface. Subclasses should use the
|
||||
// NS_DECL/IMPL_ISUPPORTS_INHERITED macros to implement the
|
||||
// nsISupports interface.
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() {
|
||||
return mOuter->AddRef();
|
||||
}
|
||||
|
||||
NS_IMETHOD_(nsrefcnt) Release() {
|
||||
return mOuter->Release();
|
||||
}
|
||||
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aResult) {
|
||||
return mOuter->QueryInterface(aIID, aResult);
|
||||
}
|
||||
};
|
||||
|
||||
#define NS_IMPL_XULELEMENT_ISUPPORTS \
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { \
|
||||
return mOuter->AddRef(); \
|
||||
} \
|
||||
\
|
||||
NS_IMETHOD_(nsrefcnt) Release() { \
|
||||
return mOuter->Release(); \
|
||||
} \
|
||||
\
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aResult) { \
|
||||
if (aIID.Equals(GetDOMIID())) { \
|
||||
*aResult = this; \
|
||||
NS_ADDREF(this); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
else { \
|
||||
return mOuter->QueryInterface(aIID, aResult); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // nsXULElement_h__
|
||||
55
mozilla/content/xul/content/src/nsXULTreeElement.cpp
Normal file
55
mozilla/content/xul/content/src/nsXULTreeElement.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsXULTreeElement.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsXULTreeElement, nsXULElement, nsIDOMXULTreeElement);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeElement::GetDatabase(nsIRDFCompositeDataSource** aDatabase)
|
||||
{
|
||||
NS_PRECONDITION(aDatabase != nsnull, "null ptr");
|
||||
if (! aDatabase)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_IF_ADDREF(mDatabase);
|
||||
*aDatabase = mDatabase;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeElement::SetDatabase(nsIRDFCompositeDataSource* aDatabase)
|
||||
{
|
||||
// XXX maybe someday you'll be allowed to change it.
|
||||
NS_PRECONDITION(mDatabase == nsnull, "already initialized");
|
||||
if (mDatabase)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
mDatabase = aDatabase;
|
||||
NS_IF_ADDREF(aDatabase);
|
||||
|
||||
// XXX reconstruct the entire tree now!
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
60
mozilla/content/xul/content/src/nsXULTreeElement.h
Normal file
60
mozilla/content/xul/content/src/nsXULTreeElement.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsXULTreeElement_h__
|
||||
#define nsXULTreeElement_h__
|
||||
|
||||
#include "nsXULElement.h"
|
||||
#include "nsIDOMXULTreeElement.h"
|
||||
#include "nsIRDFCompositeDataSource.h"
|
||||
|
||||
class nsXULTreeElement : public nsXULElement,
|
||||
public nsIDOMXULTreeElement
|
||||
{
|
||||
private:
|
||||
nsIRDFCompositeDataSource* mDatabase;
|
||||
|
||||
public:
|
||||
nsXULTreeElement(nsIDOMXULElement* aOuter)
|
||||
: nsXULElement(aOuter),
|
||||
mDatabase(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode interface
|
||||
NS_FORWARD_IDOMNODE(mOuter->);
|
||||
|
||||
// nsIDOMElement interface
|
||||
NS_FORWARD_IDOMELEMENT(mOuter->);
|
||||
|
||||
// nsIDOMXULElement interface
|
||||
NS_FORWARD_IDOMXULELEMENT(mOuter->);
|
||||
|
||||
// nsIDOMXULTreeElement interface
|
||||
NS_DECL_IDOMXULTREEELEMENT
|
||||
|
||||
virtual const nsIID& GetDOMIID() {
|
||||
return nsIDOMXULTreeElement::GetIID();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // nsXULTreeElement_h__
|
||||
3186
mozilla/content/xul/document/src/nsXULDocument.cpp
Normal file
3186
mozilla/content/xul/document/src/nsXULDocument.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1214
mozilla/content/xul/templates/src/nsXULSortService.cpp
Normal file
1214
mozilla/content/xul/templates/src/nsXULSortService.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1671
mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp
Normal file
1671
mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
35
mozilla/db/mdb/Makefile.in
Normal file
35
mozilla/db/mdb/Makefile.in
Normal file
@@ -0,0 +1,35 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
# no src yet, or tests or build
|
||||
DIRS = public
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
# DIRS += tests
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
24
mozilla/db/mdb/makefile.win
Normal file
24
mozilla/db/mdb/makefile.win
Normal file
@@ -0,0 +1,24 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
#tests src no tests or src yet
|
||||
|
||||
DIRS=public
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
32
mozilla/db/mdb/public/Makefile.in
Normal file
32
mozilla/db/mdb/public/Makefile.in
Normal file
@@ -0,0 +1,32 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
EXPORTS= \
|
||||
mdb.h \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
32
mozilla/db/mdb/public/makefile.win
Normal file
32
mozilla/db/mdb/public/makefile.win
Normal file
@@ -0,0 +1,32 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
IDLSRCS = \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
mdb.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE=mailnews
|
||||
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
1910
mozilla/db/mdb/public/mdb.h
Normal file
1910
mozilla/db/mdb/public/mdb.h
Normal file
File diff suppressed because it is too large
Load Diff
30
mozilla/db/mork/Makefile.in
Normal file
30
mozilla/db/mork/Makefile.in
Normal file
@@ -0,0 +1,30 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = src # tests public
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
24
mozilla/db/mork/makefile.win
Normal file
24
mozilla/db/mork/makefile.win
Normal file
@@ -0,0 +1,24 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
#tests no tests yet or public yet
|
||||
|
||||
DIRS=src
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
86
mozilla/db/mork/src/Makefile.in
Normal file
86
mozilla/db/mork/src/Makefile.in
Normal file
@@ -0,0 +1,86 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = mailnews
|
||||
LIBRARY_NAME=mork
|
||||
|
||||
EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
orkinCell.cpp\
|
||||
orkinEnv.cpp\
|
||||
orkinFactory.cpp\
|
||||
orkinHeap.cpp\
|
||||
orkinPortTableCursor.cpp\
|
||||
orkinRow.cpp\
|
||||
orkinRowCellCursor.cpp\
|
||||
orkinStore.cpp\
|
||||
orkinTable.cpp\
|
||||
orkinTableRowCursor.cpp\
|
||||
orkinThumb.cpp\
|
||||
morkArray.cpp\
|
||||
morkAtom.cpp\
|
||||
morkAtomMap.cpp\
|
||||
morkAtomSpace.cpp\
|
||||
morkBlob.cpp\
|
||||
morkBuilder.cpp\
|
||||
morkCell.cpp\
|
||||
morkCellObject.cpp\
|
||||
morkConfig.cpp\
|
||||
morkCursor.cpp \
|
||||
morkDeque.cpp\
|
||||
morkEnv.cpp\
|
||||
morkFactory.cpp\
|
||||
morkFile.cpp\
|
||||
morkHandle.cpp\
|
||||
morkIntMap.cpp\
|
||||
morkMap.cpp\
|
||||
morkNode.cpp\
|
||||
morkNodeMap.cpp\
|
||||
morkObject.cpp\
|
||||
morkParser.cpp\
|
||||
morkPool.cpp\
|
||||
morkRow.cpp\
|
||||
morkRowCellCursor.cpp\
|
||||
morkRowMap.cpp\
|
||||
morkRowObject.cpp\
|
||||
morkRowSpace.cpp\
|
||||
morkSink.cpp\
|
||||
morkSpace.cpp\
|
||||
morkStore.cpp\
|
||||
morkStream.cpp\
|
||||
morkTable.cpp\
|
||||
morkPortTableCursor.cpp\
|
||||
morkTableRowCursor.cpp\
|
||||
morkThumb.cpp\
|
||||
morkWriter.cpp\
|
||||
morkYarn.cpp\
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
148
mozilla/db/mork/src/makefile.win
Normal file
148
mozilla/db/mork/src/makefile.win
Normal file
@@ -0,0 +1,148 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
LINCS= -I$(PUBLIC)\xpcom -I$(PUBLIC)\mailnews
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
LIBRARY_NAME=mork
|
||||
MODULE= mailnews
|
||||
REQUIRES=rdf
|
||||
|
||||
DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPPSRCS= orkinCell.cpp\
|
||||
orkinEnv.cpp\
|
||||
orkinFactory.cpp\
|
||||
orkinHeap.cpp\
|
||||
orkinPortTableCursor.cpp\
|
||||
orkinRow.cpp\
|
||||
orkinRowCellCursor.cpp\
|
||||
orkinStore.cpp\
|
||||
orkinTable.cpp\
|
||||
orkinTableRowCursor.cpp\
|
||||
orkinThumb.cpp\
|
||||
morkArray.cpp\
|
||||
morkAtom.cpp\
|
||||
morkAtomMap.cpp\
|
||||
morkAtomSpace.cpp\
|
||||
morkBlob.cpp\
|
||||
morkBuilder.cpp\
|
||||
morkCell.cpp\
|
||||
morkCellObject.cpp\
|
||||
morkConfig.cpp\
|
||||
morkCursor.cpp \
|
||||
morkDeque.cpp\
|
||||
morkEnv.cpp\
|
||||
morkFactory.cpp\
|
||||
morkFile.cpp\
|
||||
morkHandle.cpp\
|
||||
morkIntMap.cpp\
|
||||
morkMap.cpp\
|
||||
morkNode.cpp\
|
||||
morkNodeMap.cpp\
|
||||
morkObject.cpp\
|
||||
morkParser.cpp\
|
||||
morkPool.cpp\
|
||||
morkRow.cpp\
|
||||
morkRowCellCursor.cpp\
|
||||
morkRowMap.cpp\
|
||||
morkRowObject.cpp\
|
||||
morkRowSpace.cpp\
|
||||
morkSink.cpp\
|
||||
morkSpace.cpp\
|
||||
morkStore.cpp\
|
||||
morkStream.cpp\
|
||||
morkTable.cpp\
|
||||
morkPortTableCursor.cpp\
|
||||
morkTableRowCursor.cpp\
|
||||
morkThumb.cpp\
|
||||
morkWriter.cpp\
|
||||
morkYarn.cpp\
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS= .\$(OBJDIR)\orkinCell.obj\
|
||||
.\$(OBJDIR)\orkinEnv.obj\
|
||||
.\$(OBJDIR)\orkinFactory.obj\
|
||||
.\$(OBJDIR)\orkinHeap.obj\
|
||||
.\$(OBJDIR)\orkinPortTableCursor.obj\
|
||||
.\$(OBJDIR)\orkinRow.obj\
|
||||
.\$(OBJDIR)\orkinRowCellCursor.obj\
|
||||
.\$(OBJDIR)\orkinStore.obj\
|
||||
.\$(OBJDIR)\orkinTable.obj\
|
||||
.\$(OBJDIR)\orkinTableRowCursor.obj\
|
||||
.\$(OBJDIR)\orkinThumb.obj\
|
||||
.\$(OBJDIR)\morkArray.obj \
|
||||
.\$(OBJDIR)\morkAtom.obj \
|
||||
.\$(OBJDIR)\morkAtomMap.obj \
|
||||
.\$(OBJDIR)\morkAtomSpace.obj \
|
||||
.\$(OBJDIR)\morkBlob.obj\
|
||||
.\$(OBJDIR)\morkBuilder.obj\
|
||||
.\$(OBJDIR)\morkCell.obj\
|
||||
.\$(OBJDIR)\morkCellObject.obj\
|
||||
.\$(OBJDIR)\morkConfig.obj\
|
||||
.\$(OBJDIR)\morkCursor.obj\
|
||||
.\$(OBJDIR)\morkDeque.obj\
|
||||
.\$(OBJDIR)\morkEnv.obj\
|
||||
.\$(OBJDIR)\morkFactory.obj\
|
||||
.\$(OBJDIR)\morkFile.obj\
|
||||
.\$(OBJDIR)\morkHandle.obj\
|
||||
.\$(OBJDIR)\morkIntMap.obj\
|
||||
.\$(OBJDIR)\morkMap.obj\
|
||||
.\$(OBJDIR)\morkNode.obj\
|
||||
.\$(OBJDIR)\morkNodeMap.obj\
|
||||
.\$(OBJDIR)\morkObject.obj\
|
||||
.\$(OBJDIR)\morkParser.obj\
|
||||
.\$(OBJDIR)\morkPool.obj\
|
||||
.\$(OBJDIR)\morkPortTableCursor.obj\
|
||||
.\$(OBJDIR)\morkRow.obj\
|
||||
.\$(OBJDIR)\morkRowCellCursor.obj\
|
||||
.\$(OBJDIR)\morkRowMap.obj\
|
||||
.\$(OBJDIR)\morkRowObject.obj\
|
||||
.\$(OBJDIR)\morkRowSpace.obj\
|
||||
.\$(OBJDIR)\morkSink.obj\
|
||||
.\$(OBJDIR)\morkSpace.obj\
|
||||
.\$(OBJDIR)\morkStore.obj\
|
||||
.\$(OBJDIR)\morkStream.obj\
|
||||
.\$(OBJDIR)\morkTable.obj\
|
||||
.\$(OBJDIR)\morkTableRowCursor.obj\
|
||||
.\$(OBJDIR)\morkThumb.obj\
|
||||
.\$(OBJDIR)\morkWriter.obj\
|
||||
.\$(OBJDIR)\morkYarn.obj\
|
||||
$(NULL)
|
||||
|
||||
|
||||
EXPORTS= \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
$(DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
193
mozilla/db/mork/src/mork.h
Normal file
193
mozilla/db/mork/src/mork.h
Normal file
@@ -0,0 +1,193 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORK_
|
||||
#define _MORK_ 1
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
// { %%%%% begin disable unused param warnings %%%%%
|
||||
#define MORK_USED_1(x) (void)(&x)
|
||||
#define MORK_USED_2(x,y) (void)(&x,&y)
|
||||
#define MORK_USED_3(x,y,z) (void)(&x,&y,&z)
|
||||
#define MORK_USED_4(w,x,y,z) (void)(&w,&x,&y,&z)
|
||||
// } %%%%% end disable unused param warnings %%%%%
|
||||
|
||||
// { %%%%% begin macro for finding class member offset %%%%%
|
||||
|
||||
/*| OffsetOf: the unsigned integer offset of a class or struct
|
||||
**| field from the beginning of that class or struct. This is
|
||||
**| the same as the similarly named public domain IronDoc macro,
|
||||
**| and is also the same as another macro appearing in stdlib.h.
|
||||
**| We want these offsets so we can correctly convert pointers
|
||||
**| to member slots back into pointers to enclosing objects, and
|
||||
**| have this exactly match what the compiler thinks is true.
|
||||
**|
|
||||
**|| Bascially we are asking the compiler to determine the offset at
|
||||
**| compile time, and we use the definition of address artithmetic
|
||||
**| to do this. By casting integer zero to a pointer of type obj*,
|
||||
**| we can reference the address of a slot in such an object that
|
||||
**| is hypothetically physically placed at address zero, but without
|
||||
**| actually dereferencing a memory location. The absolute address
|
||||
**| of slot is the same as offset of that slot, when the object is
|
||||
**| placed at address zero.
|
||||
|*/
|
||||
#define mork_OffsetOf(obj,slot) ((unsigned int)&((obj*) 0)->slot)
|
||||
|
||||
// } %%%%% end macro for finding class member offset %%%%%
|
||||
|
||||
// { %%%%% begin specific-size integer scalar typedefs %%%%%
|
||||
typedef unsigned char mork_u1; // make sure this is one byte
|
||||
typedef unsigned short mork_u2; // make sure this is two bytes
|
||||
typedef short mork_i2; // make sure this is two bytes
|
||||
typedef unsigned long mork_u4; // make sure this is four bytes
|
||||
typedef long mork_i4; // make sure this is four bytes
|
||||
typedef long mork_ip; // make sure sizeof(mork_ip) == sizeof(void*)
|
||||
|
||||
typedef mork_u2 mork_base; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_derived; // 2-byte magic class signature slot in object
|
||||
typedef mork_u2 mork_uses; // 2-byte strong uses count
|
||||
typedef mork_u2 mork_refs; // 2-byte actual reference count
|
||||
|
||||
typedef mork_u4 mork_token; // unsigned token for atomized string
|
||||
typedef mork_token mork_scope; // token used to id scope for rows
|
||||
typedef mork_token mork_kind; // token used to id kind for tables
|
||||
typedef mork_token mork_cscode; // token used to id charset names
|
||||
typedef mork_token mork_aid; // token used to id atomize cell values
|
||||
|
||||
typedef mork_token mork_column; // token used to id columns for rows
|
||||
typedef mork_column mork_delta; // mork_column plus mork_change
|
||||
|
||||
typedef mork_u4 mork_magic; // unsigned magic signature
|
||||
|
||||
typedef mork_u4 mork_seed; // unsigned collection change counter
|
||||
typedef mork_u4 mork_count; // unsigned collection member count
|
||||
typedef mork_count mork_num; // synonym for count
|
||||
typedef mork_u4 mork_size; // unsigned physical media size
|
||||
typedef mork_u4 mork_fill; // unsigned logical content size
|
||||
typedef mork_u4 mork_more; // more available bytes for larger buffer
|
||||
|
||||
typedef mork_i4 mork_pos; // negative means "before first" (at zero pos)
|
||||
typedef mork_i4 mork_line; // negative means "before first line in file"
|
||||
|
||||
typedef mork_u1 mork_usage; // 1-byte magic usage signature slot in object
|
||||
typedef mork_u1 mork_access; // 1-byte magic access signature slot in object
|
||||
|
||||
typedef mork_u1 mork_change; // add, cut, put, set, nil
|
||||
|
||||
typedef mork_u1 mork_able; // on, off, asleep (clone IronDoc's fe_able)
|
||||
typedef mork_u1 mork_load; // dirty or clean (clone IronDoc's fe_load)
|
||||
// } %%%%% end specific-size integer scalar typedefs %%%%%
|
||||
|
||||
// { %%%%% begin constants for Mork scalar types %%%%%
|
||||
#define morkAble_kEnabled ((mork_able) 0x55) /* same as IronDoc constant */
|
||||
#define morkAble_kDisabled ((mork_able) 0xAA) /* same as IronDoc constant */
|
||||
#define morkAble_kAsleep ((mork_able) 0x5A) /* same as IronDoc constant */
|
||||
|
||||
#define morkChange_kAdd 'a' /* add member */
|
||||
#define morkChange_kCut 'c' /* cut member */
|
||||
#define morkChange_kPut 'p' /* put member */
|
||||
#define morkChange_kSet 's' /* set all members */
|
||||
#define morkChange_kNil 0 /* no change in this member */
|
||||
|
||||
#define morkLoad_kDirty ((mork_load) 0xDD) /* same as IronDoc constant */
|
||||
#define morkLoad_kClean ((mork_load) 0x22) /* same as IronDoc constant */
|
||||
|
||||
#define morkAccess_kOpen 'o'
|
||||
#define morkAccess_kClosing 'c'
|
||||
#define morkAccess_kShut 's'
|
||||
#define morkAccess_kDead 'd'
|
||||
// } %%%%% end constants for Mork scalar types %%%%%
|
||||
|
||||
// { %%%%% begin non-specific-size integer scalar typedefs %%%%%
|
||||
typedef int mork_char; // nominal type for ints used to hold input byte
|
||||
#define morkChar_IsWhite(c) \
|
||||
((c) == 0xA || (c) == 0x9 || (c) == 0xD || (c) == ' ')
|
||||
// } %%%%% end non-specific-size integer scalar typedefs %%%%%
|
||||
|
||||
// { %%%%% begin mdb-driven scalar typedefs %%%%%
|
||||
// easier to define bool exactly the same as mdb:
|
||||
typedef mdb_bool mork_bool; // unsigned byte with zero=false, nonzero=true
|
||||
|
||||
/* canonical boolean constants provided only for code clarity: */
|
||||
#define morkBool_kTrue ((mork_bool) 1) /* actually any nonzero means true */
|
||||
#define morkBool_kFalse ((mork_bool) 0) /* only zero means false */
|
||||
|
||||
// mdb clients can assign these, so we cannot pick maximum size:
|
||||
typedef mdb_id mork_id; // unsigned object identity in a scope
|
||||
typedef mork_id mork_rid; // unsigned row identity inside scope
|
||||
typedef mork_id mork_tid; // unsigned table identity inside scope
|
||||
typedef mork_id mork_gid; // unsigned group identity without any scope
|
||||
|
||||
// we only care about neg, zero, pos -- so we don't care about size:
|
||||
typedef mdb_order mork_order; // neg:lessthan, zero:equalto, pos:greaterthan
|
||||
// } %%%%% end mdb-driven scalar typedefs %%%%%
|
||||
|
||||
#define morkId_kMinusOne ((mdb_id) -1)
|
||||
|
||||
// { %%%%% begin class forward defines %%%%%
|
||||
// try to put these in alphabetical order for easier examination:
|
||||
class morkAtom;
|
||||
class morkAtomSpace;
|
||||
class morkBookAtom;
|
||||
class morkBuf;
|
||||
class morkBuilder;
|
||||
class morkCell;
|
||||
class morkCellObject;
|
||||
class morkCursor;
|
||||
class morkEnv;
|
||||
class morkFactory;
|
||||
class morkFile;
|
||||
class morkHandle;
|
||||
class morkHandleFace; // just an opaque cookie type
|
||||
class morkHandleFrame;
|
||||
class morkHashArrays;
|
||||
class morkMap;
|
||||
class morkNode;
|
||||
class morkObject;
|
||||
class morkOidAtom;
|
||||
class morkParser;
|
||||
class morkPool;
|
||||
class morkPort;
|
||||
class morkPortTableCursor;
|
||||
class morkRow;
|
||||
class morkRowCellCursor;
|
||||
class morkRowObject;
|
||||
class morkRowSpace;
|
||||
class morkSpace;
|
||||
class morkStore;
|
||||
class morkStream;
|
||||
class morkTable;
|
||||
class morkTableRowCursor;
|
||||
class morkThumb;
|
||||
class morkWriter;
|
||||
// } %%%%% end class forward defines %%%%%
|
||||
|
||||
// include this config file last for platform & environment specific stuff:
|
||||
#ifndef _MORKCONFIG_
|
||||
#include "morkConfig.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORK_ */
|
||||
310
mozilla/db/mork/src/morkArray.cpp
Normal file
310
mozilla/db/mork/src/morkArray.cpp
Normal file
@@ -0,0 +1,310 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#include "morkArray.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkArray::CloseMorkNode(morkEnv* ev) // CloseTable() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseArray(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkArray::~morkArray() // assert CloseTable() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
MORK_ASSERT(mArray_Slots==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkArray::morkArray(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mArray_Slots( 0 )
|
||||
, mArray_Heap( 0 )
|
||||
, mArray_Fill( 0 )
|
||||
, mArray_Size( 0 )
|
||||
, mArray_Seed( (mork_u4) this ) // "random" integer assignment
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mArray_Heap);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( inSize < 3 )
|
||||
inSize = 3;
|
||||
mdb_size byteSize = inSize * sizeof(void*);
|
||||
void** block = 0;
|
||||
ioSlotHeap->Alloc(ev->AsMdbEnv(), byteSize, (void**) &block);
|
||||
if ( block && ev->Good() )
|
||||
{
|
||||
mArray_Slots = block;
|
||||
mArray_Size = inSize;
|
||||
MORK_MEMSET(mArray_Slots, 0, byteSize);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkArray::CloseArray(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( mArray_Heap && mArray_Slots )
|
||||
mArray_Heap->Free(ev->AsMdbEnv(), mArray_Slots);
|
||||
|
||||
mArray_Slots = 0;
|
||||
mArray_Size = 0;
|
||||
mArray_Fill = 0;
|
||||
++mArray_Seed;
|
||||
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mArray_Heap);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkArray::NonArrayTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkArray");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::IndexBeyondEndError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("array index beyond end");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::NilSlotsAddressError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mArray_Slots");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkArray::FillBeyondSizeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mArray_Fill > mArray_Size");
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkArray::Grow(morkEnv* ev, mork_size inNewSize)
|
||||
// Grow() returns true if capacity becomes >= inNewSize and ev->Good()
|
||||
{
|
||||
if ( ev->Good() && inNewSize > mArray_Size ) // make array larger?
|
||||
{
|
||||
if ( mArray_Fill <= mArray_Size ) // fill and size fit the invariant?
|
||||
{
|
||||
if ( inNewSize - mArray_Size < 3 ) // actually want a few more slots?
|
||||
inNewSize = mArray_Size + 3;
|
||||
|
||||
mdb_size newByteSize = inNewSize * sizeof(void*);
|
||||
void** newBlock = 0;
|
||||
mArray_Heap->Alloc(ev->AsMdbEnv(), newByteSize, (void**) &newBlock);
|
||||
if ( newBlock && ev->Good() ) // okay new block?
|
||||
{
|
||||
void** oldSlots = mArray_Slots;
|
||||
void** oldEnd = oldSlots + mArray_Fill;
|
||||
|
||||
void** newSlots = newBlock;
|
||||
void** newEnd = newBlock + inNewSize;
|
||||
|
||||
while ( oldSlots < oldEnd )
|
||||
*newSlots++ = *oldSlots++;
|
||||
|
||||
while ( newSlots < newEnd )
|
||||
*newSlots++ = (void*) 0;
|
||||
|
||||
oldSlots = mArray_Slots;
|
||||
mArray_Size = inNewSize;
|
||||
mArray_Slots = newBlock;
|
||||
mArray_Heap->Free(ev->AsMdbEnv(), oldSlots);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->FillBeyondSizeError(ev);
|
||||
}
|
||||
++mArray_Seed; // always modify seed, since caller intends to add slots
|
||||
return ( ev->Good() && mArray_Size >= inNewSize );
|
||||
}
|
||||
|
||||
void*
|
||||
morkArray::SafeAt(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( inPos < mArray_Fill )
|
||||
return mArray_Slots[ inPos ];
|
||||
else
|
||||
this->IndexBeyondEndError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
return (void*) 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( inPos < mArray_Fill )
|
||||
{
|
||||
mArray_Slots[ inPos ] = ioSlot;
|
||||
++mArray_Seed;
|
||||
}
|
||||
else
|
||||
this->IndexBeyondEndError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
}
|
||||
|
||||
mork_pos
|
||||
morkArray::AppendSlot(morkEnv* ev, void* ioSlot)
|
||||
{
|
||||
mork_pos outPos = -1;
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( this->Grow(ev, fill+1) )
|
||||
{
|
||||
outPos = fill;
|
||||
mArray_Slots[ fill ] = ioSlot;
|
||||
mArray_Fill = fill + 1;
|
||||
// note Grow() increments mArray_Seed
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( this->Grow(ev, fill+1) )
|
||||
{
|
||||
void** slot = mArray_Slots; // the slot vector
|
||||
void** end = slot + fill; // one past the last used array slot
|
||||
slot += inPos; // the slot to be added
|
||||
|
||||
while ( --end >= slot ) // another slot to move upward?
|
||||
end[ 1 ] = *end;
|
||||
|
||||
*slot = ioSlot;
|
||||
mArray_Fill = fill + 1;
|
||||
// note Grow() increments mArray_Seed
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::CutSlot(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
mork_fill fill = mArray_Fill;
|
||||
if ( inPos < fill ) // cutting a slot in the used array portion?
|
||||
{
|
||||
void** slot = mArray_Slots; // the slot vector
|
||||
void** end = slot + fill; // one past the last used array slot
|
||||
slot += inPos; // the slot to be cut
|
||||
|
||||
while ( ++slot < end ) // another slot to move downward?
|
||||
slot[ -1 ] = *slot;
|
||||
|
||||
slot[ -1 ] = 0; // clear the last used slot which is now unused
|
||||
|
||||
// note inPos<fill implies fill>0, so fill-1 must be nonnegative:
|
||||
mArray_Fill = fill - 1;
|
||||
++mArray_Seed;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkArray::CutAllSlots(morkEnv* ev)
|
||||
{
|
||||
if ( mArray_Slots )
|
||||
{
|
||||
if ( mArray_Fill <= mArray_Size )
|
||||
{
|
||||
mdb_size oldByteSize = mArray_Fill * sizeof(void*);
|
||||
MORK_MEMSET(mArray_Slots, 0, oldByteSize);
|
||||
}
|
||||
else
|
||||
this->FillBeyondSizeError(ev);
|
||||
}
|
||||
else
|
||||
this->NilSlotsAddressError(ev);
|
||||
|
||||
++mArray_Seed;
|
||||
mArray_Fill = 0;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
111
mozilla/db/mork/src/morkArray.h
Normal file
111
mozilla/db/mork/src/morkArray.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#define _MORKARRAY_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kArray /*i*/ 0x4179 /* ascii 'Ay' */
|
||||
|
||||
class morkArray : public morkNode { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
void** mArray_Slots; // array of pointers
|
||||
nsIMdbHeap* mArray_Heap; // required heap for allocating mArray_Slots
|
||||
mork_fill mArray_Fill; // logical count of used slots in mArray_Slots
|
||||
mork_size mArray_Size; // physical count of mArray_Slots ( >= Fill)
|
||||
mork_seed mArray_Seed; // change counter for syncing with iterators
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseArray()
|
||||
virtual ~morkArray(); // assert that close executed earlier
|
||||
|
||||
public: // morkArray construction & destruction
|
||||
morkArray(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, mork_size inSize, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseArray(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkArray(const morkArray& other);
|
||||
morkArray& operator=(const morkArray& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsArray() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kArray; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing & errors
|
||||
static void NonArrayTypeError(morkEnv* ev);
|
||||
static void IndexBeyondEndError(morkEnv* ev);
|
||||
static void NilSlotsAddressError(morkEnv* ev);
|
||||
static void FillBeyondSizeError(morkEnv* ev);
|
||||
|
||||
public: // other table row cursor methods
|
||||
|
||||
mork_fill Length() const { return mArray_Fill; }
|
||||
mork_size Capacity() const { return mArray_Size; }
|
||||
|
||||
mork_bool Grow(morkEnv* ev, mork_size inNewSize);
|
||||
// Grow() returns true if capacity becomes >= inNewSize and ev->Good()
|
||||
|
||||
void* At(mork_pos inPos) const { return mArray_Slots[ inPos ]; }
|
||||
void AtPut(mork_pos inPos, void* ioSlot)
|
||||
{ mArray_Slots[ inPos ] = ioSlot; }
|
||||
|
||||
void* SafeAt(morkEnv* ev, mork_pos inPos);
|
||||
void SafeAtPut(morkEnv* ev, mork_pos inPos, void* ioSlot);
|
||||
|
||||
mork_pos AppendSlot(morkEnv* ev, void* ioSlot);
|
||||
void AddSlot(morkEnv* ev, mork_pos inPos, void* ioSlot);
|
||||
void CutSlot(morkEnv* ev, mork_pos inPos);
|
||||
void CutAllSlots(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakArray(morkArray* me,
|
||||
morkEnv* ev, morkArray** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongArray(morkArray* me,
|
||||
morkEnv* ev, morkArray** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKTABLEROWCURSOR_ */
|
||||
504
mozilla/db/mork/src/morkAtom.cpp
Normal file
504
mozilla/db/mork/src/morkAtom.cpp
Normal file
@@ -0,0 +1,504 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
mork_bool
|
||||
morkAtom::GetYarn(mdbYarn* outYarn) const
|
||||
{
|
||||
const void* source = 0;
|
||||
mdb_fill fill = 0;
|
||||
mdb_cscode form = 0;
|
||||
outYarn->mYarn_More = 0;
|
||||
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsWeeBook() )
|
||||
{
|
||||
morkWeeBookAtom* weeBook = (morkWeeBookAtom*) this;
|
||||
source = weeBook->mWeeBookAtom_Body;
|
||||
fill = weeBook->mAtom_Size;
|
||||
}
|
||||
else if ( this->IsBigBook() )
|
||||
{
|
||||
morkBigBookAtom* bigBook = (morkBigBookAtom*) this;
|
||||
source = bigBook->mBigBookAtom_Body;
|
||||
fill = bigBook->mBigBookAtom_Size;
|
||||
form = bigBook->mBigBookAtom_Form;
|
||||
}
|
||||
else if ( this->IsWeeAnon() )
|
||||
{
|
||||
morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) this;
|
||||
source = weeAnon->mWeeAnonAtom_Body;
|
||||
fill = weeAnon->mAtom_Size;
|
||||
}
|
||||
else if ( this->IsBigAnon() )
|
||||
{
|
||||
morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) this;
|
||||
source = bigAnon->mBigAnonAtom_Body;
|
||||
fill = bigAnon->mBigAnonAtom_Size;
|
||||
form = bigAnon->mBigAnonAtom_Form;
|
||||
}
|
||||
}
|
||||
if ( source && fill ) // have an atom with nonempty content?
|
||||
{
|
||||
// if we have too many bytes, and yarn seems growable:
|
||||
if ( fill > outYarn->mYarn_Size && outYarn->mYarn_Grow ) // try grow?
|
||||
(*outYarn->mYarn_Grow)(outYarn, (mdb_size) fill); // request bigger
|
||||
|
||||
mdb_size size = outYarn->mYarn_Size; // max dest size
|
||||
if ( fill > size ) // too much atom content?
|
||||
{
|
||||
outYarn->mYarn_More = size - fill; // extra atom bytes omitted
|
||||
fill = size; // copy no more bytes than size of yarn buffer
|
||||
}
|
||||
void* dest = outYarn->mYarn_Buf; // where bytes are going
|
||||
if ( !dest ) // nil destination address buffer?
|
||||
fill = 0; // we can't write any content at all
|
||||
|
||||
if ( fill ) // anything to copy?
|
||||
MORK_MEMCPY(dest, source, fill); // copy fill bytes to yarn
|
||||
|
||||
outYarn->mYarn_Fill = fill; // tell yarn size of copied content
|
||||
}
|
||||
else // no content to put into the yarn
|
||||
{
|
||||
outYarn->mYarn_Fill = 0; // tell yarn that atom has no bytes
|
||||
}
|
||||
outYarn->mYarn_Form = form; // always update the form slot
|
||||
|
||||
return ( source != 0 );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkAtom::AsBuf(morkBuf& outBuf) const
|
||||
{
|
||||
const morkAtom* atom = this;
|
||||
if ( atom )
|
||||
{
|
||||
if ( atom->IsWeeBook() )
|
||||
{
|
||||
morkWeeBookAtom* weeBook = (morkWeeBookAtom*) atom;
|
||||
outBuf.mBuf_Body = weeBook->mWeeBookAtom_Body;
|
||||
outBuf.mBuf_Fill = weeBook->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigBook() )
|
||||
{
|
||||
morkBigBookAtom* bigBook = (morkBigBookAtom*) atom;
|
||||
outBuf.mBuf_Body = bigBook->mBigBookAtom_Body;
|
||||
outBuf.mBuf_Fill = bigBook->mBigBookAtom_Size;
|
||||
}
|
||||
else if ( atom->IsWeeAnon() )
|
||||
{
|
||||
morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) atom;
|
||||
outBuf.mBuf_Body = weeAnon->mWeeAnonAtom_Body;
|
||||
outBuf.mBuf_Fill = weeAnon->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigAnon() )
|
||||
{
|
||||
morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) atom;
|
||||
outBuf.mBuf_Body = bigAnon->mBigAnonAtom_Body;
|
||||
outBuf.mBuf_Fill = bigAnon->mBigAnonAtom_Size;
|
||||
}
|
||||
else
|
||||
atom = 0; // show desire to put empty content in yarn
|
||||
}
|
||||
|
||||
if ( !atom ) // empty content for yarn?
|
||||
{
|
||||
outBuf.mBuf_Body = 0;
|
||||
outBuf.mBuf_Fill = 0;
|
||||
}
|
||||
return ( atom != 0 );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkAtom::AliasYarn(mdbYarn* outYarn) const
|
||||
{
|
||||
outYarn->mYarn_More = 0;
|
||||
outYarn->mYarn_Form = 0;
|
||||
const morkAtom* atom = this;
|
||||
|
||||
if ( atom )
|
||||
{
|
||||
if ( atom->IsWeeBook() )
|
||||
{
|
||||
morkWeeBookAtom* weeBook = (morkWeeBookAtom*) atom;
|
||||
outYarn->mYarn_Buf = weeBook->mWeeBookAtom_Body;
|
||||
outYarn->mYarn_Fill = weeBook->mAtom_Size;
|
||||
outYarn->mYarn_Size = weeBook->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigBook() )
|
||||
{
|
||||
morkBigBookAtom* bigBook = (morkBigBookAtom*) atom;
|
||||
outYarn->mYarn_Buf = bigBook->mBigBookAtom_Body;
|
||||
outYarn->mYarn_Fill = bigBook->mBigBookAtom_Size;
|
||||
outYarn->mYarn_Size = bigBook->mBigBookAtom_Size;
|
||||
outYarn->mYarn_Form = bigBook->mBigBookAtom_Form;
|
||||
}
|
||||
else if ( atom->IsWeeAnon() )
|
||||
{
|
||||
morkWeeAnonAtom* weeAnon = (morkWeeAnonAtom*) atom;
|
||||
outYarn->mYarn_Buf = weeAnon->mWeeAnonAtom_Body;
|
||||
outYarn->mYarn_Fill = weeAnon->mAtom_Size;
|
||||
outYarn->mYarn_Size = weeAnon->mAtom_Size;
|
||||
}
|
||||
else if ( atom->IsBigAnon() )
|
||||
{
|
||||
morkBigAnonAtom* bigAnon = (morkBigAnonAtom*) atom;
|
||||
outYarn->mYarn_Buf = bigAnon->mBigAnonAtom_Body;
|
||||
outYarn->mYarn_Fill = bigAnon->mBigAnonAtom_Size;
|
||||
outYarn->mYarn_Size = bigAnon->mBigAnonAtom_Size;
|
||||
outYarn->mYarn_Form = bigAnon->mBigAnonAtom_Form;
|
||||
}
|
||||
else
|
||||
atom = 0; // show desire to put empty content in yarn
|
||||
}
|
||||
|
||||
if ( !atom ) // empty content for yarn?
|
||||
{
|
||||
outYarn->mYarn_Buf = 0;
|
||||
outYarn->mYarn_Fill = 0;
|
||||
outYarn->mYarn_Size = 0;
|
||||
// outYarn->mYarn_Grow = 0; // please don't modify the Grow slot
|
||||
}
|
||||
return ( atom != 0 );
|
||||
}
|
||||
|
||||
void
|
||||
morkAtom::MakeCellUseForever(morkEnv* ev)
|
||||
{
|
||||
mAtom_CellUses = morkAtom_kForeverCellUses;
|
||||
}
|
||||
|
||||
mork_u1
|
||||
morkAtom::AddCellUse(morkEnv* ev)
|
||||
{
|
||||
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not already maxed out?
|
||||
++mAtom_CellUses;
|
||||
|
||||
return mAtom_CellUses;
|
||||
}
|
||||
|
||||
mork_u1
|
||||
morkAtom::CutCellUse(morkEnv* ev)
|
||||
{
|
||||
if ( mAtom_CellUses ) // any outstanding uses to cut?
|
||||
{
|
||||
if ( mAtom_CellUses < morkAtom_kMaxCellUses ) // not frozen at max?
|
||||
--mAtom_CellUses;
|
||||
}
|
||||
else
|
||||
this->CellUsesUnderflowWarning(ev);
|
||||
|
||||
return mAtom_CellUses;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::CellUsesUnderflowWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("mAtom_CellUses underflow");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::BadAtomKindError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("bad mAtom_Kind");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::ZeroAidError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("zero atom ID");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkAtom::AtomSizeOverflowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("atom mAtom_Size overflow");
|
||||
}
|
||||
|
||||
void
|
||||
morkOidAtom::InitRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindRowOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
mOidAtom_Oid = inOid; // bitwise copy
|
||||
}
|
||||
|
||||
void
|
||||
morkOidAtom::InitTableOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindTableOid;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
mOidAtom_Oid = inOid; // bitwise copy
|
||||
}
|
||||
|
||||
void
|
||||
morkWeeAnonAtom::InitWeeAnonAtom(morkEnv* ev, const morkBuf& inBuf)
|
||||
{
|
||||
mAtom_Kind = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
if ( inBuf.mBuf_Fill <= morkAtom_kMaxByteSize )
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindWeeAnon;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mAtom_Size = (mork_u1) size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mWeeAnonAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mWeeAnonAtom_Body[ size ] = 0;
|
||||
}
|
||||
else
|
||||
this->AtomSizeOverflowError(ev);
|
||||
}
|
||||
|
||||
void
|
||||
morkBigAnonAtom::InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm)
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindBigAnon;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
mBigAnonAtom_Form = inForm;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mBigAnonAtom_Size = size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mBigAnonAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mBigAnonAtom_Body[ size ] = 0;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkBookAtom::NonBookAtomTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkBookAtom");
|
||||
}
|
||||
|
||||
mork_u4
|
||||
morkBookAtom::HashFormAndBody(morkEnv* ev) const
|
||||
{
|
||||
// This hash is obviously a variation of the dragon book string hash.
|
||||
// (I won't bother to explain or rationalize this usage for you.)
|
||||
|
||||
register mork_u4 outHash = 0; // hash value returned
|
||||
register unsigned char c; // next character
|
||||
register const mork_u1* body; // body of bytes to hash
|
||||
mork_size size = 0; // the number of bytes to hash
|
||||
|
||||
if ( this->IsWeeBook() )
|
||||
{
|
||||
size = mAtom_Size;
|
||||
body = ((const morkWeeBookAtom*) this)->mWeeBookAtom_Body;
|
||||
}
|
||||
else if ( this->IsBigBook() )
|
||||
{
|
||||
size = ((const morkBigBookAtom*) this)->mBigBookAtom_Size;
|
||||
body = ((const morkBigBookAtom*) this)->mBigBookAtom_Body;
|
||||
}
|
||||
else
|
||||
this->NonBookAtomTypeError(ev);
|
||||
|
||||
const mork_u1* end = body + size;
|
||||
while ( body < end )
|
||||
{
|
||||
c = *body++;
|
||||
outHash <<= 4;
|
||||
outHash += c;
|
||||
mork_u4 top = outHash & 0xF0000000L; // top four bits
|
||||
if ( top ) // any of high four bits equal to one?
|
||||
{
|
||||
outHash ^= (top >> 24); // fold down high bits
|
||||
outHash ^= top; // zero top four bits
|
||||
}
|
||||
}
|
||||
|
||||
return outHash;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkBookAtom::EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const
|
||||
{
|
||||
mork_bool outEqual = morkBool_kFalse;
|
||||
|
||||
const mork_u1* body = 0; // body of inAtom bytes to compare
|
||||
mork_size size; // the number of inAtom bytes to compare
|
||||
mork_cscode form; // nominal charset for ioAtom
|
||||
|
||||
if ( inAtom->IsWeeBook() )
|
||||
{
|
||||
size = inAtom->mAtom_Size;
|
||||
body = ((const morkWeeBookAtom*) inAtom)->mWeeBookAtom_Body;
|
||||
form = 0;
|
||||
}
|
||||
else if ( inAtom->IsBigBook() )
|
||||
{
|
||||
size = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Size;
|
||||
body = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Body;
|
||||
form = ((const morkBigBookAtom*) inAtom)->mBigBookAtom_Form;
|
||||
}
|
||||
else
|
||||
inAtom->NonBookAtomTypeError(ev);
|
||||
|
||||
const mork_u1* thisBody = 0; // body of bytes in this to compare
|
||||
mork_size thisSize; // the number of bytes in this to compare
|
||||
mork_cscode thisForm; // nominal charset for this atom
|
||||
|
||||
if ( this->IsWeeBook() )
|
||||
{
|
||||
thisSize = mAtom_Size;
|
||||
thisBody = ((const morkWeeBookAtom*) this)->mWeeBookAtom_Body;
|
||||
thisForm = 0;
|
||||
}
|
||||
else if ( this->IsBigBook() )
|
||||
{
|
||||
thisSize = ((const morkBigBookAtom*) this)->mBigBookAtom_Size;
|
||||
thisBody = ((const morkBigBookAtom*) this)->mBigBookAtom_Body;
|
||||
thisForm = ((const morkBigBookAtom*) this)->mBigBookAtom_Form;
|
||||
}
|
||||
else
|
||||
this->NonBookAtomTypeError(ev);
|
||||
|
||||
if ( body && thisBody && size == thisSize && form == thisForm )
|
||||
outEqual = (MORK_MEMCMP(body, thisBody, size) == 0);
|
||||
|
||||
return outEqual;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
morkBookAtom::CutBookAtomFromSpace(morkEnv* ev)
|
||||
{
|
||||
morkAtomSpace* space = mBookAtom_Space;
|
||||
if ( space )
|
||||
{
|
||||
mBookAtom_Space = 0;
|
||||
space->mAtomSpace_AtomBodies.CutAtom(ev, this);
|
||||
space->mAtomSpace_AtomAids.CutAtom(ev, this);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
morkWeeBookAtom::morkWeeBookAtom(mork_aid inAid)
|
||||
{
|
||||
mAtom_Kind = morkAtom_kKindWeeBook;
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
mAtom_Size = 0;
|
||||
|
||||
mBookAtom_Space = 0;
|
||||
mBookAtom_Id = inAid;
|
||||
|
||||
mWeeBookAtom_Body[ 0 ] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkWeeBookAtom::InitWeeBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
{
|
||||
mAtom_Kind = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
if ( ioSpace )
|
||||
{
|
||||
if ( inAid )
|
||||
{
|
||||
if ( inBuf.mBuf_Fill <= morkAtom_kMaxByteSize )
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindWeeBook;
|
||||
mBookAtom_Space = ioSpace;
|
||||
mBookAtom_Id = inAid;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mAtom_Size = (mork_u1) size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mWeeBookAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mWeeBookAtom_Body[ size ] = 0;
|
||||
}
|
||||
else
|
||||
this->AtomSizeOverflowError(ev);
|
||||
}
|
||||
else
|
||||
this->ZeroAidError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
void
|
||||
morkBigBookAtom::InitBigBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
{
|
||||
mAtom_Kind = 0;
|
||||
mAtom_Change = morkChange_kNil;
|
||||
if ( ioSpace )
|
||||
{
|
||||
if ( inAid )
|
||||
{
|
||||
mAtom_CellUses = 0;
|
||||
mAtom_Kind = morkAtom_kKindBigBook;
|
||||
mAtom_Size = 0;
|
||||
mBookAtom_Space = ioSpace;
|
||||
mBookAtom_Id = inAid;
|
||||
mBigBookAtom_Form = inForm;
|
||||
mork_size size = inBuf.mBuf_Fill;
|
||||
mBigBookAtom_Size = size;
|
||||
if ( size && inBuf.mBuf_Body )
|
||||
MORK_MEMCPY(mBigBookAtom_Body, inBuf.mBuf_Body, size);
|
||||
|
||||
mBigBookAtom_Body[ size ] = 0;
|
||||
}
|
||||
else
|
||||
this->ZeroAidError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
323
mozilla/db/mork/src/morkAtom.h
Normal file
323
mozilla/db/mork/src/morkAtom.h
Normal file
@@ -0,0 +1,323 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#define _MORKATOM_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
#define morkAtom_kMaxByteSize 255 /* max for 8-bit integer */
|
||||
#define morkAtom_kForeverCellUses 0x0FF /* max for 8-bit integer */
|
||||
#define morkAtom_kMaxCellUses 0x07F /* max for 7-bit integer */
|
||||
|
||||
#define morkAtom_kKindWeeAnon 'a' /* means morkWeeAnonAtom subclass */
|
||||
#define morkAtom_kKindBigAnon 'A' /* means morkBigAnonAtom subclass */
|
||||
#define morkAtom_kKindWeeBook 'b' /* means morkWeeBookAtom subclass */
|
||||
#define morkAtom_kKindBigBook 'B' /* means morkBigBookAtom subclass */
|
||||
#define morkAtom_kKindRowOid 'r' /* means morkOidAtom subclass */
|
||||
#define morkAtom_kKindTableOid 't' /* means morkOidAtom subclass */
|
||||
|
||||
/*| Atom: .
|
||||
|*/
|
||||
class morkAtom { //
|
||||
|
||||
public:
|
||||
|
||||
mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
mork_change mAtom_Change; // how has this atom been changed?
|
||||
mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
public:
|
||||
morkAtom(mork_aid inAid, mork_u1 inKind);
|
||||
|
||||
mork_bool IsWeeAnon() const { return mAtom_Kind == morkAtom_kKindWeeAnon; }
|
||||
mork_bool IsBigAnon() const { return mAtom_Kind == morkAtom_kKindBigAnon; }
|
||||
mork_bool IsWeeBook() const { return mAtom_Kind == morkAtom_kKindWeeBook; }
|
||||
mork_bool IsBigBook() const { return mAtom_Kind == morkAtom_kKindBigBook; }
|
||||
mork_bool IsRowOid() const { return mAtom_Kind == morkAtom_kKindRowOid; }
|
||||
mork_bool IsTableOid() const { return mAtom_Kind == morkAtom_kKindTableOid; }
|
||||
|
||||
mork_bool IsBook() const { return this->IsWeeBook() || this->IsBigBook(); }
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkAtom() { }
|
||||
|
||||
public: // one-byte refcounting, freezing at maximum
|
||||
void MakeCellUseForever(morkEnv* ev);
|
||||
mork_u1 AddCellUse(morkEnv* ev);
|
||||
mork_u1 CutCellUse(morkEnv* ev);
|
||||
|
||||
mork_bool IsCellUseForever() const
|
||||
{ return mAtom_CellUses == morkAtom_kForeverCellUses; }
|
||||
|
||||
void SetAtomDirty() { mAtom_Change = morkChange_kAdd; }
|
||||
|
||||
private: // warnings
|
||||
|
||||
static void CellUsesUnderflowWarning(morkEnv* ev);
|
||||
|
||||
public: // errors
|
||||
|
||||
static void BadAtomKindError(morkEnv* ev);
|
||||
static void ZeroAidError(morkEnv* ev);
|
||||
static void AtomSizeOverflowError(morkEnv* ev);
|
||||
|
||||
public: // yarns
|
||||
|
||||
mork_bool AsBuf(morkBuf& outBuf) const;
|
||||
mork_bool AliasYarn(mdbYarn* outYarn) const;
|
||||
mork_bool GetYarn(mdbYarn* outYarn) const;
|
||||
|
||||
private: // copying is not allowed
|
||||
morkAtom(const morkAtom& other);
|
||||
morkAtom& operator=(const morkAtom& other);
|
||||
};
|
||||
|
||||
/*| OidAtom: an atom that references a row or table by identity.
|
||||
|*/
|
||||
class morkOidAtom : public morkAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
public:
|
||||
mdbOid mOidAtom_Oid; // identity of referenced object
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkOidAtom() { }
|
||||
void InitRowOidAtom(morkEnv* ev, const mdbOid& inOid);
|
||||
void InitTableOidAtom(morkEnv* ev, const mdbOid& inOid);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkOidAtom(const morkOidAtom& other);
|
||||
morkOidAtom& operator=(const morkOidAtom& other);
|
||||
};
|
||||
|
||||
/*| WeeAnonAtom: an atom whose content immediately follows morkAtom slots
|
||||
**| in an inline fashion, so that morkWeeAnonAtom contains both leading
|
||||
**| atom slots and then the content bytes without further overhead. Note
|
||||
**| that charset encoding is not indicated, so zero is implied for Latin1.
|
||||
**| (Non-Latin1 content must be stored in a morkBigAnonAtom with a charset.)
|
||||
**|
|
||||
**|| An anon (anonymous) atom has no identity, with no associated bookkeeping
|
||||
**| for lookup needed for sharing like a book atom.
|
||||
**|
|
||||
**|| A wee anon atom is immediate but not shared with any other users of this
|
||||
**| atom, so no bookkeeping for sharing is needed. This means the atom has
|
||||
**| no ID, because the atom has no identity other than this immediate content,
|
||||
**| and no hash table is needed to look up this particular atom. This also
|
||||
**| applies to the larger format morkBigAnonAtom, which has more slots.
|
||||
|*/
|
||||
class morkWeeAnonAtom : public morkAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
public:
|
||||
mork_u1 mWeeAnonAtom_Body[ 1 ]; // 1st byte of immediate content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkWeeAnonAtom() { }
|
||||
void InitWeeAnonAtom(morkEnv* ev, const morkBuf& inBuf);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkWeeAnonAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkWeeAnonAtom(const morkWeeAnonAtom& other);
|
||||
morkWeeAnonAtom& operator=(const morkWeeAnonAtom& other);
|
||||
};
|
||||
|
||||
/*| BigAnonAtom: another immediate atom that cannot be encoded as the smaller
|
||||
**| morkWeeAnonAtom format because either the size is too great, and/or the
|
||||
**| charset is not the default zero for Latin1 and must be explicitly noted.
|
||||
**|
|
||||
**|| An anon (anonymous) atom has no identity, with no associated bookkeeping
|
||||
**| for lookup needed for sharing like a book atom.
|
||||
|*/
|
||||
class morkBigAnonAtom : public morkAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
public:
|
||||
mork_cscode mBigAnonAtom_Form; // charset format encoding
|
||||
mork_size mBigAnonAtom_Size; // size of content vector
|
||||
mork_u1 mBigAnonAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkBigAnonAtom() { }
|
||||
void InitBigAnonAtom(morkEnv* ev, const morkBuf& inBuf, mork_cscode inForm);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkBigAnonAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBigAnonAtom(const morkBigAnonAtom& other);
|
||||
morkBigAnonAtom& operator=(const morkBigAnonAtom& other);
|
||||
};
|
||||
|
||||
#define morkBookAtom_kMaxBodySize 1024 /* if larger, cannot be shared */
|
||||
|
||||
/*| BookAtom: the common subportion of wee book atoms and big book atoms that
|
||||
**| includes the atom ID and the pointer to the space referencing this atom
|
||||
**| through a hash table.
|
||||
|*/
|
||||
class morkBookAtom : public morkAtom { //
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
public:
|
||||
morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->mSpace_Scope is atom scope
|
||||
mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkBookAtom() { }
|
||||
|
||||
static void NonBookAtomTypeError(morkEnv* ev);
|
||||
|
||||
public: // Hash() and Equal() for atom ID maps are same for all subclasses:
|
||||
|
||||
mork_u4 HashAid() const { return mBookAtom_Id; }
|
||||
mork_bool EqualAid(const morkBookAtom* inAtom) const
|
||||
{ return ( mBookAtom_Id == inAtom->mBookAtom_Id); }
|
||||
|
||||
public: // Hash() and Equal() for atom body maps know about subclasses:
|
||||
|
||||
mork_u4 HashFormAndBody(morkEnv* ev) const;
|
||||
mork_bool EqualFormAndBody(morkEnv* ev, const morkBookAtom* inAtom) const;
|
||||
|
||||
public: // separation from containing space
|
||||
|
||||
void CutBookAtomFromSpace(morkEnv* ev);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBookAtom(const morkBookAtom& other);
|
||||
morkBookAtom& operator=(const morkBookAtom& other);
|
||||
};
|
||||
|
||||
/*| WeeBookAtom: .
|
||||
|*/
|
||||
class morkWeeBookAtom : public morkBookAtom { //
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // only for atoms smaller than 256 bytes
|
||||
|
||||
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->mSpace_Scope is scope
|
||||
// mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
public:
|
||||
mork_u1 mWeeBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkWeeBookAtom() { }
|
||||
morkWeeBookAtom(mork_aid inAid);
|
||||
|
||||
void InitWeeBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
morkAtomSpace* ioSpace, mork_aid inAid);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkWeeBookAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkWeeBookAtom(const morkWeeBookAtom& other);
|
||||
morkWeeBookAtom& operator=(const morkWeeBookAtom& other);
|
||||
};
|
||||
|
||||
/*| BigBookAtom: .
|
||||
|*/
|
||||
class morkBigBookAtom : public morkBookAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->mSpace_Scope is scope
|
||||
// mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
public:
|
||||
mork_cscode mBigBookAtom_Form; // charset format encoding
|
||||
mork_size mBigBookAtom_Size; // size of content vector
|
||||
mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkBigBookAtom() { }
|
||||
void InitBigBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid);
|
||||
|
||||
// allow extra trailing byte for a null byte:
|
||||
static mork_size SizeForFill(mork_fill inFill)
|
||||
{ return sizeof(morkBigBookAtom) + inFill; }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBigBookAtom(const morkBigBookAtom& other);
|
||||
morkBigBookAtom& operator=(const morkBigBookAtom& other);
|
||||
};
|
||||
|
||||
/*| MaxBookAtom: .
|
||||
|*/
|
||||
class morkMaxBookAtom : public morkBigBookAtom { //
|
||||
|
||||
// mork_u1 mAtom_Kind; // identifies a specific atom subclass
|
||||
// mork_u1 mAtom_CellUses; // number of persistent uses in a cell
|
||||
// mork_change mAtom_Change; // how has this atom been changed?
|
||||
// mork_u1 mAtom_Size; // NOT USED IN "BIG" format atoms
|
||||
|
||||
// morkAtomSpace* mBookAtom_Space; // mBookAtom_Space->mSpace_Scope is scope
|
||||
// mork_aid mBookAtom_Id; // identity token for this shared atom
|
||||
|
||||
// mork_cscode mBigBookAtom_Form; // charset format encoding
|
||||
// mork_size mBigBookAtom_Size; // size of content vector
|
||||
// mork_u1 mBigBookAtom_Body[ 1 ]; // 1st byte of immed content vector
|
||||
|
||||
public:
|
||||
mork_u1 mBigBookAtom_Body[ morkBookAtom_kMaxBodySize + 3 ]; // max bytes
|
||||
|
||||
public: // empty construction does nothing
|
||||
morkMaxBookAtom() { }
|
||||
void InitMaxBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
{ this->InitBigBookAtom(ev, inBuf, inForm, ioSpace, inAid); }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkMaxBookAtom(const morkMaxBookAtom& other);
|
||||
morkMaxBookAtom& operator=(const morkMaxBookAtom& other);
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKATOM_ */
|
||||
263
mozilla/db/mork/src/morkAtomMap.cpp
Normal file
263
mozilla/db/mork/src/morkAtomMap.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#include "morkAtomMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkAtomAidMap::CloseMorkNode(morkEnv* ev) // CloseAtomAidMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseAtomAidMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkAtomAidMap::~morkAtomAidMap() // assert CloseAtomAidMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkAtomAidMap::morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
morkAtomAidMap_kStartSlotCount, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomAidMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkAtomAidMap::CloseAtomAidMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkAtomAidMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKeyA)->EqualAid(
|
||||
*(const morkBookAtom**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkAtomAidMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKey)->HashAid();
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
|
||||
mork_bool
|
||||
morkAtomAidMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* oldKey = 0;
|
||||
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* key = 0; // old val in the map
|
||||
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomAidMap::GetAid(morkEnv* ev, mork_aid inAid)
|
||||
{
|
||||
morkWeeBookAtom weeAtom(inAid);
|
||||
morkBookAtom* key = &weeAtom; // we need a pointer
|
||||
morkBookAtom* oldKey = 0; // old key in the map
|
||||
this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkAtomBodyMap::CloseMorkNode(morkEnv* ev) // CloseAtomBodyMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseAtomBodyMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkAtomBodyMap::~morkAtomBodyMap() // assert CloseAtomBodyMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkAtomBodyMap::morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkBookAtom*), /*inValSize*/ 0,
|
||||
morkAtomBodyMap_kStartSlotCount, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kFalse)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomBodyMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkAtomBodyMap::CloseAtomBodyMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkAtomBodyMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKeyA)->EqualFormAndBody(ev,
|
||||
*(const morkBookAtom**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkAtomBodyMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return (*(const morkBookAtom**) inKey)->HashFormAndBody(ev);
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
|
||||
mork_bool
|
||||
morkAtomBodyMap::AddAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &ioAtom, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomBodyMap::CutAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* oldKey = 0;
|
||||
this->Cut(ev, &inAtom, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomBodyMap::GetAtom(morkEnv* ev, const morkBookAtom* inAtom)
|
||||
{
|
||||
morkBookAtom* key = 0; // old val in the map
|
||||
this->Get(ev, &inAtom, &key, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
187
mozilla/db/mork/src/morkAtomMap.h
Normal file
187
mozilla/db/mork/src/morkAtomMap.h
Normal file
@@ -0,0 +1,187 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#define _MORKATOMMAP_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kAtomAidMap /*i*/ 0x6141 /* ascii 'aA' */
|
||||
|
||||
#define morkAtomAidMap_kStartSlotCount 512
|
||||
|
||||
/*| morkAtomAidMap: keys of morkBookAtom organized by atom ID
|
||||
|*/
|
||||
class morkAtomAidMap : public morkMap { // for mapping tokens to maps
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseAtomAidMap() only if open
|
||||
virtual ~morkAtomAidMap(); // assert that CloseAtomAidMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkAtomAidMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseAtomAidMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsAtomAidMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kAtomAidMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
// implemented using morkBookAtom::HashAid()
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// implemented using morkBookAtom::EqualAid()
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
// AddAtom() returns ev->Good()
|
||||
|
||||
morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// CutAtom() returns the atom removed equal to inAtom, if there was one
|
||||
|
||||
morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// GetAtom() returns the atom equal to inAtom, or else nil
|
||||
|
||||
morkBookAtom* GetAid(morkEnv* ev, mork_aid inAid);
|
||||
// GetAid() returns the atom equal to inAid, or else nil
|
||||
|
||||
// note the atoms are owned elsewhere, usuall by morkAtomSpace
|
||||
};
|
||||
|
||||
|
||||
class morkAtomAidMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkAtomAidMapIter( ) : morkMapIter() { }
|
||||
void InitAtomAidMapIter(morkEnv* ev, morkAtomAidMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->First(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kAtomBodyMap /*i*/ 0x6142 /* ascii 'aB' */
|
||||
|
||||
#define morkAtomBodyMap_kStartSlotCount 512
|
||||
|
||||
/*| morkAtomBodyMap: keys of morkBookAtom organized by body bytes
|
||||
|*/
|
||||
class morkAtomBodyMap : public morkMap { // for mapping tokens to maps
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseAtomBodyMap() only if open
|
||||
virtual ~morkAtomBodyMap(); // assert CloseAtomBodyMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkAtomBodyMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseAtomBodyMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsAtomBodyMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kAtomBodyMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
// implemented using morkBookAtom::HashFormAndBody()
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// implemented using morkBookAtom::EqualFormAndBody()
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddAtom(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
// AddAtom() returns ev->Good()
|
||||
|
||||
morkBookAtom* CutAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// CutAtom() returns the atom removed equal to inAtom, if there was one
|
||||
|
||||
morkBookAtom* GetAtom(morkEnv* ev, const morkBookAtom* inAtom);
|
||||
// GetAtom() returns the atom equal to inAtom, or else nil
|
||||
|
||||
// note the atoms are owned elsewhere, usuall by morkAtomSpace
|
||||
};
|
||||
|
||||
class morkAtomBodyMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkAtomBodyMapIter( ) : morkMapIter() { }
|
||||
void InitAtomBodyMapIter(morkEnv* ev, morkAtomBodyMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change* FirstAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->First(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* NextAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Next(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* HereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->Here(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* CutHereAtom(morkEnv* ev, morkBookAtom** outAtomPtr)
|
||||
{ return this->CutHere(ev, outAtomPtr, /*val*/ (void*) 0); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKATOMMAP_ */
|
||||
220
mozilla/db/mork/src/morkAtomSpace.cpp
Normal file
220
mozilla/db/mork/src/morkAtomSpace.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#include "morkSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#include "morkSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkAtomSpace::CloseMorkNode(morkEnv* ev) // CloseAtomSpace() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseAtomSpace(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkAtomSpace::~morkAtomSpace() // assert CloseAtomSpace() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mAtomSpace_HighUnderId==0);
|
||||
MORK_ASSERT(mAtomSpace_HighOverId==0);
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
MORK_ASSERT(mAtomSpace_AtomAids.IsShutNode());
|
||||
MORK_ASSERT(mAtomSpace_AtomBodies.IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkAtomSpace::morkAtomSpace(morkEnv* ev, const morkUsage& inUsage,
|
||||
mork_scope inScope, morkStore* ioStore,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap)
|
||||
, mAtomSpace_HighUnderId( morkAtomSpace_kMinUnderId )
|
||||
, mAtomSpace_HighOverId( morkAtomSpace_kMinOverId )
|
||||
, mAtomSpace_AtomAids(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
|
||||
, mAtomSpace_AtomBodies(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomSpace;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkAtomSpace::CloseAtomSpace(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mAtomSpace_AtomBodies.CloseMorkNode(ev);
|
||||
morkStore* store = mSpace_Store;
|
||||
if ( store )
|
||||
this->CutAllAtoms(ev, &store->mStore_Pool);
|
||||
|
||||
mAtomSpace_AtomAids.CloseMorkNode(ev);
|
||||
this->CloseSpace(ev);
|
||||
mAtomSpace_HighUnderId = 0;
|
||||
mAtomSpace_HighOverId = 0;
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkAtomSpace::NonAtomSpaceTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkAtomSpace");
|
||||
}
|
||||
|
||||
mork_num
|
||||
morkAtomSpace::CutAllAtoms(morkEnv* ev, morkPool* ioPool)
|
||||
{
|
||||
mork_num outSlots = mAtomSpace_AtomAids.mMap_Fill;
|
||||
morkBookAtom* a = 0; // old key atom in the map
|
||||
|
||||
mork_change* c = 0;
|
||||
morkAtomAidMapIter i(ev, &mAtomSpace_AtomAids);
|
||||
for ( c = i.FirstAtom(ev, &a); c ; c = i.NextAtom(ev, &a) )
|
||||
{
|
||||
if ( a )
|
||||
ioPool->ZapAtom(ev, a);
|
||||
i.CutHereAtom(ev, /*key*/ (morkBookAtom**) 0);
|
||||
}
|
||||
|
||||
return outSlots;
|
||||
}
|
||||
|
||||
|
||||
morkBookAtom*
|
||||
morkAtomSpace::MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
||||
// make copy of inAtom and put it in both maps, using a new ID as needed.
|
||||
{
|
||||
morkBookAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
morkBookAtom* atom = pool->NewBookAtomCopy(ev, inAtom);
|
||||
if ( atom )
|
||||
{
|
||||
mork_aid id = this->MakeNewAtomId(ev, atom);
|
||||
if ( id )
|
||||
{
|
||||
outAtom = atom;
|
||||
mAtomSpace_AtomAids.AddAtom(ev, atom);
|
||||
mAtomSpace_AtomBodies.AddAtom(ev, atom);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
|
||||
mork_aid
|
||||
morkAtomSpace::MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
{
|
||||
mork_aid outAid = 0;
|
||||
mork_tid id = mAtomSpace_HighUnderId;
|
||||
mork_num count = 8; // try up to eight times
|
||||
|
||||
while ( !outAid && count ) // still trying to find an unused table ID?
|
||||
{
|
||||
--count;
|
||||
ioAtom->mBookAtom_Id = id;
|
||||
if ( !mAtomSpace_AtomAids.GetAtom(ev, ioAtom) )
|
||||
outAid = id;
|
||||
else
|
||||
{
|
||||
MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems
|
||||
++id;
|
||||
}
|
||||
}
|
||||
|
||||
mAtomSpace_HighUnderId = id + 1;
|
||||
return outAid;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
morkAtomSpaceMap::~morkAtomSpaceMap()
|
||||
{
|
||||
}
|
||||
|
||||
morkAtomSpaceMap::morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kAtomSpaceMap;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
213
mozilla/db/mork/src/morkAtomSpace.h
Normal file
213
mozilla/db/mork/src/morkAtomSpace.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#define _MORKATOMSPACE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#include "morkSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#include "morkAtomMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#include "morkNodeMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*| kMinUnderId: the smallest ID we auto-assign to the 'under' namespace
|
||||
**| reserved for tokens expected to occur very frequently, such as the names
|
||||
**| of columns. We reserve single byte ids in the ASCII range to correspond
|
||||
**| one-to-one to those tokens consisting single ASCII characters (so that
|
||||
**| this assignment is always known and constant). So we start at 0x80, and
|
||||
**| then reserve the upper half of two hex digit ids and all the three hex
|
||||
**| digit IDs for the 'under' namespace for common tokens.
|
||||
|*/
|
||||
#define morkAtomSpace_kMinUnderId 0x80 /* low 7 bits mean byte tokens */
|
||||
|
||||
#define morkAtomSpace_kMaxSevenBitAid 0x7F /* low seven bit integer ID */
|
||||
|
||||
/*| kMinOverId: the smallest ID we auto-assign to the 'over' namespace that
|
||||
**| might include very large numbers of tokens that are used infrequently,
|
||||
**| so that we care less whether the shortest hex representation is used.
|
||||
**| So we start all IDs for 'over' category tokens at a value range that
|
||||
**| needs at least four hex digits, so we can reserve three hex digits and
|
||||
**| shorter for more commonly occuring tokens in the 'under' category.
|
||||
|*/
|
||||
#define morkAtomSpace_kMinOverId 0x1000 /* using at least four hex bytes */
|
||||
|
||||
#define morkDerived_kAtomSpace /*i*/ 0x6153 /* ascii 'aS' */
|
||||
|
||||
/*| morkAtomSpace:
|
||||
|*/
|
||||
class morkAtomSpace : public morkSpace { //
|
||||
|
||||
// public: // slots inherited from morkSpace (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkStore* mSpace_Store; // weak ref to containing store
|
||||
// mork_scope mSpace_Scope; // the scope for this space
|
||||
|
||||
// mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs
|
||||
// mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs
|
||||
// mork_u1 mSpace_Pad[ 2 ]; // pad to u4 alignment
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
mork_aid mAtomSpace_HighUnderId; // high ID in 'under' range
|
||||
mork_aid mAtomSpace_HighOverId; // high ID in 'over' range
|
||||
|
||||
morkAtomAidMap mAtomSpace_AtomAids; // all atoms in space by ID
|
||||
morkAtomBodyMap mAtomSpace_AtomBodies; // all atoms in space by body
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseAtomSpace() only if open
|
||||
virtual ~morkAtomSpace(); // assert that CloseAtomSpace() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkAtomSpace(morkEnv* ev, const morkUsage& inUsage, mork_scope inScope,
|
||||
morkStore* ioStore, nsIMdbHeap* ioNodeHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseAtomSpace(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsAtomSpace() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kAtomSpace; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
void NonAtomSpaceTypeError(morkEnv* ev);
|
||||
|
||||
public: // setup
|
||||
|
||||
mork_bool MarkAllAtomSpaceContentDirty(morkEnv* ev);
|
||||
// MarkAllAtomSpaceContentDirty() visits every space object and marks
|
||||
// them dirty, including every table, row, cell, and atom. The return
|
||||
// equals ev->Good(), to show whether any error happened. This method is
|
||||
// intended for use in the beginning of a "compress commit" which writes
|
||||
// all store content, whether dirty or not. We dirty everything first so
|
||||
// that later iterations over content can mark things clean as they are
|
||||
// written, and organize the process of serialization so that objects are
|
||||
// written only at need (because of being dirty).
|
||||
|
||||
public: // other space methods
|
||||
|
||||
mork_num CutAllAtoms(morkEnv* ev, morkPool* ioPool);
|
||||
// CutAllAtoms() puts all the atoms back in the pool.
|
||||
|
||||
morkBookAtom* MakeBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom);
|
||||
// Make copy of inAtom and put it in both maps, using a new ID as needed.
|
||||
|
||||
mork_aid MakeNewAtomId(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
// generate an unused atom id.
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakAtomSpace(morkAtomSpace* me,
|
||||
morkEnv* ev, morkAtomSpace** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongAtomSpace(morkAtomSpace* me,
|
||||
morkEnv* ev, morkAtomSpace** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kAtomSpaceMap /*i*/ 0x615A /* ascii 'aZ' */
|
||||
|
||||
/*| morkAtomSpaceMap: maps mork_scope -> morkAtomSpace
|
||||
|*/
|
||||
class morkAtomSpaceMap : public morkNodeMap { // for mapping tokens to tables
|
||||
|
||||
public:
|
||||
|
||||
virtual ~morkAtomSpaceMap();
|
||||
morkAtomSpaceMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddAtomSpace(morkEnv* ev, morkAtomSpace* ioAtomSpace)
|
||||
{ return this->AddNode(ev, ioAtomSpace->mSpace_Scope, ioAtomSpace); }
|
||||
// the AddAtomSpace() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutAtomSpace(morkEnv* ev, mork_scope inScope)
|
||||
{ return this->CutNode(ev, inScope); }
|
||||
// The CutAtomSpace() boolean return indicates whether removal happened.
|
||||
|
||||
morkAtomSpace* GetAtomSpace(morkEnv* ev, mork_scope inScope)
|
||||
{ return (morkAtomSpace*) this->GetNode(ev, inScope); }
|
||||
// Note the returned space does NOT have an increase in refcount for this.
|
||||
|
||||
mork_num CutAllAtomSpaces(morkEnv* ev)
|
||||
{ return this->CutAllNodes(ev); }
|
||||
// CutAllAtomSpaces() releases all the referenced table values.
|
||||
};
|
||||
|
||||
class morkAtomSpaceMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkAtomSpaceMapIter(morkEnv* ev, morkAtomSpaceMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkAtomSpaceMapIter( ) : morkMapIter() { }
|
||||
void InitAtomSpaceMapIter(morkEnv* ev, morkAtomSpaceMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change*
|
||||
FirstAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace)
|
||||
{ return this->First(ev, outScope, outAtomSpace); }
|
||||
|
||||
mork_change*
|
||||
NextAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace)
|
||||
{ return this->Next(ev, outScope, outAtomSpace); }
|
||||
|
||||
mork_change*
|
||||
HereAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace)
|
||||
{ return this->Here(ev, outScope, outAtomSpace); }
|
||||
|
||||
mork_change*
|
||||
CutHereAtomSpace(morkEnv* ev, mork_scope* outScope, morkAtomSpace** outAtomSpace)
|
||||
{ return this->CutHere(ev, outScope, outAtomSpace); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKATOMSPACE_ */
|
||||
62
mozilla/db/mork/src/morkBlob.cpp
Normal file
62
mozilla/db/mork/src/morkBlob.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
morkSpool::morkSpool(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
{
|
||||
mBuf_Body = 0;
|
||||
mBuf_Fill = 0;
|
||||
mBlob_Size = 0;
|
||||
mText_Form = 0;
|
||||
mSpool_Heap = ioHeap;
|
||||
if ( !ioHeap )
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
void
|
||||
morkSpool::CloseSpool(morkEnv* ev)
|
||||
{
|
||||
void* body = mBuf_Body;
|
||||
nsIMdbHeap* heap = mSpool_Heap;
|
||||
|
||||
if ( body && heap )
|
||||
{
|
||||
heap->Free(ev->AsMdbEnv(), body);
|
||||
}
|
||||
mBuf_Body = 0;
|
||||
mSpool_Heap = 0;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
144
mozilla/db/mork/src/morkBlob.h
Normal file
144
mozilla/db/mork/src/morkBlob.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#define _MORKBLOB_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*| Buf: the minimum needed to describe location and content length.
|
||||
**| This is typically only enough to read from this buffer, since
|
||||
**| one cannot write effectively without knowing the size of a buf.
|
||||
|*/
|
||||
class morkBuf { // subset of nsIMdbYarn slots
|
||||
public:
|
||||
void* mBuf_Body; // space for holding any binary content
|
||||
mork_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
|
||||
public:
|
||||
morkBuf() { }
|
||||
morkBuf(const void* ioBuf, mork_fill inFill)
|
||||
: mBuf_Body((void*) ioBuf), mBuf_Fill(inFill) { }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBuf(const morkBuf& other);
|
||||
morkBuf& operator=(const morkBuf& other);
|
||||
};
|
||||
|
||||
/*| Blob: a buffer with an associated size, to increase known buf info
|
||||
**| to include max capacity in addition to buf location and content.
|
||||
**| This form factor allows us to allocate a vector of such blobs,
|
||||
**| which can share the same managing heap stored elsewhere, and that
|
||||
**| is why we don't include a pointer to a heap in this blob class.
|
||||
|*/
|
||||
class morkBlob : public morkBuf { // greater subset of nsIMdbYarn slots
|
||||
|
||||
// void* mBuf_Body; // space for holding any binary content
|
||||
// mdb_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
public:
|
||||
mork_size mBlob_Size; // physical size of Buf in bytes
|
||||
|
||||
public:
|
||||
morkBlob() { }
|
||||
morkBlob(const void* ioBuf, mork_fill inFill, mork_size inSize)
|
||||
: morkBuf(ioBuf, inFill), mBlob_Size(inSize) { }
|
||||
|
||||
public:
|
||||
mork_bool Grow(morkEnv* ev, nsIMdbHeap* ioHeap, mork_size inNewSize);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBlob(const morkBlob& other);
|
||||
morkBlob& operator=(const morkBlob& other);
|
||||
|
||||
};
|
||||
|
||||
/*| Text: a blob with an associated charset annotation, where the
|
||||
**| charset actually includes the general notion of typing, and not
|
||||
**| just a specification of character set alone; we want to permit
|
||||
**| arbitrary charset annotations for ad hoc binary types as well.
|
||||
**| (We avoid including a nsIMdbHeap pointer in morkText for the same
|
||||
**| reason morkBlob does: we want minimal size vectors of morkText.)
|
||||
|*/
|
||||
class morkText : public morkBlob { // greater subset of nsIMdbYarn slots
|
||||
|
||||
// void* mBuf_Body; // space for holding any binary content
|
||||
// mdb_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
// mdb_size mBlob_Size; // physical size of Buf in bytes
|
||||
|
||||
public:
|
||||
mork_cscode mText_Form; // charset format encoding
|
||||
|
||||
morkText() { }
|
||||
|
||||
private: // copying is not allowed
|
||||
morkText(const morkText& other);
|
||||
morkText& operator=(const morkText& other);
|
||||
};
|
||||
|
||||
/*| Spool: a text with an associated nsIMdbHeap instance that provides
|
||||
**| all memory management for the space pointed to by mBuf_Body. (This
|
||||
**| was the hardest type to give a name in this small class hierarchy,
|
||||
**| because it's hard to characterize self-management of one's space.)
|
||||
**| A spool is a self-contained blob that knows how to grow itself as
|
||||
**| necessary to hold more content when necessary. Spool descends from
|
||||
**| morkText to include the mText_Form slot, even though this won't be
|
||||
**| needed always, because we are not as concerned about the overall
|
||||
**| size of this particular Spool object (if we were concerned about
|
||||
**| the size of an array of Spool instances, we would not bother with
|
||||
**| a separate heap pointer for each of them).
|
||||
**|
|
||||
**|| A spool makes a good medium in which to stream content as a sink,
|
||||
**| so we will have a subclass of morkSink called morkSpoolSink that
|
||||
**| will stream bytes into this self-contained spool object. The name
|
||||
**| of this morkSpool class derives more from this intended usage than
|
||||
**| from anything else. The Mork code to parse db content will use
|
||||
**| spools with associated sinks to accumulate parsed strings.
|
||||
**|
|
||||
**|| Heap: this is the heap used for memory allocation. This instance
|
||||
**| is NOT refcounted, since this spool always assumes the heap is held
|
||||
**| through a reference elsewhere (for example, through the same object
|
||||
**| that contains or holds the spool itself. This lack of refcounting
|
||||
**| is consistent with the fact that morkSpool itself is not refcounted,
|
||||
**| and is not intended for use as a standalone object.
|
||||
|*/
|
||||
class morkSpool : public morkText { // self-managing text blob object
|
||||
|
||||
// void* mBuf_Body; // space for holding any binary content
|
||||
// mdb_fill mBuf_Fill; // logical content in Buf in bytes
|
||||
// mdb_size mBlob_Size; // physical size of Buf in bytes
|
||||
// mdb_cscode mText_Form; // charset format encoding
|
||||
public:
|
||||
nsIMdbHeap* mSpool_Heap; // storage manager for mBuf_Body pointer
|
||||
|
||||
public:
|
||||
morkSpool(morkEnv* ev, nsIMdbHeap* ioHeap);
|
||||
|
||||
void CloseSpool(morkEnv* ev);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkSpool(const morkSpool& other);
|
||||
morkSpool& operator=(const morkSpool& other);
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKBLOB_ */
|
||||
325
mozilla/db/mork/src/morkBuilder.cpp
Normal file
325
mozilla/db/mork/src/morkBuilder.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBUILDER_
|
||||
#include "morkBuilder.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkBuilder::CloseMorkNode(morkEnv* ev) // CloseBuilder() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseBuilder(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkBuilder::~morkBuilder() // assert CloseBuilder() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mBuilder_Table==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkBuilder::morkBuilder(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStream* ioStream, mdb_count inBytesPerParseSegment,
|
||||
nsIMdbHeap* ioSlotHeap, morkStore* ioStore)
|
||||
: morkParser(ev, inUsage, ioHeap, ioStream,
|
||||
inBytesPerParseSegment, ioSlotHeap)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kBuilder;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkBuilder::CloseBuilder(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseParser(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkBuilder::NonBuilderTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkBuilder");
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn)
|
||||
// The parser might ask that some aliases be turned into yarns, so they
|
||||
// can be concatenated into longer blobs under some circumstances. This
|
||||
// is an alternative to using a long and complex callback for many parts
|
||||
// for a single cell value.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewPort(morkEnv* ev, const morkPlace& inPlace)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewMeta(morkEnv* ev, const morkPlace& inPlace)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnMetaEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewDict(morkEnv* ev, const morkPlace& inPlace)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnDictEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnCellEnd(morkEnv* ev, const morkSpan& inSpan)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkBuilder::OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
290
mozilla/db/mork/src/morkBuilder.h
Normal file
290
mozilla/db/mork/src/morkBuilder.h
Normal file
@@ -0,0 +1,290 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKBUILDER_
|
||||
#define _MORKBUILDER_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*| kCellsVecSize: length of cell vector buffer inside morkBuilder
|
||||
|*/
|
||||
#define morkBuilder_kCellsVecSize 64
|
||||
|
||||
#define morkBuilder_kDefaultBytesPerParseSegment 512 /* plausible to big */
|
||||
|
||||
#define morkDerived_kBuilder /*i*/ 0x4275 /* ascii 'Bu' */
|
||||
|
||||
class morkBuilder /*d*/ : public morkParser {
|
||||
|
||||
// public: // slots inherited from morkParser (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
|
||||
// nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
// morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
// mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
// mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
|
||||
|
||||
// mork_u4 mParser_State; // state where parser should resume
|
||||
|
||||
// after finding ends of group transactions, we can re-seek the start:
|
||||
// mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
// mork_gid mParser_GroupId; // group ID if inside a group
|
||||
// mork_tid mParser_TableId; // table ID if inside a table
|
||||
// mork_rid mParser_RowId; // row ID if inside a row
|
||||
|
||||
// mork_bool mParser_InPort; // called OnNewPort but not OnPortEnd?
|
||||
// mork_bool mParser_InDict; // called OnNewDict but not OnDictEnd?
|
||||
// mork_bool mParser_InCell; // called OnNewCell but not OnCellEnd?
|
||||
// mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd?
|
||||
|
||||
// morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool below:
|
||||
|
||||
// blob spools allocated in mParser_Heap
|
||||
// morkSpool mParser_ScopeSpool; // place to accumulate ID scope blobs
|
||||
// morkSpool mParser_ValueSpool; // place to accumulate value blobs
|
||||
// morkSpool mParser_ColumnSpool; // place to accumulate column blobs
|
||||
// morkSpool mParser_StringSpool; // place to accumulate string blobs
|
||||
|
||||
// morkSpoolSink mParser_ScopeSink; // writes to mParser_ScopeSpool
|
||||
// morkSpoolSink mParser_ValueSink; // writes to mParser_ValueSpool
|
||||
// morkSpoolSink mParser_ColumnSink; // writes to mParser_ColumnSpool
|
||||
// morkSpoolSink mParser_StringSink; // writes to mParser_StringSpool
|
||||
|
||||
// yarns allocated in mParser_Heap
|
||||
// morkYarn mParser_AliasYarn; // place to receive from AliasToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
// morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
||||
// various spans denoting nested subspaces inside the file's port span:
|
||||
// morkSpan mParser_GroupSpan; // span of current transaction group
|
||||
// morkSpan mParser_DictSpan;
|
||||
// morkSpan mParser_AliasSpan;
|
||||
// morkSpan mParser_MetaDictSpan;
|
||||
// morkSpan mParser_TableSpan;
|
||||
// morkSpan mParser_MetaTableSpan;
|
||||
// morkSpan mParser_RowSpan;
|
||||
// morkSpan mParser_MetaRowSpan;
|
||||
// morkSpan mParser_CellSpan;
|
||||
// morkSpan mParser_ColumnSpan;
|
||||
// morkSpan mParser_SlotSpan;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected morkBuilder members
|
||||
|
||||
// weak refs that do not prevent closure of referenced nodes:
|
||||
morkStore* mBuilder_Store; // weak ref to builder's store
|
||||
|
||||
// strong refs that do indeed prevent closure of referenced nodes:
|
||||
morkTable* mBuilder_Table; // current table being built (or nil)
|
||||
morkRow* mBuilder_Row; // current row being built (or nil)
|
||||
morkCell* mBuilder_Cell; // current cell within CellsVec (or nil)
|
||||
|
||||
morkRowSpace* mBuilder_RowSpace; // space for mBuilder_CurrentRowScope
|
||||
morkAtomSpace* mBuilder_AtomSpace; // space for mBuilder_CurrentAtomScope
|
||||
|
||||
morkAtomSpace* mBuilder_OidAtomSpace; // ground atom space for oids
|
||||
morkAtomSpace* mBuilder_ScopeAtomSpace; // ground atom space for scopes
|
||||
|
||||
// scoped object ids for current objects under construction:
|
||||
mdbOid mBuilder_TableOid; // full oid for current table
|
||||
mdbOid mBuilder_RowOid; // full oid for current row
|
||||
|
||||
// standard tokens that we want to know about for this port:
|
||||
mork_cscode mBuilder_iso_8859_1; // token for "iso-8859-1"
|
||||
mork_cscode mBuilder_r; // token for "r"
|
||||
mork_cscode mBuilder_a; // token for "a"
|
||||
mork_cscode mBuilder_t; // token for "t"
|
||||
|
||||
// tokens that become set as the result of meta cells in port rows:
|
||||
mork_cscode mBuilder_PortForm; // default port charset format
|
||||
mork_scope mBuilder_PortRowScope; // port row scope
|
||||
mork_scope mBuilder_PortAtomScope; // port atom scope
|
||||
|
||||
// tokens that become set as the result of meta cells in meta tables:
|
||||
mork_cscode mBuilder_TableForm; // default table charset format
|
||||
mork_scope mBuilder_TableRowScope; // table row scope
|
||||
mork_scope mBuilder_TableAtomScope; // table atom scope
|
||||
mork_kind mBuilder_TableKind; // table kind
|
||||
|
||||
// tokens that become set as the result of meta cells in meta rows:
|
||||
mork_cscode mBuilder_RowForm; // default row charset format
|
||||
mork_scope mBuilder_RowRowScope; // row scope per row metainfo
|
||||
mork_scope mBuilder_RowAtomScope; // row atom scope
|
||||
|
||||
// meta tokens currently in force, driven by meta info slots above:
|
||||
mork_cscode mBuilder_CurrentForm; // current charset format
|
||||
mork_scope mBuilder_CurrentRowScope; // current row scope
|
||||
mork_scope mBuilder_CurrentAtomScope; // current atom scope
|
||||
|
||||
// If any of these 'cut' bools are true, it means a minus was seen in the
|
||||
// Mork source text to indicate removal of content from some container.
|
||||
// (Note there is no corresponding 'add' bool, since add is the default.)
|
||||
// CutRow implies the current row should be cut from the table.
|
||||
// CutCell implies the current column should be cut from the row.
|
||||
mork_bool mBuilder_CutRow; // row with kCut change
|
||||
mork_bool mBuilder_CutCell; // cell with kCut change
|
||||
mork_u1 mBuilder_Pad1; // pad to u4 alignment
|
||||
mork_u1 mBuilder_Pad2; // pad to u4 alignment
|
||||
|
||||
morkCell mBuilder_CellsVec[ morkBuilder_kCellsVecSize ];
|
||||
mork_fill mBuilder_CellsVecFill; // count used in CellsVec
|
||||
// Note when mBuilder_CellsVecFill equals morkBuilder_kCellsVecSize, and
|
||||
// another cell is added, this means all the cells in the vector above
|
||||
// must be flushed to the current row being built to create more room.
|
||||
|
||||
protected: // protected inlines
|
||||
|
||||
mork_bool CellVectorIsFull() const
|
||||
{ return ( mBuilder_CellsVecFill == morkBuilder_kCellsVecSize ); };
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseBuilder() only if open
|
||||
virtual ~morkBuilder(); // assert that CloseBuilder() executed earlier
|
||||
|
||||
public: // morkYarn construction & destruction
|
||||
morkBuilder(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStream* ioStream, // the readonly stream for input bytes
|
||||
mdb_count inBytesPerParseSegment, // target for ParseMore()
|
||||
nsIMdbHeap* ioSlotHeap, morkStore* ioStore
|
||||
);
|
||||
|
||||
void CloseBuilder(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkBuilder(const morkBuilder& other);
|
||||
morkBuilder& operator=(const morkBuilder& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsBuilder() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kBuilder; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonBuilderTypeError(morkEnv* ev);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // in virtual morkParser methods, data flow subclass to parser
|
||||
|
||||
virtual void AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn);
|
||||
// The parser might ask that some aliases be turned into yarns, so they
|
||||
// can be concatenated into longer blobs under some circumstances. This
|
||||
// is an alternative to using a long and complex callback for many parts
|
||||
// for a single cell value.
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // out virtual morkParser methods, data flow parser to subclass
|
||||
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid);
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace);
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange);
|
||||
virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch);
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat);
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan);
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf);
|
||||
|
||||
virtual void OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkBuilder methods
|
||||
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakBuilder(morkBuilder* me,
|
||||
morkEnv* ev, morkBuilder** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongBuilder(morkBuilder* me,
|
||||
morkEnv* ev, morkBuilder** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKBUILDER_ */
|
||||
120
mozilla/db/mork/src/morkCell.cpp
Normal file
120
mozilla/db/mork/src/morkCell.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
void
|
||||
morkCell::SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
morkAtom* atom = ioStore->YarnToAtom(ev, inYarn);
|
||||
if ( atom )
|
||||
this->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom
|
||||
}
|
||||
|
||||
void
|
||||
morkCell::GetYarn(morkEnv* ev, mdbYarn* outYarn) const
|
||||
{
|
||||
mCell_Atom->GetYarn(outYarn);
|
||||
}
|
||||
|
||||
void
|
||||
morkCell::AliasYarn(morkEnv* ev, mdbYarn* outYarn) const
|
||||
{
|
||||
mCell_Atom->AliasYarn(outYarn);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
morkCell::SetCellDirty()
|
||||
{
|
||||
mork_column col = this->GetColumn();
|
||||
this->SetColumnAndChange(col, morkChange_kAdd);
|
||||
}
|
||||
|
||||
void
|
||||
morkCell::SetAtom(morkEnv* ev, morkAtom* ioAtom, morkPool* ioPool)
|
||||
// SetAtom() "acquires" the new ioAtom if non-nil, by calling AddCellUse()
|
||||
// to increase the refcount, and puts ioAtom into mCell_Atom. If the old
|
||||
// atom in mCell_Atom is non-nil, then it is "released" first by a call to
|
||||
// CutCellUse(), and if the use count then becomes zero, then the old atom
|
||||
// is deallocated by returning it to the pool ioPool. (And this is
|
||||
// why ioPool is a parameter to this method.) Note that ioAtom can be nil
|
||||
// to cause the cell to refer to nothing, and the old atom in mCell_Atom
|
||||
// can also be nil, and all the atom refcounting is handled correctly.
|
||||
//
|
||||
// Note that if ioAtom was just created, it typically has a zero use count
|
||||
// before calling SetAtom(). But use count is one higher after SetAtom().
|
||||
{
|
||||
morkAtom* oldAtom = mCell_Atom;
|
||||
if ( oldAtom != ioAtom ) // ioAtom is not already installed in this cell?
|
||||
{
|
||||
if ( oldAtom )
|
||||
{
|
||||
mCell_Atom = 0;
|
||||
if ( oldAtom->CutCellUse(ev) == 0 )
|
||||
{
|
||||
if ( ioPool )
|
||||
{
|
||||
if ( oldAtom->IsBook() )
|
||||
((morkBookAtom*) oldAtom)->CutBookAtomFromSpace(ev);
|
||||
|
||||
ioPool->ZapAtom(ev, oldAtom);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
if ( ioAtom )
|
||||
ioAtom->AddCellUse(ev);
|
||||
|
||||
mCell_Atom = ioAtom;
|
||||
}
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
89
mozilla/db/mork/src/morkCell.h
Normal file
89
mozilla/db/mork/src/morkCell.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#define _MORKCELL_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDelta_kShift 8 /* 8 bit shift */
|
||||
#define morkDelta_kChangeMask 0x0FF /* low 8 bit mask */
|
||||
#define morkDelta_kColumnMask (~ (mork_column) morkDelta_kChangeMask)
|
||||
#define morkDelta_Init(self,cl,ch) ((self) = ((cl)<<morkDelta_kShift) | (ch))
|
||||
#define morkDelta_Change(self) ((self) & morkDelta_kChangeMask)
|
||||
#define morkDelta_Column(self) ((self) >> morkDelta_kShift)
|
||||
|
||||
class morkCell { // minimal cell format
|
||||
|
||||
public:
|
||||
mork_delta mCell_Delta; // encoding of both column and change
|
||||
morkAtom* mCell_Atom; // content in this cell
|
||||
|
||||
public:
|
||||
morkCell() : mCell_Atom( 0 ), mCell_Delta( 0 ) { }
|
||||
|
||||
// note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse():
|
||||
morkCell(mork_column inCol, mork_change inChange, morkAtom* ioAtom)
|
||||
{
|
||||
morkDelta_Init(mCell_Delta, inCol,inChange);
|
||||
mCell_Atom = ioAtom;
|
||||
}
|
||||
|
||||
// note if ioAtom is non-nil, caller needs to call ioAtom->AddCellUse():
|
||||
void Init(mork_column inCol, mork_change inChange, morkAtom* ioAtom)
|
||||
{
|
||||
morkDelta_Init(mCell_Delta,inCol,inChange);
|
||||
mCell_Atom = ioAtom;
|
||||
}
|
||||
|
||||
mork_column GetColumn() const { return morkDelta_Column(mCell_Delta); }
|
||||
mork_change GetChange() const { return morkDelta_Change(mCell_Delta); }
|
||||
|
||||
void SetCellDirty();
|
||||
|
||||
void SetColumnAndChange(mork_column inCol, mork_change inChange)
|
||||
{ morkDelta_Init(mCell_Delta, inCol, inChange); }
|
||||
|
||||
morkAtom* GetAtom() { return mCell_Atom; }
|
||||
|
||||
void SetAtom(morkEnv* ev, morkAtom* ioAtom, morkPool* ioPool);
|
||||
// SetAtom() "acquires" the new ioAtom if non-nil, by calling AddCellUse()
|
||||
// to increase the refcount, and puts ioAtom into mCell_Atom. If the old
|
||||
// atom in mCell_Atom is non-nil, then it is "released" first by a call to
|
||||
// CutCellUse(), and if the use count then becomes zero, then the old atom
|
||||
// is deallocated by returning it to the pool ioPool. (And this is
|
||||
// why ioPool is a parameter to this method.) Note that ioAtom can be nil
|
||||
// to cause the cell to refer to nothing, and the old atom in mCell_Atom
|
||||
// can also be nil, and all the atom refcounting is handled correctly.
|
||||
//
|
||||
// Note that if ioAtom was just created, it typically has a zero use count
|
||||
// before calling SetAtom(). But use count is one higher after SetAtom().
|
||||
|
||||
void SetYarn(morkEnv* ev, const mdbYarn* inYarn, morkStore* ioStore);
|
||||
|
||||
void AliasYarn(morkEnv* ev, mdbYarn* outYarn) const;
|
||||
void GetYarn(morkEnv* ev, mdbYarn* outYarn) const;
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKCELL_ */
|
||||
233
mozilla/db/mork/src/morkCellObject.cpp
Normal file
233
mozilla/db/mork/src/morkCellObject.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELLOBJECT_
|
||||
#include "morkCellObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINCELL_
|
||||
#include "orkinCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkCellObject::CloseMorkNode(morkEnv* ev) // CloseCellObject() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseCellObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkCellObject::~morkCellObject() // assert CloseCellObject() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mCellObject_Row==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkCellObject::morkCellObject(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkRow* ioRow, morkCell* ioCell,
|
||||
mork_column inCol, mork_pos inPos)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mCellObject_RowObject( 0 )
|
||||
, mCellObject_Row( 0 )
|
||||
, mCellObject_Cell( 0 )
|
||||
, mCellObject_Col( inCol )
|
||||
, mCellObject_RowSeed( 0 )
|
||||
, mCellObject_Pos( (mork_u2) inPos )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioRow && ioCell )
|
||||
{
|
||||
if ( ioRow->IsRow() )
|
||||
{
|
||||
morkStore* store = ioRow->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowObject* rowObj = ioRow->GetRowObject(ev, store);
|
||||
if ( rowObj )
|
||||
{
|
||||
mCellObject_Row = ioRow;
|
||||
mCellObject_Cell = ioCell;
|
||||
mCellObject_RowSeed = ioRow->mRow_Seed;
|
||||
morkRowObject::SlotStrongRowObject(rowObj, ev,
|
||||
&mCellObject_RowObject);
|
||||
}
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kCellObject;
|
||||
}
|
||||
}
|
||||
else
|
||||
ioRow->NonRowTypeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkCellObject::CloseCellObject(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkRowObject::SlotStrongRowObject((morkRowObject*) 0, ev,
|
||||
&mCellObject_RowObject);
|
||||
mCellObject_Row = 0;
|
||||
mCellObject_Cell = 0;
|
||||
mCellObject_RowSeed = 0;
|
||||
this->CloseObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
mork_bool
|
||||
morkCellObject::ResyncWithRow(morkEnv* ev)
|
||||
{
|
||||
morkRow* row = mCellObject_Row;
|
||||
mork_pos pos = 0;
|
||||
morkCell* cell = row->GetCell(ev, mCellObject_Col, &pos);
|
||||
if ( cell )
|
||||
{
|
||||
mCellObject_Pos = pos;
|
||||
mCellObject_Cell = cell;
|
||||
mCellObject_RowSeed = row->mRow_Seed;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCellObject_Cell = 0;
|
||||
this->MissingRowColumnError(ev);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkCellObject::GetCellAtom(morkEnv* ev) const
|
||||
{
|
||||
morkCell* cell = mCellObject_Cell;
|
||||
if ( cell )
|
||||
return cell->GetAtom();
|
||||
else
|
||||
this->NilCellError(ev);
|
||||
|
||||
return (morkAtom*) 0;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::WrongRowObjectRowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mCellObject_Row != mCellObject_RowObject->mRowObject_Row");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NilRowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mCellObject_Row");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NilRowObjectError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mCellObject_RowObject");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NilCellError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mCellObject_Cell");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::NonCellObjectTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkCellObject");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkCellObject::MissingRowColumnError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mCellObject_Col not in mCellObject_Row");
|
||||
}
|
||||
|
||||
nsIMdbCell*
|
||||
morkCellObject::AcquireCellHandle(morkEnv* ev)
|
||||
{
|
||||
nsIMdbCell* outCell = 0;
|
||||
orkinCell* c = (orkinCell*) mObject_Handle;
|
||||
if ( c ) // have an old handle?
|
||||
c->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
c = orkinCell::MakeCell(ev, this);
|
||||
mObject_Handle = c;
|
||||
}
|
||||
if ( c )
|
||||
outCell = c;
|
||||
return outCell;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
107
mozilla/db/mork/src/morkCellObject.h
Normal file
107
mozilla/db/mork/src/morkCellObject.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKCELLOBJECT_
|
||||
#define _MORKCELLOBJECT_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kCellObject /*i*/ 0x634F /* ascii 'cO' */
|
||||
|
||||
class morkCellObject : public morkObject { // blob attribute in column scope
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkFactory* mObject_Factory; // weak ref to suite factory
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
morkRowObject* mCellObject_RowObject; // strong ref to row's object
|
||||
morkRow* mCellObject_Row; // cell's row if still in row object
|
||||
morkCell* mCellObject_Cell; // cell in row if rowseed matches
|
||||
mork_column mCellObject_Col; // col of cell last living in pos
|
||||
mork_u2 mCellObject_RowSeed; // copy of row's seed
|
||||
mork_u2 mCellObject_Pos; // position of cell in row
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseCellObject() only if open
|
||||
virtual ~morkCellObject(); // assert that CloseCellObject() executed earlier
|
||||
|
||||
public: // morkCellObject construction & destruction
|
||||
morkCellObject(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkRow* ioRow, morkCell* ioCell,
|
||||
mork_column inCol, mork_pos inPos);
|
||||
void CloseCellObject(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkCellObject(const morkCellObject& other);
|
||||
morkCellObject& operator=(const morkCellObject& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsCellObject() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kCellObject; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // other cell node methods
|
||||
|
||||
mork_bool ResyncWithRow(morkEnv* ev); // return ev->Good()
|
||||
morkAtom* GetCellAtom(morkEnv* ev) const;
|
||||
|
||||
static void MissingRowColumnError(morkEnv* ev);
|
||||
static void NilRowError(morkEnv* ev);
|
||||
static void NilCellError(morkEnv* ev);
|
||||
static void NilRowObjectError(morkEnv* ev);
|
||||
static void WrongRowObjectRowError(morkEnv* ev);
|
||||
static void NonCellObjectTypeError(morkEnv* ev);
|
||||
|
||||
nsIMdbCell* AcquireCellHandle(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakCellObject(morkCellObject* me,
|
||||
morkEnv* ev, morkCellObject** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongCellObject(morkCellObject* me,
|
||||
morkEnv* ev, morkCellObject** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKCELLOBJECT_ */
|
||||
249
mozilla/db/mork/src/morkConfig.cpp
Normal file
249
mozilla/db/mork/src/morkConfig.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCONFIG_
|
||||
#include "morkConfig.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* ----- ----- ----- ----- MORK_MAC ----- ----- ----- ----- */
|
||||
#ifdef MORK_MAC
|
||||
|
||||
#include <Types.h>
|
||||
|
||||
static void // copied almost verbatim from the IronDoc debugger sources:
|
||||
mork_mac_break_string(register const char* inMessage) /*i*/
|
||||
{
|
||||
Str255 pascalStr; // to hold Pascal string version of inMessage
|
||||
mork_u4 length = XP_STRLEN(inMessage);
|
||||
|
||||
// if longer than maximum 255 bytes, just copy 255 bytes worth
|
||||
pascalStr[ 0 ] = (length > 255)? 255 : length;
|
||||
if ( length ) // anything to copy? */
|
||||
{
|
||||
register mork_u1* p = ((mork_u1*) &pascalStr) + 1; // after length byte
|
||||
register mork_u1* end = p + length; // one past last byte to copy
|
||||
while ( p < end ) // more bytes to copy?
|
||||
{
|
||||
register int c = (mork_u1) *inMessage++;
|
||||
if ( c == ';' ) // c is the MacsBug ';' metacharacter?
|
||||
c = ':'; // change to ':', rendering harmless in a MacsBug context
|
||||
*p++ = (mork_u1) c;
|
||||
}
|
||||
}
|
||||
|
||||
DebugStr(pascalStr); /* call Mac debugger entry point */
|
||||
}
|
||||
#endif /*MORK_MAC*/
|
||||
/* ----- ----- ----- ----- MORK_MAC ----- ----- ----- ----- */
|
||||
|
||||
void mork_assertion_signal(const char* inMessage)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
mork_mac_break_string(inMessage);
|
||||
#endif /*XP_MAC*/
|
||||
|
||||
#ifdef MORK_WIN
|
||||
// asm { int 3 }
|
||||
NS_ASSERTION(0, inMessage);
|
||||
#endif /*MORK_WIN*/
|
||||
}
|
||||
|
||||
#ifdef MORK_PROVIDE_STDLIB
|
||||
|
||||
MORK_LIB_IMPL(mork_i4)
|
||||
mork_memcmp(const void* inOne, const void* inTwo, mork_size inSize)
|
||||
{
|
||||
register const mork_u1* t = (const mork_u1*) inTwo;
|
||||
register const mork_u1* s = (const mork_u1*) inOne;
|
||||
const mork_u1* end = s + inSize;
|
||||
register mork_i4 delta;
|
||||
|
||||
while ( s < end )
|
||||
{
|
||||
delta = ((mork_i4) *s) - ((mork_i4) *t);
|
||||
if ( delta )
|
||||
return delta;
|
||||
else
|
||||
{
|
||||
++t;
|
||||
++s;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_memcpy(void* outDst, const void* inSrc, mork_size inSize)
|
||||
{
|
||||
register mork_u1* d = (mork_u1*) outDst;
|
||||
mork_u1* end = d + inSize;
|
||||
register const mork_u1* s = ((const mork_u1*) inSrc);
|
||||
|
||||
while ( inSize >= 8 )
|
||||
{
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
|
||||
inSize -= 8;
|
||||
}
|
||||
|
||||
while ( d < end )
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_memmove(void* outDst, const void* inSrc, mork_size inSize)
|
||||
{
|
||||
register mork_u1* d = (mork_u1*) outDst;
|
||||
register const mork_u1* s = (const mork_u1*) inSrc;
|
||||
if ( d != s && inSize ) // copy is necessary?
|
||||
{
|
||||
const mork_u1* srcEnd = s + inSize; // one past last source byte
|
||||
|
||||
if ( d > s && d < srcEnd ) // overlap? need to copy backwards?
|
||||
{
|
||||
s = srcEnd; // start one past last source byte
|
||||
d += inSize; // start one past last dest byte
|
||||
mork_u1* dstBegin = d; // last byte to write is first in dest range
|
||||
while ( d - dstBegin >= 8 )
|
||||
{
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
*--d = *--s;
|
||||
}
|
||||
while ( d > dstBegin )
|
||||
*--d = *--s;
|
||||
}
|
||||
else // can copy forwards without any overlap
|
||||
{
|
||||
mork_u1* dstEnd = d + inSize;
|
||||
while ( dstEnd - d >= 8 )
|
||||
{
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
while ( d < dstEnd )
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_memset(void* outDst, int inByte, mork_size inSize)
|
||||
{
|
||||
register mork_u1* d = (mork_u1*) outDst;
|
||||
mork_u1* end = d + inSize;
|
||||
while ( d < end )
|
||||
*d++ = (mork_u1) inByte;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(void)
|
||||
mork_strcpy(void* outDst, const void* inSrc)
|
||||
{
|
||||
// back up one first to support preincrement
|
||||
register mork_u1* d = ((mork_u1*) outDst) - 1;
|
||||
register const mork_u1* s = ((const mork_u1*) inSrc) - 1;
|
||||
while ( ( *++d = *++s ) != 0 )
|
||||
/* empty */;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(mork_i4)
|
||||
mork_strcmp(const void* inOne, const void* inTwo)
|
||||
{
|
||||
register const mork_u1* t = (const mork_u1*) inTwo;
|
||||
register const mork_u1* s = ((const mork_u1*) inOne);
|
||||
register mork_i4 a;
|
||||
register mork_i4 b;
|
||||
register mork_i4 delta;
|
||||
|
||||
do
|
||||
{
|
||||
a = (mork_i4) *s++;
|
||||
b = (mork_i4) *t++;
|
||||
delta = a - b;
|
||||
}
|
||||
while ( !delta && a && b );
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(mork_i4)
|
||||
mork_strncmp(const void* inOne, const void* inTwo, mork_size inSize)
|
||||
{
|
||||
register const mork_u1* t = (const mork_u1*) inTwo;
|
||||
register const mork_u1* s = (const mork_u1*) inOne;
|
||||
const mork_u1* end = s + inSize;
|
||||
register mork_i4 delta;
|
||||
register mork_i4 a;
|
||||
register mork_i4 b;
|
||||
|
||||
while ( s < end )
|
||||
{
|
||||
a = (mork_i4) *s++;
|
||||
b = (mork_i4) *t++;
|
||||
delta = a - b;
|
||||
if ( delta || !a || !b )
|
||||
return delta;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MORK_LIB_IMPL(mork_size)
|
||||
mork_strlen(const void* inString)
|
||||
{
|
||||
// back up one first to support preincrement
|
||||
register const mork_u1* s = ((const mork_u1*) inString) - 1;
|
||||
while ( *++s ) // preincrement is cheapest
|
||||
/* empty */;
|
||||
|
||||
return s - ((const mork_u1*) inString); // distance from original address
|
||||
}
|
||||
|
||||
#endif /*MORK_PROVIDE_STDLIB*/
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
171
mozilla/db/mork/src/morkConfig.h
Normal file
171
mozilla/db/mork/src/morkConfig.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKCONFIG_
|
||||
#define _MORKCONFIG_ 1
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// { %%%%% begin debug mode options in Mork %%%%%
|
||||
#define MORK_DEBUG 1
|
||||
// } %%%%% end debug mode options in Mork %%%%%
|
||||
|
||||
#ifdef MORK_DEBUG
|
||||
#define MORK_MAX_CODE_COMPILE 1
|
||||
#endif
|
||||
|
||||
// { %%%%% begin platform defs peculiar to Mork %%%%%
|
||||
#ifdef XP_MAC
|
||||
#define MORK_MAC 1
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
#define MORK_OS2 1
|
||||
#endif
|
||||
|
||||
#ifdef XP_PC
|
||||
#define MORK_WIN 1
|
||||
#define XP_WIN 1
|
||||
#endif
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#define MORK_UNIX 1
|
||||
#endif
|
||||
// } %%%%% end platform defs peculiar to Mork %%%%%
|
||||
|
||||
#if defined (MORK_WIN) || defined(MORK_UNIX)
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
#include "errno.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
#define MORK_FILETELL(file) ftell(file)
|
||||
#define MORK_FILESEEK(file, where, how) fseek(file, where, how)
|
||||
#define MORK_FILEREAD(outbuf, insize, file) fread(outbuf, insize, 1, file)
|
||||
#define MORK_FILEFLUSH(file) fflush(file)
|
||||
#define MORK_FILECLOSE(file) fclose(file)
|
||||
#endif /*MORK_WIN*/
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#include "xp_file.h"
|
||||
#include "ctype.h"
|
||||
|
||||
#define MORK_ISPRINT(c) isprint(c)
|
||||
|
||||
#define MORK_FILETELL(file) XP_FileTell(file)
|
||||
#define MORK_FILESEEK(file, where, how) XP_FileSeek(file, where, how)
|
||||
#define MORK_FILEREAD(outbuf, insize, file) XP_FileRead(outbuf, insize, file)
|
||||
#define MORK_FILEFLUSH(file) XP_FileFlush(file)
|
||||
#define MORK_FILECLOSE(file) XP_FileClose(file)
|
||||
#endif /*MORK_MAC*/
|
||||
|
||||
/* ===== ===== ===== ===== line characters ===== ===== ===== ===== */
|
||||
#define mork_kCR '\015'
|
||||
#define mork_kLF '\012'
|
||||
#define mork_kVTAB '\013'
|
||||
#define mork_kFF '\014'
|
||||
#define mork_kTAB '\011'
|
||||
#define mork_kCRLF "\015\012" /* A CR LF equivalent string */
|
||||
|
||||
#ifdef MORK_MAC
|
||||
# define mork_kNewline "\015"
|
||||
# define mork_kNewlineSize 1
|
||||
#else
|
||||
# if defined(MORK_WIN) || defined(MORK_OS2)
|
||||
# define mork_kNewline "\015\012"
|
||||
# define mork_kNewlineSize 2
|
||||
# else
|
||||
# ifdef MORK_UNIX
|
||||
# define mork_kNewline "\012"
|
||||
# define mork_kNewlineSize 1
|
||||
# endif /* MORK_UNIX */
|
||||
# endif /* MORK_WIN */
|
||||
#endif /* MORK_MAC */
|
||||
|
||||
// { %%%%% begin assertion macro %%%%%
|
||||
extern void mork_assertion_signal(const char* inMessage);
|
||||
#define MORK_ASSERTION_SIGNAL(Y) mork_assertion_signal(Y)
|
||||
#define MORK_ASSERT(X) if (!(X)) MORK_ASSERTION_SIGNAL(#X)
|
||||
// } %%%%% end assertion macro %%%%%
|
||||
|
||||
#define MORK_LIB(return) return /*API return declaration*/
|
||||
#define MORK_LIB_IMPL(return) return /*implementation return declaration*/
|
||||
|
||||
// { %%%%% begin standard c utility methods %%%%%
|
||||
/*define MORK_USE_XP_STDLIB 1*/
|
||||
|
||||
#ifdef MORK_MAC
|
||||
#define MORK_PROVIDE_STDLIB 1
|
||||
#endif /*MORK_MAC*/
|
||||
|
||||
#ifdef MORK_WIN
|
||||
#define MORK_USE_C_STDLIB 1
|
||||
#endif /*MORK_WIN*/
|
||||
|
||||
#ifdef MORK_USE_C_STDLIB
|
||||
#define MORK_MEMCMP(src1,src2,size) memcmp(src1,src2,size)
|
||||
#define MORK_MEMCPY(dest,src,size) memcpy(dest,src,size)
|
||||
#define MORK_MEMMOVE(dest,src,size) memmove(dest,src,size)
|
||||
#define MORK_MEMSET(dest,byte,size) memset(dest,byte,size)
|
||||
#define MORK_STRCPY(dest,src) strcpy(dest,src)
|
||||
#define MORK_STRCMP(one,two) strcmp(one,two)
|
||||
#define MORK_STRNCMP(one,two,length) strncmp(one,two,length)
|
||||
#define MORK_STRLEN(string) strlen(string)
|
||||
#endif /*MORK_USE_C_STDLIB*/
|
||||
|
||||
#ifdef MORK_PROVIDE_STDLIB
|
||||
MORK_LIB(mork_i4) mork_memcmp(const void* a, const void* b, mork_size inSize);
|
||||
MORK_LIB(void) mork_memcpy(void* dst, const void* src, mork_size inSize);
|
||||
MORK_LIB(void) mork_memmove(void* dst, const void* src, mork_size inSize);
|
||||
MORK_LIB(void) mork_memset(void* dst, int inByte, mork_size inSize);
|
||||
MORK_LIB(void) mork_strcpy(void* dst, const void* src);
|
||||
MORK_LIB(mork_i4) mork_strcmp(const void* a, const void* b);
|
||||
MORK_LIB(mork_i4) mork_strncmp(const void* a, const void* b, mork_size inSize);
|
||||
MORK_LIB(mork_size) mork_strlen(const void* inString);
|
||||
|
||||
#define MORK_MEMCMP(src1,src2,size) mork_memcmp(src1,src2,size)
|
||||
#define MORK_MEMCPY(dest,src,size) mork_memcpy(dest,src,size)
|
||||
#define MORK_MEMMOVE(dest,src,size) mork_memmove(dest,src,size)
|
||||
#define MORK_MEMSET(dest,byte,size) mork_memset(dest,byte,size)
|
||||
#define MORK_STRCPY(dest,src) mork_strcpy(dest,src)
|
||||
#define MORK_STRCMP(one,two) mork_strcmp(one,two)
|
||||
#define MORK_STRNCMP(one,two,length) mork_strncmp(one,two,length)
|
||||
#define MORK_STRLEN(string) mork_strlen(string)
|
||||
#endif /*MORK_PROVIDE_STDLIB*/
|
||||
|
||||
#ifdef MORK_USE_XP_STDLIB
|
||||
#define MORK_MEMCMP(src1,src2,size) XP_MEMCMP(src1,src2,size)
|
||||
#define MORK_MEMCPY(dest,src,size) XP_MEMCPY(dest,src,size)
|
||||
#define MORK_MEMMOVE(dest,src,size) XP_MEMMOVE(dest,src,size)
|
||||
#define MORK_MEMSET(dest,byte,size) XP_MEMSET(dest,byte,size)
|
||||
#define MORK_STRCPY(dest,src) XP_STRCPY(dest,src)
|
||||
#define MORK_STRCMP(one,two) XP_STRCMP(one,two)
|
||||
#define MORK_STRNCMP(one,two,length) XP_STRNCMP(one,two,length)
|
||||
#define MORK_STRLEN(string) XP_STRLEN(string)
|
||||
#endif /*MORK_USE_XP_STDLIB*/
|
||||
|
||||
|
||||
// } %%%%% end standard c utility methods %%%%%
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKCONFIG_ */
|
||||
98
mozilla/db/mork/src/morkCursor.cpp
Normal file
98
mozilla/db/mork/src/morkCursor.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkCursor::CloseMorkNode(morkEnv* ev) // CloseCursor() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkCursor::~morkCursor() // assert CloseCursor() executed earlier
|
||||
{
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkCursor::morkCursor(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mCursor_Seed( 0 )
|
||||
, mCursor_Pos( -1 )
|
||||
, mCursor_DoFailOnSeedOutOfSync( morkBool_kFalse )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kCursor;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkCursor::CloseCursor(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mCursor_Seed = 0;
|
||||
mCursor_Pos = -1;
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
88
mozilla/db/mork/src/morkCursor.h
Normal file
88
mozilla/db/mork/src/morkCursor.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#define _MORKCURSOR_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kCursor /*i*/ 0x4375 /* ascii 'Cu' */
|
||||
|
||||
class morkCursor : public morkObject { // collection iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkFactory* mObject_Factory; // weak ref to suite factory
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
mork_seed mCursor_Seed;
|
||||
mork_pos mCursor_Pos;
|
||||
mork_bool mCursor_DoFailOnSeedOutOfSync;
|
||||
mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseCursor() only if open
|
||||
virtual ~morkCursor(); // assert that CloseCursor() executed earlier
|
||||
|
||||
public: // morkCursor construction & destruction
|
||||
morkCursor(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap);
|
||||
void CloseCursor(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkCursor(const morkCursor& other);
|
||||
morkCursor& operator=(const morkCursor& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsCursor() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kCursor; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // other cursor methods
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakCursor(morkCursor* me,
|
||||
morkEnv* ev, morkCursor** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongCursor(morkCursor* me,
|
||||
morkEnv* ev, morkCursor** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKCURSOR_ */
|
||||
125
mozilla/db/mork/src/morkDeque.cpp
Normal file
125
mozilla/db/mork/src/morkDeque.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*************************************************************************
|
||||
This software is part of a public domain IronDoc source code distribution,
|
||||
and is provided on an "AS IS" basis, with all risks borne by the consumers
|
||||
or users of the IronDoc software. There are no warranties, guarantees, or
|
||||
promises about quality of any kind; and no remedies for failure exist.
|
||||
|
||||
Permission is hereby granted to use this IronDoc software for any purpose
|
||||
at all, without need for written agreements, without royalty or license
|
||||
fees, and without fees or obligations of any other kind. Anyone can use,
|
||||
copy, change and distribute this software for any purpose, and nothing is
|
||||
required, implicitly or otherwise, in exchange for this usage.
|
||||
|
||||
You cannot apply your own copyright to this software, but otherwise you
|
||||
are encouraged to enjoy the use of this software in any way you see fit.
|
||||
However, it would be rude to remove names of developers from the code.
|
||||
(IronDoc is also known by the short name "Fe" and a longer name "Ferrum",
|
||||
which are used interchangeably with the name IronDoc in the sources.)
|
||||
*************************************************************************/
|
||||
/*
|
||||
* File: morkDeque.cpp
|
||||
* Contains: Ferrum deque (double ended queue (linked list))
|
||||
*
|
||||
* Copied directly from public domain IronDoc, with minor naming tweaks:
|
||||
* Designed and written by David McCusker, but all this code is public domain.
|
||||
* There are no warranties, no guarantees, no promises, and no remedies.
|
||||
*/
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKDEQUE_
|
||||
#include "morkDeque.h"
|
||||
#endif
|
||||
|
||||
/*| RemoveFirst:
|
||||
|*/
|
||||
morkLink*
|
||||
morkDeque::RemoveFirst() /*i*/
|
||||
{
|
||||
morkLink* link = mDeque_Head.mLink_Next;
|
||||
if ( link != &mDeque_Head )
|
||||
{
|
||||
(mDeque_Head.mLink_Next = link->mLink_Next)->mLink_Prev =
|
||||
&mDeque_Head;
|
||||
return link;
|
||||
}
|
||||
return (morkLink*) 0;
|
||||
}
|
||||
|
||||
/*| RemoveLast:
|
||||
|*/
|
||||
morkLink*
|
||||
morkDeque::RemoveLast() /*i*/
|
||||
{
|
||||
morkLink* link = mDeque_Head.mLink_Prev;
|
||||
if ( link != &mDeque_Head )
|
||||
{
|
||||
(mDeque_Head.mLink_Prev = link->mLink_Prev)->mLink_Next =
|
||||
&mDeque_Head;
|
||||
return link;
|
||||
}
|
||||
return (morkLink*) 0;
|
||||
}
|
||||
|
||||
/*| At:
|
||||
|*/
|
||||
morkLink*
|
||||
morkDeque::At(mork_pos index) const /*i*/
|
||||
/* indexes are one based (and not zero based) */
|
||||
{
|
||||
register mork_num count = 0;
|
||||
register morkLink* link;
|
||||
for ( link = this->First(); link; link = this->After(link) )
|
||||
{
|
||||
if ( ++count == index )
|
||||
break;
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
/*| IndexOf:
|
||||
|*/
|
||||
mork_pos
|
||||
morkDeque::IndexOf(const morkLink* member) const /*i*/
|
||||
/* indexes are one based (and not zero based) */
|
||||
/* zero means member is not in deque */
|
||||
{
|
||||
register mork_num count = 0;
|
||||
register const morkLink* link;
|
||||
for ( link = this->First(); link; link = this->After(link) )
|
||||
{
|
||||
++count;
|
||||
if ( member == link )
|
||||
return count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*| Length:
|
||||
|*/
|
||||
mork_num
|
||||
morkDeque::Length() const /*i*/
|
||||
{
|
||||
register mork_num count = 0;
|
||||
register morkLink* link;
|
||||
for ( link = this->First(); link; link = this->After(link) )
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
/*| LengthCompare:
|
||||
|*/
|
||||
int
|
||||
morkDeque::LengthCompare(mork_num c) const /*i*/
|
||||
{
|
||||
register mork_num count = 0;
|
||||
register const morkLink* link;
|
||||
for ( link = this->First(); link; link = this->After(link) )
|
||||
{
|
||||
if ( ++count > c )
|
||||
return 1;
|
||||
}
|
||||
return ( count == c )? 0 : -1;
|
||||
}
|
||||
149
mozilla/db/mork/src/morkDeque.h
Normal file
149
mozilla/db/mork/src/morkDeque.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*************************************************************************
|
||||
This software is part of a public domain IronDoc source code distribution,
|
||||
and is provided on an "AS IS" basis, with all risks borne by the consumers
|
||||
or users of the IronDoc software. There are no warranties, guarantees, or
|
||||
promises about quality of any kind; and no remedies for failure exist.
|
||||
|
||||
Permission is hereby granted to use this IronDoc software for any purpose
|
||||
at all, without need for written agreements, without royalty or license
|
||||
fees, and without fees or obligations of any other kind. Anyone can use,
|
||||
copy, change and distribute this software for any purpose, and nothing is
|
||||
required, implicitly or otherwise, in exchange for this usage.
|
||||
|
||||
You cannot apply your own copyright to this software, but otherwise you
|
||||
are encouraged to enjoy the use of this software in any way you see fit.
|
||||
However, it would be rude to remove names of developers from the code.
|
||||
(IronDoc is also known by the short name "Fe" and a longer name "Ferrum",
|
||||
which are used interchangeably with the name IronDoc in the sources.)
|
||||
*************************************************************************/
|
||||
/*
|
||||
* File: morkDeque.h
|
||||
* Contains: Ferrum deque (double ended queue (linked list))
|
||||
*
|
||||
* Copied directly from public domain IronDoc, with minor naming tweaks:
|
||||
* Designed and written by David McCusker, but all this code is public domain.
|
||||
* There are no warranties, no guarantees, no promises, and no remedies.
|
||||
*/
|
||||
|
||||
#ifndef _MORKDEQUE_
|
||||
#define _MORKDEQUE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
/*=============================================================================
|
||||
* morkLink: linked list node embedded in objs to allow insertion in morkDeques
|
||||
*/
|
||||
|
||||
class morkLink /*d*/ {
|
||||
public:
|
||||
morkLink* mLink_Next;
|
||||
morkLink* mLink_Prev;
|
||||
|
||||
public:
|
||||
morkLink* Next() const { return mLink_Next; }
|
||||
morkLink* Prev() const { return mLink_Prev; }
|
||||
|
||||
void SelfRefer() { mLink_Next = mLink_Prev = this; }
|
||||
void Clear() { mLink_Next = mLink_Prev = 0; }
|
||||
|
||||
void AddBefore(morkLink* old)
|
||||
{
|
||||
((old)->mLink_Prev->mLink_Next = (this))->mLink_Prev = (old)->mLink_Prev;
|
||||
((this)->mLink_Next = (old))->mLink_Prev = this;
|
||||
}
|
||||
|
||||
void AddAfter(morkLink* old)
|
||||
{
|
||||
((old)->mLink_Next->mLink_Prev = (this))->mLink_Next = (old)->mLink_Next;
|
||||
((this)->mLink_Prev = (old))->mLink_Next = this;
|
||||
}
|
||||
|
||||
void Remove()
|
||||
{
|
||||
(mLink_Prev->mLink_Next = mLink_Next)->mLink_Prev = mLink_Prev;
|
||||
}
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkDeque: doubly linked list modeled after VAX queue instructions
|
||||
*/
|
||||
|
||||
class morkDeque /*d*/ {
|
||||
public:
|
||||
morkLink mDeque_Head;
|
||||
|
||||
public: // construction
|
||||
morkDeque() { mDeque_Head.SelfRefer(); }
|
||||
|
||||
public:// methods
|
||||
morkLink* RemoveFirst();
|
||||
|
||||
morkLink* RemoveLast();
|
||||
|
||||
morkLink* At(mork_pos index) const ; /* one-based, not zero-based */
|
||||
|
||||
mork_pos IndexOf(const morkLink* inMember) const;
|
||||
/* one-based index ; zero means member is not in deque */
|
||||
|
||||
mork_num Length() const;
|
||||
|
||||
/* the following method is more efficient for long lists: */
|
||||
int LengthCompare(mork_num inCount) const;
|
||||
/* -1: length < count, 0: length == count, 1: length > count */
|
||||
|
||||
public: // inlines
|
||||
|
||||
mork_bool IsEmpty()const
|
||||
{ return (mDeque_Head.mLink_Next == (morkLink*) &mDeque_Head); }
|
||||
|
||||
morkLink* After(const morkLink* old) const
|
||||
{ return (((old)->mLink_Next != &mDeque_Head)?
|
||||
(old)->mLink_Next : (morkLink*) 0); }
|
||||
|
||||
morkLink* Before(const morkLink* old) const
|
||||
{ return (((old)->mLink_Prev != &mDeque_Head)?
|
||||
(old)->mLink_Prev : (morkLink*) 0); }
|
||||
|
||||
morkLink* First() const
|
||||
{ return ((mDeque_Head.mLink_Next != &mDeque_Head)?
|
||||
mDeque_Head.mLink_Next : (morkLink*) 0); }
|
||||
|
||||
morkLink* Last() const
|
||||
{ return ((mDeque_Head.mLink_Prev != &mDeque_Head)?
|
||||
mDeque_Head.mLink_Prev : (morkLink*) 0); }
|
||||
|
||||
/*
|
||||
From IronDoc documentation for AddFirst:
|
||||
+--------+ +--------+ +--------+ +--------+ +--------+
|
||||
| h.next |-->| b.next | | h.next |-->| a.next |-->| b.next |
|
||||
+--------+ +--------+ ==> +--------+ +--------+ +--------+
|
||||
| h.prev |<--| b.prev | | h.prev |<--| a.prev |<--| b.prev |
|
||||
+--------+ +--------+ +--------+ +--------+ +--------+
|
||||
*/
|
||||
|
||||
void AddFirst(morkLink* in) /*i*/
|
||||
{
|
||||
( (mDeque_Head.mLink_Next->mLink_Prev =
|
||||
(in))->mLink_Next = mDeque_Head.mLink_Next,
|
||||
((in)->mLink_Prev = &mDeque_Head)->mLink_Next = (in) );
|
||||
}
|
||||
/*
|
||||
From IronDoc documentation for AddLast:
|
||||
+--------+ +--------+ +--------+ +--------+ +--------+
|
||||
| y.next |-->| h.next | | y.next |-->| z.next |-->| h.next |
|
||||
+--------+ +--------+ ==> +--------+ +--------+ +--------+
|
||||
| y.prev |<--| h.prev | | y.prev |<--| z.prev |<--| h.prev |
|
||||
+--------+ +--------+ +--------+ +--------+ +--------+
|
||||
*/
|
||||
|
||||
void AddLast(morkLink* in)
|
||||
{
|
||||
( (mDeque_Head.mLink_Prev->mLink_Next =
|
||||
(in))->mLink_Prev = mDeque_Head.mLink_Prev,
|
||||
((in)->mLink_Next = &mDeque_Head)->mLink_Prev = (in) );
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _MORKDEQUE_ */
|
||||
406
mozilla/db/mork/src/morkEnv.cpp
Normal file
406
mozilla/db/mork/src/morkEnv.cpp
Normal file
@@ -0,0 +1,406 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINENV_
|
||||
#include "orkinEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFACTORY_
|
||||
#include "morkFactory.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkEnv::CloseMorkNode(morkEnv* ev) /*i*/ // CloseEnv() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseEnv(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkEnv::~morkEnv() /*i*/ // assert CloseEnv() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mEnv_SelfAsMdbEnv==0);
|
||||
MORK_ASSERT(mEnv_ErrorHook==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkEnv::morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap)
|
||||
: morkObject(inUsage, ioHeap)
|
||||
, mEnv_Factory( ioFactory )
|
||||
, mEnv_Heap( ioSlotHeap )
|
||||
|
||||
, mEnv_SelfAsMdbEnv( 0 )
|
||||
, mEnv_ErrorHook( 0 )
|
||||
, mEnv_HandlePool( 0 )
|
||||
|
||||
, mEnv_ErrorCount( 0 )
|
||||
, mEnv_WarningCount( 0 )
|
||||
|
||||
, mEnv_ErrorCode( 0 )
|
||||
|
||||
, mEnv_DoTrace( morkBool_kFalse )
|
||||
, mEnv_AutoClear( morkAble_kDisabled )
|
||||
, mEnv_ShouldAbort( morkBool_kFalse )
|
||||
{
|
||||
MORK_ASSERT(ioSlotHeap && ioFactory );
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
// mEnv_Heap is NOT refcounted:
|
||||
// nsIMdbHeap_SlotStrongHeap(ioSlotHeap, this, &mEnv_Heap);
|
||||
|
||||
mEnv_HandlePool = new morkPool(morkUsage::kGlobal,
|
||||
(nsIMdbHeap*) 0, ioSlotHeap);
|
||||
|
||||
MORK_ASSERT(mEnv_HandlePool);
|
||||
if ( mEnv_HandlePool && this->Good() )
|
||||
{
|
||||
mNode_Derived = morkDerived_kEnv;
|
||||
mNode_Refs += morkEnv_kWeakRefCountEnvBonus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkEnv::morkEnv(morkEnv* ev, /*i*/
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbEnv* inSelfAsMdbEnv,
|
||||
morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mEnv_Factory( ioFactory )
|
||||
, mEnv_Heap( ioSlotHeap )
|
||||
|
||||
, mEnv_SelfAsMdbEnv( inSelfAsMdbEnv )
|
||||
, mEnv_ErrorHook( 0 )
|
||||
, mEnv_HandlePool( 0 )
|
||||
|
||||
, mEnv_ErrorCount( 0 )
|
||||
, mEnv_WarningCount( 0 )
|
||||
|
||||
, mEnv_ErrorCode( 0 )
|
||||
|
||||
, mEnv_DoTrace( morkBool_kFalse )
|
||||
, mEnv_AutoClear( morkAble_kDisabled )
|
||||
{
|
||||
// $$$ do we need to refcount the inSelfAsMdbEnv nsIMdbEnv??
|
||||
|
||||
if ( ioFactory && inSelfAsMdbEnv && ioSlotHeap)
|
||||
{
|
||||
// mEnv_Heap is NOT refcounted:
|
||||
// nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mEnv_Heap);
|
||||
|
||||
mEnv_HandlePool = new(*ioSlotHeap, ev) morkPool(ev,
|
||||
morkUsage::kHeap, ioSlotHeap, ioSlotHeap);
|
||||
|
||||
MORK_ASSERT(mEnv_HandlePool);
|
||||
if ( mEnv_HandlePool && ev->Good() )
|
||||
{
|
||||
mNode_Derived = morkDerived_kEnv;
|
||||
mNode_Refs += morkEnv_kWeakRefCountEnvBonus;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkEnv::CloseEnv(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
// $$$ release mEnv_SelfAsMdbEnv??
|
||||
// $$$ release mEnv_ErrorHook??
|
||||
|
||||
mEnv_SelfAsMdbEnv = 0;
|
||||
mEnv_ErrorHook = 0;
|
||||
|
||||
// mEnv_Factory is NOT refcounted
|
||||
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
mork_size
|
||||
morkEnv::OidAsHex(void* outBuf, const mdbOid& inOid)
|
||||
// sprintf(buf, "%lX:^%lX", (long) inOid.mOid_Id, (long) inOid.mOid_Scope);
|
||||
{
|
||||
mork_u1* p = (mork_u1*) outBuf;
|
||||
mork_size idSize = this->TokenAsHex(p, inOid.mOid_Id);
|
||||
p += idSize;
|
||||
*p++ = ':';
|
||||
*p++ = '^';
|
||||
mork_size scopeSize = this->TokenAsHex(p, inOid.mOid_Scope);
|
||||
return idSize + scopeSize + 2;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkEnv::TokenAsHex(void* outBuf, mork_token inToken)
|
||||
// TokenAsHex() is the same as sprintf(outBuf, "%lX", (long) inToken);
|
||||
{
|
||||
static const char* morkEnv_kHexDigits = "0123456789ABCDEF";
|
||||
char* p = (char*) outBuf;
|
||||
char* end = p + 32; // write no more than 32 digits for safety
|
||||
if ( inToken )
|
||||
{
|
||||
// first write all the hex digits in backwards order:
|
||||
while ( p < end && inToken ) // more digits to write?
|
||||
{
|
||||
*p++ = morkEnv_kHexDigits[ inToken & 0x0F ]; // low four bits
|
||||
inToken >>= 4; // we fervently hope this does not sign extend
|
||||
}
|
||||
*p = 0; // end the string with a null byte
|
||||
char* s = (char*) outBuf; // first byte in string
|
||||
mork_size size = p - s; // distance from start
|
||||
|
||||
// now reverse the string in place:
|
||||
// note that p starts on the null byte, so we need predecrement:
|
||||
while ( --p > s ) // need to swap another byte in the string?
|
||||
{
|
||||
char c = *p; // temp for swap
|
||||
*p = *s;
|
||||
*s++ = c; // move s forward here, and p backward in the test
|
||||
}
|
||||
return size;
|
||||
}
|
||||
else // special case for zero integer
|
||||
{
|
||||
*p++ = '0'; // write a zero digit
|
||||
*p = 0; // end with a null byte
|
||||
return 1; // one digit in hex representation
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
morkEnv::CopyString(nsIMdbHeap* ioHeap, const char* inString)
|
||||
{
|
||||
char* outString = 0;
|
||||
if ( ioHeap && inString )
|
||||
{
|
||||
mork_size size = MORK_STRLEN(inString) + 1;
|
||||
ioHeap->Alloc(this->AsMdbEnv(), size, (void**) &outString);
|
||||
if ( outString )
|
||||
MORK_STRCPY(outString, inString);
|
||||
}
|
||||
else
|
||||
this->NilPointerError();
|
||||
return outString;
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::FreeString(nsIMdbHeap* ioHeap, char* ioString)
|
||||
{
|
||||
if ( ioHeap )
|
||||
{
|
||||
if ( ioString )
|
||||
ioHeap->Free(this->AsMdbEnv(), ioString);
|
||||
}
|
||||
else
|
||||
this->NilPointerError();
|
||||
}
|
||||
|
||||
nsIMdbEnv*
|
||||
morkEnv::AcquireEnvHandle(morkEnv* ev)
|
||||
{
|
||||
nsIMdbEnv* outEnv = 0;
|
||||
orkinEnv* e = (orkinEnv*) mObject_Handle;
|
||||
if ( e ) // have an old handle?
|
||||
e->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
e = orkinEnv::MakeEnv(ev, this);
|
||||
mObject_Handle = e;
|
||||
}
|
||||
if ( e )
|
||||
outEnv = e;
|
||||
return outEnv;
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::NewErrorAndCode(const char* inString, mork_u2 inCode)
|
||||
{
|
||||
MORK_ASSERT(morkBool_kFalse); // get developer's attention
|
||||
|
||||
++mEnv_ErrorCount;
|
||||
mEnv_ErrorCode = (inCode)? inCode: morkEnv_kGenericError;
|
||||
|
||||
if ( mEnv_ErrorHook )
|
||||
mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString);
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::NewError(const char* inString)
|
||||
{
|
||||
MORK_ASSERT(morkBool_kFalse); // get developer's attention
|
||||
|
||||
++mEnv_ErrorCount;
|
||||
mEnv_ErrorCode = morkEnv_kGenericError;
|
||||
|
||||
if ( mEnv_ErrorHook )
|
||||
mEnv_ErrorHook->OnErrorString(this->AsMdbEnv(), inString);
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::NewWarning(const char* inString)
|
||||
{
|
||||
MORK_ASSERT(morkBool_kFalse); // get developer's attention
|
||||
|
||||
++mEnv_WarningCount;
|
||||
if ( mEnv_ErrorHook )
|
||||
mEnv_ErrorHook->OnWarningString(this->AsMdbEnv(), inString);
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::StubMethodOnlyError()
|
||||
{
|
||||
this->NewError("method is stub only");
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::OutOfMemoryError()
|
||||
{
|
||||
this->NewError("out of memory");
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::NilPointerError()
|
||||
{
|
||||
this->NewError("nil pointer");
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::NewNonEnvError()
|
||||
{
|
||||
this->NewError("non-env instance");
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::NilEnvSlotError()
|
||||
{
|
||||
if ( !mEnv_HandlePool || !mEnv_Factory )
|
||||
{
|
||||
if ( !mEnv_HandlePool )
|
||||
this->NewError("nil mEnv_HandlePool");
|
||||
if ( !mEnv_Factory )
|
||||
this->NewError("nil mEnv_Factory");
|
||||
}
|
||||
else
|
||||
this->NewError("unknown nil env slot");
|
||||
}
|
||||
|
||||
|
||||
void morkEnv::NonEnvTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkEnv");
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::ClearMorkErrorsAndWarnings()
|
||||
{
|
||||
mEnv_ErrorCount = 0;
|
||||
mEnv_WarningCount = 0;
|
||||
mEnv_ErrorCode = 0;
|
||||
mEnv_ShouldAbort = morkBool_kFalse;
|
||||
}
|
||||
|
||||
void
|
||||
morkEnv::AutoClearMorkErrorsAndWarnings()
|
||||
{
|
||||
if ( this->DoAutoClear() )
|
||||
{
|
||||
mEnv_ErrorCount = 0;
|
||||
mEnv_WarningCount = 0;
|
||||
mEnv_ErrorCode = 0;
|
||||
mEnv_ShouldAbort = morkBool_kFalse;
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ morkEnv*
|
||||
morkEnv::FromMdbEnv(nsIMdbEnv* ioEnv) // dynamic type checking
|
||||
{
|
||||
morkEnv* outEnv = 0;
|
||||
if ( ioEnv )
|
||||
{
|
||||
// Note this cast is expected to perform some address adjustment of the
|
||||
// pointer, so oenv likely does not equal ioEnv. Do not cast to void*
|
||||
// first to force an exactly equal pointer (we tried it and it's wrong).
|
||||
orkinEnv* oenv = (orkinEnv*) ioEnv;
|
||||
if ( oenv->IsHandle() )
|
||||
{
|
||||
if ( oenv->IsOpenNode() )
|
||||
{
|
||||
morkEnv* ev = (morkEnv*) oenv->mHandle_Object;
|
||||
if ( ev && ev->IsEnv() )
|
||||
{
|
||||
if ( ev->DoAutoClear() )
|
||||
{
|
||||
ev->mEnv_ErrorCount = 0;
|
||||
ev->mEnv_WarningCount = 0;
|
||||
ev->mEnv_ErrorCode = 0;
|
||||
}
|
||||
outEnv = ev;
|
||||
}
|
||||
else
|
||||
MORK_ASSERT(outEnv);
|
||||
}
|
||||
else
|
||||
MORK_ASSERT(outEnv);
|
||||
}
|
||||
else
|
||||
MORK_ASSERT(outEnv);
|
||||
}
|
||||
else
|
||||
MORK_ASSERT(outEnv);
|
||||
return outEnv;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
187
mozilla/db/mork/src/morkEnv.h
Normal file
187
mozilla/db/mork/src/morkEnv.h
Normal file
@@ -0,0 +1,187 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#define _MORKENV_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kEnv /*i*/ 0x4576 /* ascii 'Ev' */
|
||||
|
||||
#define morkEnv_kNoError 0 /* no error has happened */
|
||||
|
||||
#define morkEnv_kGenericError 1 /* non-specific error code */
|
||||
#define morkEnv_kNonEnvTypeError 2 /* morkEnv::IsEnv() is false */
|
||||
|
||||
#define morkEnv_kStubMethodOnlyError 3
|
||||
#define morkEnv_kOutOfMemoryError 4
|
||||
#define morkEnv_kNilPointerError 5
|
||||
#define morkEnv_kNewNonEnvError 6
|
||||
#define morkEnv_kNilEnvSlotError 7
|
||||
|
||||
#define morkEnv_kBadFactoryError 8
|
||||
#define morkEnv_kBadFactoryEnvError 9
|
||||
#define morkEnv_kBadEnvError 10
|
||||
|
||||
#define morkEnv_kNonHandleTypeError 11
|
||||
#define morkEnv_kNonOpenNodeError 12
|
||||
|
||||
#define morkEnv_kWeakRefCountEnvBonus 16 /* try to leak all env instances */
|
||||
|
||||
/*| morkEnv:
|
||||
|*/
|
||||
class morkEnv : public morkObject {
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkHandle* mObject_Handle; // weak ref to handle for this object
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkFactory* mEnv_Factory; // NON-refcounted factory
|
||||
nsIMdbHeap* mEnv_Heap; // NON-refcounted heap
|
||||
|
||||
nsIMdbEnv* mEnv_SelfAsMdbEnv;
|
||||
nsIMdbErrorHook* mEnv_ErrorHook;
|
||||
|
||||
morkPool* mEnv_HandlePool; // pool for re-using handles
|
||||
|
||||
mork_u2 mEnv_ErrorCount;
|
||||
mork_u2 mEnv_WarningCount;
|
||||
|
||||
mork_u4 mEnv_ErrorCode; // simple basis for mdb_err style errors
|
||||
|
||||
mork_bool mEnv_DoTrace;
|
||||
mork_able mEnv_AutoClear;
|
||||
mork_bool mEnv_ShouldAbort;
|
||||
mork_bool mEnv_Pad;
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseEnv() only if open
|
||||
virtual ~morkEnv(); // assert that CloseEnv() executed earlier
|
||||
|
||||
public: // morkEnv construction & destruction
|
||||
morkEnv(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkFactory* ioFactory, nsIMdbHeap* ioSlotHeap);
|
||||
morkEnv(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
nsIMdbEnv* inSelfAsMdbEnv, morkFactory* ioFactory,
|
||||
nsIMdbHeap* ioSlotHeap);
|
||||
void CloseEnv(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkEnv(const morkEnv& other);
|
||||
morkEnv& operator=(const morkEnv& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsEnv() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kEnv; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // utility env methods
|
||||
|
||||
mork_size TokenAsHex(void* outBuf, mork_token inToken);
|
||||
// TokenAsHex() is the same as sprintf(outBuf, "%lX", (long) inToken);
|
||||
|
||||
mork_size OidAsHex(void* outBuf, const mdbOid& inOid);
|
||||
// sprintf(buf, "%lX:^%lX", (long) inOid.mOid_Id, (long) inOid.mOid_Scope);
|
||||
|
||||
char* CopyString(nsIMdbHeap* ioHeap, const char* inString);
|
||||
void FreeString(nsIMdbHeap* ioHeap, char* ioString);
|
||||
|
||||
public: // other env methods
|
||||
|
||||
nsIMdbEnv* AcquireEnvHandle(morkEnv* ev); // mObject_Handle
|
||||
|
||||
// alloc and free individual handles in mEnv_HandlePool:
|
||||
morkHandleFace* NewHandle(mork_size inSize)
|
||||
{ return mEnv_HandlePool->NewHandle(this, inSize); }
|
||||
|
||||
void ZapHandle(morkHandleFace* ioHandle)
|
||||
{ mEnv_HandlePool->ZapHandle(this, ioHandle); }
|
||||
|
||||
void EnableAutoClear() { mEnv_AutoClear = morkAble_kEnabled; }
|
||||
void DisableAutoClear() { mEnv_AutoClear = morkAble_kDisabled; }
|
||||
|
||||
mork_bool DoAutoClear() const
|
||||
{ return mEnv_AutoClear == morkAble_kEnabled; }
|
||||
|
||||
void NewErrorAndCode(const char* inString, mork_u2 inCode);
|
||||
void NewError(const char* inString);
|
||||
void NewWarning(const char* inString);
|
||||
|
||||
void ClearMorkErrorsAndWarnings(); // clear both errors & warnings
|
||||
void AutoClearMorkErrorsAndWarnings(); // clear if auto is enabled
|
||||
|
||||
void StubMethodOnlyError();
|
||||
void OutOfMemoryError();
|
||||
void NilPointerError();
|
||||
void NewNonEnvError();
|
||||
void NilEnvSlotError();
|
||||
|
||||
void NonEnvTypeError(morkEnv* ev);
|
||||
|
||||
// canonical env convenience methods to check for presence of errors:
|
||||
mork_bool Good() const { return ( mEnv_ErrorCount == 0 ); }
|
||||
mork_bool Bad() const { return ( mEnv_ErrorCount != 0 ); }
|
||||
|
||||
nsIMdbEnv* AsMdbEnv() { return mEnv_SelfAsMdbEnv; }
|
||||
static morkEnv* FromMdbEnv(nsIMdbEnv* ioEnv); // dynamic type checking
|
||||
|
||||
mork_u2 ErrorCode() const { return mEnv_ErrorCode; }
|
||||
|
||||
mdb_err AsErr() const { return (mdb_err) mEnv_ErrorCode; }
|
||||
//mdb_err AsErr() const { return (mdb_err) ( mEnv_ErrorCount != 0 ); }
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakEnv(morkEnv* me,
|
||||
morkEnv* ev, morkEnv** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongEnv(morkEnv* me,
|
||||
morkEnv* ev, morkEnv** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKENV_ */
|
||||
159
mozilla/db/mork/src/morkFactory.cpp
Normal file
159
mozilla/db/mork/src/morkFactory.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFACTORY_
|
||||
#include "morkFactory.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINFACTORY_
|
||||
#include "orkinFactory.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINHEAP_
|
||||
#include "orkinHeap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkFactory::CloseMorkNode(morkEnv* ev) /*i*/ // CloseFactory() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseFactory(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkFactory::~morkFactory() /*i*/ // assert CloseFactory() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mFactory_Env.IsShutNode());
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkFactory::morkFactory() // uses orkinHeap
|
||||
: morkObject(morkUsage::kGlobal, (nsIMdbHeap*) 0)
|
||||
, mFactory_Heap()
|
||||
, mFactory_Env(morkUsage::kMember, (nsIMdbHeap*) 0, this,
|
||||
new orkinHeap())
|
||||
{
|
||||
if ( mFactory_Env.Good() )
|
||||
{
|
||||
mNode_Derived = morkDerived_kFactory;
|
||||
mNode_Refs += morkFactory_kWeakRefCountBonus;
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkFactory::morkFactory(nsIMdbHeap* ioHeap)
|
||||
: morkObject(morkUsage::kHeap, ioHeap)
|
||||
, mFactory_Heap()
|
||||
, mFactory_Env(morkUsage::kMember, (nsIMdbHeap*) 0, this, ioHeap)
|
||||
{
|
||||
if ( mFactory_Env.Good() )
|
||||
{
|
||||
mNode_Derived = morkDerived_kFactory;
|
||||
mNode_Refs += morkFactory_kWeakRefCountBonus;
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkFactory::morkFactory(morkEnv* ev, /*i*/
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mFactory_Env(morkUsage::kMember, (nsIMdbHeap*) 0, this, ioHeap)
|
||||
, mFactory_Heap()
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mNode_Derived = morkDerived_kFactory;
|
||||
mNode_Refs += morkFactory_kWeakRefCountBonus;
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkFactory::CloseFactory(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mFactory_Env.CloseMorkNode(ev);
|
||||
this->CloseObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
nsIMdbFactory*
|
||||
morkFactory::AcquireFactoryHandle(morkEnv* ev) // mObject_Handle
|
||||
{
|
||||
nsIMdbFactory* outFactory = 0;
|
||||
orkinFactory* f = (orkinFactory*) mObject_Handle;
|
||||
if ( f ) // have an old handle?
|
||||
f->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
f = orkinFactory::MakeFactory(ev, this);
|
||||
mObject_Handle = f;
|
||||
}
|
||||
if ( f )
|
||||
outFactory = f;
|
||||
return outFactory;
|
||||
}
|
||||
|
||||
void
|
||||
morkFactory::NonFactoryTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkFactory");
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
117
mozilla/db/mork/src/morkFactory.h
Normal file
117
mozilla/db/mork/src/morkFactory.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKFACTORY_
|
||||
#define _MORKFACTORY_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINHEAP_
|
||||
#include "orkinHeap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class nsIMdbFactory;
|
||||
|
||||
#define morkDerived_kFactory /*i*/ 0x4663 /* ascii 'Fc' */
|
||||
#define morkFactory_kWeakRefCountBonus 16 /* try to leak all factories */
|
||||
|
||||
/*| morkFactory:
|
||||
|*/
|
||||
class morkFactory : public morkObject { // nsIMdbObject
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkHandle* mObject_Handle; // weak ref to handle for this object
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkEnv mFactory_Env; // private env instance used internally
|
||||
orkinHeap mFactory_Heap;
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkFactory virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseFactory() only if open
|
||||
virtual ~morkFactory(); // assert that CloseFactory() executed earlier
|
||||
|
||||
public: // morkYarn construction & destruction
|
||||
morkFactory(); // uses orkinHeap
|
||||
morkFactory(nsIMdbHeap* ioHeap); // caller supplied heap
|
||||
morkFactory(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap);
|
||||
void CloseFactory(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
|
||||
public: // morkNode memory management operators
|
||||
void* operator new(size_t inSize)
|
||||
{ return ::operator new(inSize); }
|
||||
|
||||
void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev)
|
||||
{ return morkNode::MakeNew(inSize, ioHeap, ev); }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
// do NOT call delete on morkNode instances. Call ZapOld() instead.
|
||||
|
||||
private: // copying is not allowed
|
||||
morkFactory(const morkFactory& other);
|
||||
morkFactory& operator=(const morkFactory& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsFactory() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kFactory; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // other factory methods
|
||||
|
||||
nsIMdbFactory* AcquireFactoryHandle(morkEnv* ev); // mObject_Handle
|
||||
|
||||
void NonFactoryTypeError(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakFactory(morkFactory* me,
|
||||
morkEnv* ev, morkFactory** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongFactory(morkFactory* me,
|
||||
morkEnv* ev, morkFactory** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKFACTORY_ */
|
||||
716
mozilla/db/mork/src/morkFile.cpp
Normal file
716
mozilla/db/mork/src/morkFile.cpp
Normal file
@@ -0,0 +1,716 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkFile::CloseMorkNode(morkEnv* ev) // CloseFile() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseFile(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkFile::~morkFile() // assert CloseFile() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mFile_Frozen==0);
|
||||
MORK_ASSERT(mFile_DoTrace==0);
|
||||
MORK_ASSERT(mFile_IoOpen==0);
|
||||
MORK_ASSERT(mFile_Active==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkFile::morkFile(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mFile_Frozen( 0 )
|
||||
, mFile_DoTrace( 0 )
|
||||
, mFile_IoOpen( 0 )
|
||||
, mFile_Active( 0 )
|
||||
|
||||
, mFile_SlotHeap( 0 )
|
||||
, mFile_Name( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mFile_SlotHeap);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kFile;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkFile::CloseFile(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mFile_Frozen = 0;
|
||||
mFile_DoTrace = 0;
|
||||
mFile_IoOpen = 0;
|
||||
mFile_Active = 0;
|
||||
|
||||
if ( mFile_Name )
|
||||
this->SetFileName(ev, (const char*) 0);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*virtual*/ void
|
||||
morkFile::BecomeTrunk(morkEnv* ev)
|
||||
// If this file is a file version branch created by calling AcquireBud(),
|
||||
// BecomeTrunk() causes this file's content to replace the original
|
||||
// file's content, typically by assuming the original file's identity.
|
||||
// This default implementation of BecomeTrunk() does nothing, and this
|
||||
// is appropriate behavior for files which are not branches, and is
|
||||
// also the right behavior for files returned from AcquireBud() which are
|
||||
// in fact the original file that has been truncated down to zero length.
|
||||
{
|
||||
this->Flush(ev);
|
||||
}
|
||||
|
||||
/*static*/ morkFile*
|
||||
morkFile::OpenOldFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath, mork_bool inFrozen)
|
||||
// Choose some subclass of morkFile to instantiate, in order to read
|
||||
// (and write if not frozen) the file known by inFilePath. The file
|
||||
// returned should be open and ready for use, and presumably positioned
|
||||
// at the first byte position of the file. The exact manner in which
|
||||
// files must be opened is considered a subclass specific detail, and
|
||||
// other portions or Mork source code don't want to know how it's done.
|
||||
{
|
||||
return morkStdioFile::OpenOldStdioFile(ev, ioHeap, inFilePath, inFrozen);
|
||||
}
|
||||
|
||||
/*static*/ morkFile*
|
||||
morkFile::CreateNewFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath)
|
||||
// Choose some subclass of morkFile to instantiate, in order to read
|
||||
// (and write if not frozen) the file known by inFilePath. The file
|
||||
// returned should be created and ready for use, and presumably positioned
|
||||
// at the first byte position of the file. The exact manner in which
|
||||
// files must be opened is considered a subclass specific detail, and
|
||||
// other portions or Mork source code don't want to know how it's done.
|
||||
{
|
||||
return morkStdioFile::CreateNewStdioFile(ev, ioHeap, inFilePath);
|
||||
}
|
||||
|
||||
void
|
||||
morkFile::NewMissingIoError(morkEnv* ev) const
|
||||
{
|
||||
ev->NewError("file missing io");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkFile::NilSlotHeapError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mFile_SlotHeap");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkFile::NilFileNameError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mFile_Name");
|
||||
}
|
||||
|
||||
void
|
||||
morkFile::SetFileName(morkEnv* ev, const char* inName) // inName can be nil
|
||||
{
|
||||
nsIMdbHeap* heap = mFile_SlotHeap;
|
||||
if ( heap )
|
||||
{
|
||||
char* name = mFile_Name;
|
||||
if ( name )
|
||||
{
|
||||
mFile_Name = 0;
|
||||
ev->FreeString(heap, name);
|
||||
}
|
||||
if ( ev->Good() && inName )
|
||||
mFile_Name = ev->CopyString(heap, inName);
|
||||
}
|
||||
else
|
||||
this->NilSlotHeapError(ev);
|
||||
}
|
||||
|
||||
void
|
||||
morkFile::NewFileDownError(morkEnv* ev) const
|
||||
// call NewFileDownError() when either IsOpenAndActiveFile()
|
||||
// is false, or when IsOpenActiveAndMutableFile() is false.
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
if ( this->FileActive() )
|
||||
{
|
||||
if ( this->FileFrozen() )
|
||||
{
|
||||
ev->NewError("file frozen");
|
||||
}
|
||||
else
|
||||
ev->NewError("unknown file problem");
|
||||
}
|
||||
else
|
||||
ev->NewError("file not active");
|
||||
}
|
||||
else
|
||||
ev->NewError("file not open");
|
||||
}
|
||||
|
||||
void
|
||||
morkFile::NewFileErrnoError(morkEnv* ev) const
|
||||
// call NewFileErrnoError() to convert std C errno into AB fault
|
||||
{
|
||||
ev->NewError("errno"); // maybe pass value of strerror() instead
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` newlines ````` ````` ````` `````
|
||||
|
||||
#ifdef MORK_MAC
|
||||
static const char* morkFile_kNewlines =
|
||||
"\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015\015";
|
||||
# define morkFile_kNewlinesCount 16
|
||||
#else
|
||||
# if defined(MORK_WIN) || defined(MORK_OS2)
|
||||
static const char* morkFile_kNewlines =
|
||||
"\015\012\015\012\015\012\015\012\015\012\015\012\015\012\015\012";
|
||||
# define morkFile_kNewlinesCount 8
|
||||
# else
|
||||
# ifdef MORK_UNIX
|
||||
static const char* morkFile_kNewlines =
|
||||
"\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012\012";
|
||||
# define morkFile_kNewlinesCount 16
|
||||
# endif /* MORK_UNIX */
|
||||
# endif /* MORK_WIN */
|
||||
#endif /* MORK_MAC */
|
||||
|
||||
mork_size
|
||||
morkFile::WriteNewlines(morkEnv* ev, mork_count inNewlines)
|
||||
// WriteNewlines() returns the number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
while ( inNewlines && ev->Good() ) // more newlines to write?
|
||||
{
|
||||
mork_u4 quantum = inNewlines;
|
||||
if ( quantum > morkFile_kNewlinesCount )
|
||||
quantum = morkFile_kNewlinesCount;
|
||||
|
||||
mork_size quantumSize = quantum * mork_kNewlineSize;
|
||||
this->Write(ev, morkFile_kNewlines, quantumSize);
|
||||
outSize += quantumSize;
|
||||
inNewlines -= quantum;
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkStdioFile::CloseMorkNode(morkEnv* ev) // CloseStdioFile() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseStdioFile(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkStdioFile::~morkStdioFile() // assert CloseStdioFile() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mStdioFile_File==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkStdioFile::CloseStdioFile(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( mStdioFile_File && this->FileActive() && this->FileIoOpen() )
|
||||
{
|
||||
this->CloseStdio(ev);
|
||||
}
|
||||
|
||||
mStdioFile_File = 0;
|
||||
|
||||
this->CloseFile(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// compatible with the morkFile::MakeFile() entry point
|
||||
|
||||
/*static*/ morkStdioFile*
|
||||
morkStdioFile::OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath, mork_bool inFrozen)
|
||||
{
|
||||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = (inFrozen)? "rb" : "wb";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
|
||||
if ( outFile )
|
||||
{
|
||||
outFile->SetFileFrozen(inFrozen);
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return outFile;
|
||||
}
|
||||
|
||||
/*static*/ morkStdioFile*
|
||||
morkStdioFile::CreateNewStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath)
|
||||
{
|
||||
morkStdioFile* outFile = 0;
|
||||
if ( ioHeap && inFilePath )
|
||||
{
|
||||
const char* mode = "wb+";
|
||||
outFile = new(*ioHeap, ev)
|
||||
morkStdioFile(ev, morkUsage::kHeap, ioHeap, ioHeap, inFilePath, mode);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return outFile;
|
||||
}
|
||||
|
||||
|
||||
/*public virtual*/ void
|
||||
morkStdioFile:: BecomeTrunk(morkEnv* ev)
|
||||
// If this file is a file version branch created by calling AcquireBud(),
|
||||
// BecomeTrunk() causes this file's content to replace the original
|
||||
// file's content, typically by assuming the original file's identity.
|
||||
{
|
||||
this->Flush(ev);
|
||||
}
|
||||
|
||||
/*public virtual*/ morkFile*
|
||||
morkStdioFile::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
// AcquireBud() starts a new "branch" version of the file, empty of content,
|
||||
// so that a new version of the file can be written. This new file
|
||||
// can later be told to BecomeTrunk() the original file, so the branch
|
||||
// created by budding the file will replace the original file. Some
|
||||
// file subclasses might initially take the unsafe but expedient
|
||||
// approach of simply truncating this file down to zero length, and
|
||||
// then returning the same morkFile pointer as this, with an extra
|
||||
// reference count increment. Note that the caller of AcquireBud() is
|
||||
// expected to eventually call CutStrongRef() on the returned file
|
||||
// in order to release the strong reference. High quality versions
|
||||
// of morkFile subclasses will create entirely new files which later
|
||||
// are renamed to become the old file, so that better transactional
|
||||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
{
|
||||
morkFile* outFile = 0;
|
||||
if ( this->IsOpenAndActiveFile() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
//#ifdef MORK_WIN
|
||||
// truncate(file, /*eof*/ 0);
|
||||
//#else /*MORK_WIN*/
|
||||
char* name = mFile_Name;
|
||||
if ( name )
|
||||
{
|
||||
if ( MORK_FILECLOSE(file) >= 0 )
|
||||
{
|
||||
this->SetFileActive(morkBool_kFalse);
|
||||
this->SetFileIoOpen(morkBool_kFalse);
|
||||
mStdioFile_File = 0;
|
||||
|
||||
file = fopen(name, "wb+"); // open for write, discarding old content
|
||||
if ( file )
|
||||
{
|
||||
mStdioFile_File = file;
|
||||
this->SetFileActive(morkBool_kTrue);
|
||||
this->SetFileIoOpen(morkBool_kTrue);
|
||||
this->SetFileFrozen(morkBool_kFalse);
|
||||
}
|
||||
else
|
||||
this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else
|
||||
this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else
|
||||
this->NilFileNameError(ev);
|
||||
|
||||
//#endif /*MORK_WIN*/
|
||||
|
||||
if ( ev->Good() && this->AddStrongRef(ev) )
|
||||
outFile = this;
|
||||
}
|
||||
else this->NewMissingIoError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outFile;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
morkStdioFile::Length(morkEnv* ev) const
|
||||
{
|
||||
mork_pos outPos = 0;
|
||||
|
||||
if ( this->IsOpenAndActiveFile() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
long start = MORK_FILETELL(file);
|
||||
if ( start >= 0 )
|
||||
{
|
||||
long fore = MORK_FILESEEK(file, 0, SEEK_END);
|
||||
if ( fore >= 0 )
|
||||
{
|
||||
long eof = MORK_FILETELL(file);
|
||||
if ( eof >= 0 )
|
||||
{
|
||||
long back = MORK_FILESEEK(file, start, SEEK_SET);
|
||||
if ( back >= 0 )
|
||||
outPos = eof;
|
||||
else
|
||||
this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->NewMissingIoError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
morkStdioFile::Tell(morkEnv* ev) const
|
||||
{
|
||||
mork_pos outPos = 0;
|
||||
|
||||
if ( this->IsOpenAndActiveFile() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
long where = MORK_FILETELL(file);
|
||||
if ( where >= 0 )
|
||||
outPos = where;
|
||||
else
|
||||
this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->NewMissingIoError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_size
|
||||
morkStdioFile::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
||||
{
|
||||
mork_num outCount = 0;
|
||||
|
||||
if ( this->IsOpenAndActiveFile() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
long count = MORK_FILEREAD(outBuf, inSize, file);
|
||||
if ( count >= 0 )
|
||||
{
|
||||
outCount = (mork_num) count;
|
||||
}
|
||||
else this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->NewMissingIoError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outCount;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
morkStdioFile::Seek(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
mork_pos outPos = 0;
|
||||
|
||||
if ( this->IsOpenOrClosingNode() && this->FileActive() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
long where = MORK_FILESEEK(file, inPos, SEEK_SET);
|
||||
if ( where >= 0 )
|
||||
outPos = inPos;
|
||||
else
|
||||
this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->NewMissingIoError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_size
|
||||
morkStdioFile::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
{
|
||||
mork_num outCount = 0;
|
||||
|
||||
if ( this->IsOpenActiveAndMutableFile() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
if ( fwrite(inBuf, 1, inSize, file) >= 0 )
|
||||
outCount = inSize;
|
||||
else
|
||||
this->new_stdio_file_fault(ev);
|
||||
}
|
||||
else this->NewMissingIoError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outCount;
|
||||
}
|
||||
|
||||
/*public virtual*/ void
|
||||
morkStdioFile::Flush(morkEnv* ev)
|
||||
{
|
||||
if ( this->IsOpenOrClosingNode() && this->FileActive() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( file )
|
||||
{
|
||||
MORK_FILEFLUSH(file);
|
||||
|
||||
}
|
||||
else this->NewMissingIoError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
//protected: // protected non-poly morkStdioFile methods
|
||||
|
||||
void
|
||||
morkStdioFile::new_stdio_file_fault(morkEnv* ev) const
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
|
||||
// bunch of stuff not ported here
|
||||
if ( !errno && file )
|
||||
errno = ferror(file);
|
||||
|
||||
this->NewFileErrnoError(ev);
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
//public: // public non-poly morkStdioFile methods
|
||||
|
||||
|
||||
/*public non-poly*/
|
||||
morkStdioFile::morkStdioFile(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkFile(ev, inUsage, ioHeap, ioSlotHeap)
|
||||
, mStdioFile_File( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kStdioFile;
|
||||
}
|
||||
|
||||
morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap,
|
||||
const char* inName, const char* inMode)
|
||||
// calls OpenStdio() after construction
|
||||
: morkFile(ev, inUsage, ioHeap, ioSlotHeap)
|
||||
, mStdioFile_File( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
this->OpenStdio(ev, inName, inMode);
|
||||
}
|
||||
|
||||
morkStdioFile::morkStdioFile(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap,
|
||||
void* ioFile, const char* inName, mork_bool inFrozen)
|
||||
// calls UseStdio() after construction
|
||||
: morkFile(ev, inUsage, ioHeap, ioSlotHeap)
|
||||
, mStdioFile_File( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
this->UseStdio(ev, ioFile, inName, inFrozen);
|
||||
}
|
||||
|
||||
void
|
||||
morkStdioFile::OpenStdio(morkEnv* ev, const char* inName, const char* inMode)
|
||||
// Open a new FILE with name inName, using mode flags from inMode.
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( !inMode )
|
||||
inMode = "";
|
||||
|
||||
mork_bool frozen = (*inMode == 'r'); // cursory attempt to note readonly
|
||||
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
if ( !this->FileActive() )
|
||||
{
|
||||
this->SetFileIoOpen(morkBool_kFalse);
|
||||
if ( inName && *inName )
|
||||
{
|
||||
this->SetFileName(ev, inName);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
FILE* file = fopen(inName, inMode);
|
||||
if ( file )
|
||||
{
|
||||
mStdioFile_File = file;
|
||||
this->SetFileActive(morkBool_kTrue);
|
||||
this->SetFileIoOpen(morkBool_kTrue);
|
||||
this->SetFileFrozen(frozen);
|
||||
}
|
||||
else
|
||||
this->new_stdio_file_fault(ev);
|
||||
}
|
||||
}
|
||||
else ev->NewError("no file name");
|
||||
}
|
||||
else ev->NewError("file already active");
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkStdioFile::UseStdio(morkEnv* ev, void* ioFile, const char* inName,
|
||||
mork_bool inFrozen)
|
||||
// Use an existing file, like stdin/stdout/stderr, which should not
|
||||
// have the io stream closed when the file is closed. The ioFile
|
||||
// parameter must actually be of type FILE (but we don't want to make
|
||||
// this header file include the stdio.h header file).
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
if ( !this->FileActive() )
|
||||
{
|
||||
if ( ioFile )
|
||||
{
|
||||
this->SetFileIoOpen(morkBool_kFalse);
|
||||
this->SetFileName(ev, inName);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mStdioFile_File = ioFile;
|
||||
this->SetFileActive(morkBool_kTrue);
|
||||
this->SetFileFrozen(inFrozen);
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
else ev->NewError("file already active");
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkStdioFile::CloseStdio(morkEnv* ev)
|
||||
// Close the stream io if both and FileActive() and FileIoOpen(), but
|
||||
// this does not close this instances (like CloseStdioFile() does).
|
||||
// If stream io was made active by means of calling UseStdio(),
|
||||
// then this method does little beyond marking the stream inactive
|
||||
// because FileIoOpen() is false.
|
||||
{
|
||||
if ( mStdioFile_File && this->FileActive() && this->FileIoOpen() )
|
||||
{
|
||||
FILE* file = (FILE*) mStdioFile_File;
|
||||
if ( MORK_FILECLOSE(file) < 0 )
|
||||
this->new_stdio_file_fault(ev);
|
||||
|
||||
mStdioFile_File = 0;
|
||||
this->SetFileActive(morkBool_kFalse);
|
||||
this->SetFileIoOpen(morkBool_kFalse);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
298
mozilla/db/mork/src/morkFile.h
Normal file
298
mozilla/db/mork/src/morkFile.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#define _MORKFILE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*=============================================================================
|
||||
* morkFile: abstract file interface
|
||||
*/
|
||||
|
||||
#define morkDerived_kFile /*i*/ 0x4669 /* ascii 'Fi' */
|
||||
|
||||
class morkFile /*d*/ : public morkNode { /* ````` simple file API ````` */
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected morkFile members (similar to public domain IronDoc)
|
||||
|
||||
mork_u1 mFile_Frozen; // 'F' => file allows only read access
|
||||
mork_u1 mFile_DoTrace; // 'T' trace if ev->DoTrace()
|
||||
mork_u1 mFile_IoOpen; // 'O' => io stream is open (& needs a close)
|
||||
mork_u1 mFile_Active; // 'A' => file is active and usable
|
||||
|
||||
nsIMdbHeap* mFile_SlotHeap; // heap for Name and other allocated slots
|
||||
char* mFile_Name; // can be nil if SetFileName() is never called
|
||||
// mFile_Name convention: managed with morkEnv::CopyString()/FreeString()
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseFile() only if open
|
||||
virtual ~morkFile(); // assert that CloseFile() executed earlier
|
||||
|
||||
public: // morkFile construction & destruction
|
||||
morkFile(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
nsIMdbHeap* ioSlotHeap);
|
||||
void CloseFile(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkFile(const morkFile& other);
|
||||
morkFile& operator=(const morkFile& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsFile() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kFile; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public static standard file creation entry point
|
||||
|
||||
static morkFile* OpenOldFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath, mork_bool inFrozen);
|
||||
// Choose some subclass of morkFile to instantiate, in order to read
|
||||
// (and write if not frozen) the file known by inFilePath. The file
|
||||
// returned should be open and ready for use, and presumably positioned
|
||||
// at the first byte position of the file. The exact manner in which
|
||||
// files must be opened is considered a subclass specific detail, and
|
||||
// other portions or Mork source code don't want to know how it's done.
|
||||
|
||||
static morkFile* CreateNewFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath);
|
||||
// Choose some subclass of morkFile to instantiate, in order to read
|
||||
// (and write if not frozen) the file known by inFilePath. The file
|
||||
// returned should be created and ready for use, and presumably positioned
|
||||
// at the first byte position of the file. The exact manner in which
|
||||
// files must be opened is considered a subclass specific detail, and
|
||||
// other portions or Mork source code don't want to know how it's done.
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // virtual morkFile methods
|
||||
|
||||
virtual void BecomeTrunk(morkEnv* ev);
|
||||
// If this file is a file version branch created by calling AcquireBud(),
|
||||
// BecomeTrunk() causes this file's content to replace the original
|
||||
// file's content, typically by assuming the original file's identity.
|
||||
// This default implementation of BecomeTrunk() does nothing, and this
|
||||
// is appropriate behavior for files which are not branches, and is
|
||||
// also the right behavior for files returned from AcquireBud() which are
|
||||
// in fact the original file that has been truncated down to zero length.
|
||||
|
||||
virtual morkFile* AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap) = 0;
|
||||
// AcquireBud() starts a new "branch" version of the file, empty of content,
|
||||
// so that a new version of the file can be written. This new file
|
||||
// can later be told to BecomeTrunk() the original file, so the branch
|
||||
// created by budding the file will replace the original file. Some
|
||||
// file subclasses might initially take the unsafe but expedient
|
||||
// approach of simply truncating this file down to zero length, and
|
||||
// then returning the same morkFile pointer as this, with an extra
|
||||
// reference count increment. Note that the caller of AcquireBud() is
|
||||
// expected to eventually call CutStrongRef() on the returned file
|
||||
// in order to release the strong reference. High quality versions
|
||||
// of morkFile subclasses will create entirely new files which later
|
||||
// are renamed to become the old file, so that better transactional
|
||||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
|
||||
virtual mork_pos Length(morkEnv* ev) const = 0; // eof
|
||||
virtual mork_pos Tell(morkEnv* ev) const = 0;
|
||||
virtual mork_size Read(morkEnv* ev, void* outBuf, mork_size inSize) = 0;
|
||||
virtual mork_pos Seek(morkEnv* ev, mork_pos inPos) = 0;
|
||||
virtual mork_size Write(morkEnv* ev, const void* inBuf, mork_size inSize) = 0;
|
||||
virtual void Flush(morkEnv* ev) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // non-poly morkFile methods
|
||||
|
||||
mork_bool FileFrozen() const { return mFile_Frozen == 'F'; }
|
||||
mork_bool FileDoTrace() const { return mFile_DoTrace == 'T'; }
|
||||
mork_bool FileIoOpen() const { return mFile_IoOpen == 'O'; }
|
||||
mork_bool FileActive() const { return mFile_Active == 'A'; }
|
||||
|
||||
void SetFileFrozen(mork_bool b) { mFile_Frozen = (b)? 'F' : 0; }
|
||||
void SetFileDoTrace(mork_bool b) { mFile_DoTrace = (b)? 'T' : 0; }
|
||||
void SetFileIoOpen(mork_bool b) { mFile_IoOpen = (b)? 'O' : 0; }
|
||||
void SetFileActive(mork_bool b) { mFile_Active = (b)? 'A' : 0; }
|
||||
|
||||
|
||||
mork_bool IsOpenActiveAndMutableFile() const
|
||||
{ return ( IsOpenNode() && FileActive() && !FileFrozen() ); }
|
||||
// call IsOpenActiveAndMutableFile() before writing a file
|
||||
|
||||
mork_bool IsOpenAndActiveFile() const
|
||||
{ return ( this->IsOpenNode() && this->FileActive() ); }
|
||||
// call IsOpenAndActiveFile() before using a file
|
||||
|
||||
void SetFileName(morkEnv* ev, const char* inName); // inName can be nil
|
||||
static void NilSlotHeapError(morkEnv* ev);
|
||||
static void NilFileNameError(morkEnv* ev);
|
||||
|
||||
void NewMissingIoError(morkEnv* ev) const;
|
||||
|
||||
void NewFileDownError(morkEnv* ev) const;
|
||||
// call NewFileDownError() when either IsOpenAndActiveFile()
|
||||
// is false, or when IsOpenActiveAndMutableFile() is false.
|
||||
|
||||
void NewFileErrnoError(morkEnv* ev) const;
|
||||
// call NewFileErrnoError() to convert std C errno into AB fault
|
||||
|
||||
mork_size WriteNewlines(morkEnv* ev, mork_count inNewlines);
|
||||
// WriteNewlines() returns the number of bytes written.
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakFile(morkFile* me,
|
||||
morkEnv* ev, morkFile** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongFile(morkFile* me,
|
||||
morkEnv* ev, morkFile** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkStdioFile: concrete file using standard C file io
|
||||
*/
|
||||
|
||||
#define morkDerived_kStdioFile /*i*/ 0x7346 /* ascii 'sF' */
|
||||
|
||||
class morkStdioFile /*d*/ : public morkFile { /* `` copied from IronDoc `` */
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected morkStdioFile members
|
||||
|
||||
void* mStdioFile_File;
|
||||
// actually type FILE*, but using opaque void* type
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseStdioFile() only if open
|
||||
virtual ~morkStdioFile(); // assert that CloseStdioFile() executed earlier
|
||||
|
||||
public: // morkStdioFile construction & destruction
|
||||
morkStdioFile(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseStdioFile(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkStdioFile(const morkStdioFile& other);
|
||||
morkStdioFile& operator=(const morkStdioFile& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsStdioFile() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kStdioFile; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonStdioFileTypeError(morkEnv* ev);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // compatible with the morkFile::OpenOldFile() entry point
|
||||
|
||||
static morkStdioFile* OpenOldStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath, mork_bool inFrozen);
|
||||
|
||||
static morkStdioFile* CreateNewStdioFile(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
const char* inFilePath);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // virtual ab_File methods
|
||||
|
||||
virtual void BecomeTrunk(morkEnv* ev);
|
||||
// If this file is a file version branch created by calling AcquireBud(),
|
||||
// BecomeTrunk() causes this file's content to replace the original
|
||||
// file's content, typically by assuming the original file's identity.
|
||||
|
||||
virtual morkFile* AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap);
|
||||
// AcquireBud() starts a new "branch" version of the file, empty of content,
|
||||
// so that a new version of the file can be written. This new file
|
||||
// can later be told to BecomeTrunk() the original file, so the branch
|
||||
// created by budding the file will replace the original file. Some
|
||||
// file subclasses might initially take the unsafe but expedient
|
||||
// approach of simply truncating this file down to zero length, and
|
||||
// then returning the same morkFile pointer as this, with an extra
|
||||
// reference count increment. Note that the caller of AcquireBud() is
|
||||
// expected to eventually call CutStrongRef() on the returned file
|
||||
// in order to release the strong reference. High quality versions
|
||||
// of morkFile subclasses will create entirely new files which later
|
||||
// are renamed to become the old file, so that better transactional
|
||||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
|
||||
virtual mork_pos Length(morkEnv* ev) const; // eof
|
||||
virtual mork_pos Tell(morkEnv* ev) const;
|
||||
virtual mork_size Read(morkEnv* ev, void* outBuf, mork_size inSize);
|
||||
virtual mork_pos Seek(morkEnv* ev, mork_pos inPos);
|
||||
virtual mork_size Write(morkEnv* ev, const void* inBuf, mork_size inSize);
|
||||
virtual void Flush(morkEnv* ev);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected non-poly morkStdioFile methods
|
||||
|
||||
void new_stdio_file_fault(morkEnv* ev) const;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkStdioFile methods
|
||||
|
||||
morkStdioFile(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap,
|
||||
const char* inName, const char* inMode);
|
||||
// calls OpenStdio() after construction
|
||||
|
||||
morkStdioFile(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap,
|
||||
void* ioFile, const char* inName, mork_bool inFrozen);
|
||||
// calls UseStdio() after construction
|
||||
|
||||
void OpenStdio(morkEnv* ev, const char* inName, const char* inMode);
|
||||
// Open a new FILE with name inName, using mode flags from inMode.
|
||||
|
||||
void UseStdio(morkEnv* ev, void* ioFile, const char* inName,
|
||||
mork_bool inFrozen);
|
||||
// Use an existing file, like stdin/stdout/stderr, which should not
|
||||
// have the io stream closed when the file is closed. The ioFile
|
||||
// parameter must actually be of type FILE (but we don't want to make
|
||||
// this header file include the stdio.h header file).
|
||||
|
||||
void CloseStdio(morkEnv* ev);
|
||||
// Close the stream io if both and FileActive() and FileIoOpen(), but
|
||||
// this does not close this instances (like CloseStdioFile() does).
|
||||
// If stream io was made active by means of calling UseStdio(),
|
||||
// then this method does little beyond marking the stream inactive
|
||||
// because FileIoOpen() is false.
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakStdioFile(morkStdioFile* me,
|
||||
morkEnv* ev, morkStdioFile** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongStdioFile(morkStdioFile* me,
|
||||
morkEnv* ev, morkStdioFile** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKFILE_ */
|
||||
404
mozilla/db/mork/src/morkHandle.cpp
Normal file
404
mozilla/db/mork/src/morkHandle.cpp
Normal file
@@ -0,0 +1,404 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFACTORY_
|
||||
#include "morkFactory.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkHandle::CloseMorkNode(morkEnv* ev) // CloseHandle() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseHandle(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkHandle::~morkHandle() // assert CloseHandle() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mHandle_Env==0);
|
||||
MORK_ASSERT(mHandle_Face==0);
|
||||
MORK_ASSERT(mHandle_Object==0);
|
||||
MORK_ASSERT(mHandle_Magic==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkHandle::morkHandle(morkEnv* ev, // note morkUsage is always morkUsage_kPool
|
||||
morkHandleFace* ioFace, // must not be nil, cookie for this handle
|
||||
morkObject* ioObject, // must not be nil, the object for this handle
|
||||
mork_magic inMagic) // magic sig to denote specific subclass
|
||||
: morkNode(ev, morkUsage::kPool, (nsIMdbHeap*) 0L)
|
||||
, mHandle_Tag( 0 )
|
||||
, mHandle_Env( ev )
|
||||
, mHandle_Face( ioFace )
|
||||
, mHandle_Object( 0 )
|
||||
, mHandle_Magic( 0 )
|
||||
{
|
||||
if ( ioFace && ioObject )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mHandle_Tag = morkHandle_kTag;
|
||||
morkObject::SlotStrongObject(ioObject, ev, &mHandle_Object);
|
||||
morkHandle::SlotWeakHandle(this, ev, &ioObject->mObject_Handle);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mHandle_Magic = inMagic;
|
||||
mNode_Derived = morkDerived_kHandle;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkHandle::CloseHandle(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkObject* obj = mHandle_Object;
|
||||
mork_bool objDidRefSelf = ( obj && obj->mObject_Handle == this );
|
||||
if ( objDidRefSelf )
|
||||
obj->mObject_Handle = 0; // drop the reference
|
||||
|
||||
morkObject::SlotStrongObject((morkObject*) 0, ev, &mHandle_Object);
|
||||
mHandle_Magic = 0;
|
||||
// note mHandle_Tag MUST stay morkHandle_kTag for morkNode::ZapOld()
|
||||
this->MarkShut();
|
||||
|
||||
if ( objDidRefSelf )
|
||||
this->CutWeakRef(ev);
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
void morkHandle::NilFactoryError(morkEnv* ev) const
|
||||
{
|
||||
ev->NewError("nil mHandle_Factory");
|
||||
}
|
||||
|
||||
void morkHandle::NilHandleObjectError(morkEnv* ev) const
|
||||
{
|
||||
ev->NewError("nil mHandle_Object");
|
||||
}
|
||||
|
||||
void morkHandle::NonNodeObjectError(morkEnv* ev) const
|
||||
{
|
||||
ev->NewError("non-node mHandle_Object");
|
||||
}
|
||||
|
||||
void morkHandle::NonOpenObjectError(morkEnv* ev) const
|
||||
{
|
||||
ev->NewError("non-open mHandle_Object");
|
||||
}
|
||||
|
||||
void morkHandle::NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const
|
||||
{
|
||||
ev->NewError("wrong mHandle_Magic");
|
||||
}
|
||||
|
||||
void morkHandle::NewDownHandleError(morkEnv* ev) const
|
||||
{
|
||||
if ( this->IsHandle() )
|
||||
{
|
||||
if ( this->GoodHandleTag() )
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
ev->NewError("unknown down morkHandle error");
|
||||
else
|
||||
this->NonOpenNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NewError("wrong morkHandle tag");
|
||||
}
|
||||
else
|
||||
ev->NewError("non morkHandle");
|
||||
}
|
||||
|
||||
morkObject* morkHandle::GetGoodHandleObject(morkEnv* ev,
|
||||
mork_bool inMutable, mork_magic inMagicType) const
|
||||
{
|
||||
morkObject* outObject = 0;
|
||||
if ( this->IsHandle() && this->GoodHandleTag() && this->IsOpenNode() )
|
||||
{
|
||||
if ( !inMagicType || mHandle_Magic == inMagicType )
|
||||
{
|
||||
morkObject* obj = this->mHandle_Object;
|
||||
if ( obj )
|
||||
{
|
||||
if ( obj->IsNode() )
|
||||
{
|
||||
if ( obj->IsOpenNode() )
|
||||
{
|
||||
if ( this->IsMutable() || !inMutable )
|
||||
outObject = obj;
|
||||
else
|
||||
this->NonMutableNodeError(ev);
|
||||
}
|
||||
else
|
||||
this->NonOpenObjectError(ev);
|
||||
}
|
||||
else
|
||||
this->NonNodeObjectError(ev);
|
||||
}
|
||||
else
|
||||
this->NilHandleObjectError(ev);
|
||||
}
|
||||
else
|
||||
this->NewBadMagicHandleError(ev, inMagicType);
|
||||
}
|
||||
else
|
||||
this->NewDownHandleError(ev);
|
||||
|
||||
MORK_ASSERT(outObject);
|
||||
return outObject;
|
||||
}
|
||||
|
||||
|
||||
morkEnv*
|
||||
morkHandle::CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
|
||||
mdb_err* outErr) const
|
||||
{
|
||||
morkEnv* outEnv = 0;
|
||||
morkEnv* ev = morkEnv::FromMdbEnv(mev);
|
||||
if ( ev )
|
||||
{
|
||||
morkObject* obj = this->GetGoodHandleObject(ev, inMutable, /*magic*/ 0);
|
||||
if ( obj )
|
||||
{
|
||||
outEnv = ev;
|
||||
}
|
||||
*outErr = ev->AsErr();
|
||||
}
|
||||
MORK_ASSERT(outEnv);
|
||||
return outEnv;
|
||||
}
|
||||
|
||||
// { ===== begin nsIMdbObject methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
MORK_ASSERT(outIsReadonly);
|
||||
if ( outIsReadonly )
|
||||
*outIsReadonly = mHandle_Object->IsFrozen();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin factory methods -----
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
morkFactory* factory = ev->mEnv_Factory;
|
||||
if ( factory )
|
||||
{
|
||||
nsIMdbFactory* handle = factory->AcquireFactoryHandle(ev);
|
||||
MORK_ASSERT(acqFactory);
|
||||
if ( handle && acqFactory )
|
||||
*acqFactory = handle;
|
||||
}
|
||||
else
|
||||
this->NilFactoryError(ev);
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end factory methods -----
|
||||
|
||||
// { ----- begin ref counting for well-behaved cyclic graphs -----
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_GetWeakRefCount(nsIMdbEnv* mev, // weak refs
|
||||
mdb_count* outCount)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
MORK_ASSERT(outCount);
|
||||
if ( outCount )
|
||||
*outCount = this->WeakRefsOnly();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_GetStrongRefCount(nsIMdbEnv* mev, // strong refs
|
||||
mdb_count* outCount)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
MORK_ASSERT(outCount);
|
||||
if ( outCount )
|
||||
*outCount = this->StrongRefsOnly();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_AddWeakRef(nsIMdbEnv* mev)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
this->AddWeakRef(ev);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_AddStrongRef(nsIMdbEnv* mev)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
this->AddStrongRef(ev);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_CutWeakRef(nsIMdbEnv* mev)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
this->CutWeakRef(ev);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_CutStrongRef(nsIMdbEnv* mev)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
this->CutStrongRef(ev);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_CloseMdbObject(nsIMdbEnv* mev)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
if ( this->IsNode() && this->IsOpenNode() )
|
||||
{
|
||||
morkEnv* ev = CanUseHandle(mev, /*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
this->CloseMorkNode(ev);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
}
|
||||
return outErr;
|
||||
} // called at strong refs zero
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
morkHandle::Handle_IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
|
||||
MORK_ASSERT(outOpen);
|
||||
if ( outOpen )
|
||||
*outOpen = this->IsOpenNode();
|
||||
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end ref counting -----
|
||||
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
189
mozilla/db/mork/src/morkHandle.h
Normal file
189
mozilla/db/mork/src/morkHandle.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#define _MORKHANDLE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKDEQUE_
|
||||
#include "morkDeque.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class morkPool;
|
||||
class morkObject;
|
||||
class morkFactory;
|
||||
|
||||
#define morkDerived_kHandle /*i*/ 0x486E /* ascii 'Hn' */
|
||||
#define morkHandle_kTag 0x68416E44 /* ascii 'hAnD' */
|
||||
|
||||
/*| morkHandle:
|
||||
|*/
|
||||
class morkHandle : public morkNode {
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
mork_u4 mHandle_Tag; // must equal morkHandle_kTag
|
||||
morkEnv* mHandle_Env; // pool that allocated this handle
|
||||
morkHandleFace* mHandle_Face; // cookie from pool containing this
|
||||
morkObject* mHandle_Object; // object this handle wraps for MDB API
|
||||
mork_magic mHandle_Magic; // magic sig different in each subclass
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseHandle() only if open
|
||||
virtual ~morkHandle(); // assert that CloseHandle() executed earlier
|
||||
|
||||
public: // morkHandle construction & destruction
|
||||
morkHandle(morkEnv* ev, // note morkUsage is always morkUsage_kPool
|
||||
morkHandleFace* ioFace, // must not be nil, cookie for this handle
|
||||
morkObject* ioObject, // must not be nil, the object for this handle
|
||||
mork_magic inMagic); // magic sig to denote specific subclass
|
||||
void CloseHandle(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkHandle(const morkHandle& other);
|
||||
morkHandle& operator=(const morkHandle& other);
|
||||
|
||||
protected: // special case empty construction for morkHandleFrame
|
||||
friend class morkHandleFrame;
|
||||
morkHandle() { }
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsHandle() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kHandle; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // morkHandle memory management operators
|
||||
void* operator new(size_t inSize, morkPool& ioPool, morkEnv* ev)
|
||||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
// do NOT call delete on morkHandle instances. They are collected.
|
||||
|
||||
public: // other handle methods
|
||||
mork_bool GoodHandleTag() const
|
||||
{ return mHandle_Tag == morkHandle_kTag; }
|
||||
|
||||
void NewBadMagicHandleError(morkEnv* ev, mork_magic inMagic) const;
|
||||
void NewDownHandleError(morkEnv* ev) const;
|
||||
void NilFactoryError(morkEnv* ev) const;
|
||||
void NilHandleObjectError(morkEnv* ev) const;
|
||||
void NonNodeObjectError(morkEnv* ev) const;
|
||||
void NonOpenObjectError(morkEnv* ev) const;
|
||||
|
||||
morkObject* GetGoodHandleObject(morkEnv* ev,
|
||||
mork_bool inMutabl, mork_magic inMagicType) const;
|
||||
|
||||
public: // interface supporting mdbObject methods
|
||||
|
||||
morkEnv* CanUseHandle(nsIMdbEnv* mev, mork_bool inMutable,
|
||||
mdb_err* outErr) const;
|
||||
|
||||
// { ----- begin mdbObject style methods -----
|
||||
mdb_err Handle_IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly);
|
||||
|
||||
mdb_err Handle_GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory);
|
||||
mdb_err Handle_GetWeakRefCount(nsIMdbEnv* ev, mdb_count* outCount);
|
||||
mdb_err Handle_GetStrongRefCount(nsIMdbEnv* ev, mdb_count* outCount);
|
||||
|
||||
mdb_err Handle_AddWeakRef(nsIMdbEnv* ev);
|
||||
mdb_err Handle_AddStrongRef(nsIMdbEnv* ev);
|
||||
|
||||
mdb_err Handle_CutWeakRef(nsIMdbEnv* ev);
|
||||
mdb_err Handle_CutStrongRef(nsIMdbEnv* ev);
|
||||
|
||||
mdb_err Handle_CloseMdbObject(nsIMdbEnv* ev);
|
||||
mdb_err Handle_IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen);
|
||||
// } ----- end mdbObject style methods -----
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakHandle(morkHandle* me,
|
||||
morkEnv* ev, morkHandle** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongHandle(morkHandle* me,
|
||||
morkEnv* ev, morkHandle** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
#define morkHandleFrame_kPadSlotCount 4
|
||||
|
||||
/*| morkHandleFrame: an object format used for allocating and maintaining
|
||||
**| instances of morkHandle, with leading slots used to maintain this in a
|
||||
**| linked list, and following slots to provide extra footprint that might
|
||||
**| be needed by any morkHandle subclasses that include very little extra
|
||||
**| space (by virtue of the fact that each morkHandle subclass is expected
|
||||
**| to multiply inherit from another base class that has only abstact methods
|
||||
**| for space overhead related only to some vtable representation).
|
||||
|*/
|
||||
class morkHandleFrame {
|
||||
public:
|
||||
morkLink mHandleFrame_Link; // list storage without trampling Handle
|
||||
morkHandle mHandleFrame_Handle;
|
||||
mork_ip mHandleFrame_Padding[ morkHandleFrame_kPadSlotCount ];
|
||||
|
||||
public:
|
||||
morkHandle* AsHandle() { return &mHandleFrame_Handle; }
|
||||
|
||||
morkHandleFrame() {} // actually, morkHandleFrame never gets constructed
|
||||
|
||||
private: // copying is not allowed
|
||||
morkHandleFrame(const morkHandleFrame& other);
|
||||
morkHandleFrame& operator=(const morkHandleFrame& other);
|
||||
};
|
||||
|
||||
#define morkHandleFrame_kHandleOffset \
|
||||
mork_OffsetOf(morkHandleFrame,mHandleFrame_Handle)
|
||||
|
||||
#define morkHandle_AsHandleFrame(h) ((h)->mHandle_Block , \
|
||||
((morkHandleFrame*) (((mork_u1*)(h)) - morkHandleFrame_kHandleOffset)))
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKHANDLE_ */
|
||||
148
mozilla/db/mork/src/morkIntMap.cpp
Normal file
148
mozilla/db/mork/src/morkIntMap.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#include "morkIntMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkIntMap::CloseMorkNode(morkEnv* ev) // CloseIntMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseIntMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkIntMap::~morkIntMap() // assert CloseIntMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkIntMap::morkIntMap(morkEnv* ev,
|
||||
const morkUsage& inUsage, mork_size inValSize,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges)
|
||||
: morkMap(ev, inUsage, ioHeap, sizeof(mork_u4), inValSize,
|
||||
morkIntMap_kStartSlotCount, ioSlotHeap, inHoldChanges)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kIntMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkIntMap::CloseIntMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
|
||||
morkIntMap::Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const
|
||||
{
|
||||
return *((const mork_u4*) inKeyA) == *((const mork_u4*) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 // some integer function of *((mork_u4*) inKey)
|
||||
morkIntMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return *((const mork_u4*) inKey);
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
mork_bool
|
||||
morkIntMap::AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress)
|
||||
// the AddInt() method return value equals ev->Good().
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &inKey, &ioAddress,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkIntMap::CutInt(morkEnv* ev, mork_u4 inKey)
|
||||
{
|
||||
return this->Cut(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
}
|
||||
|
||||
void*
|
||||
morkIntMap::GetInt(morkEnv* ev, mork_u4 inKey)
|
||||
// Note the returned val does NOT have an increase in refcount for this.
|
||||
{
|
||||
void* val = 0; // old val in the map
|
||||
this->Get(ev, &inKey, /*key*/ (void*) 0, &val, (mork_change**) 0);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkIntMap::HasInt(morkEnv* ev, mork_u4 inKey)
|
||||
// Note the returned val does NOT have an increase in refcount for this.
|
||||
{
|
||||
return this->Get(ev, &inKey, /*key*/ (void*) 0, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
87
mozilla/db/mork/src/morkIntMap.h
Normal file
87
mozilla/db/mork/src/morkIntMap.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#define _MORKINTMAP_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kIntMap /*i*/ 0x694D /* ascii 'iM' */
|
||||
|
||||
#define morkIntMap_kStartSlotCount 512
|
||||
|
||||
/*| morkIntMap: maps mork_token -> morkNode
|
||||
|*/
|
||||
class morkIntMap : public morkMap { // for mapping tokens to maps
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseIntMap() only if open
|
||||
virtual ~morkIntMap(); // assert that CloseIntMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
|
||||
// keySize for morkIntMap equals sizeof(mork_u4)
|
||||
morkIntMap(morkEnv* ev, const morkUsage& inUsage, mork_size inValSize,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges);
|
||||
void CloseIntMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsIntMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kIntMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // *((mork_u4*) inKeyA) == *((mork_u4*) inKeyB)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
|
||||
virtual mork_u4 // some integer function of *((mork_u4*) inKey)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddInt(morkEnv* ev, mork_u4 inKey, void* ioAddress);
|
||||
// the AddInt() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutInt(morkEnv* ev, mork_token inKey);
|
||||
// The CutInt() boolean return indicates whether removal happened.
|
||||
|
||||
void* GetInt(morkEnv* ev, mork_token inKey);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
mork_bool HasInt(morkEnv* ev, mork_u4 inKey);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKINTMAP_ */
|
||||
937
mozilla/db/mork/src/morkMap.cpp
Normal file
937
mozilla/db/mork/src/morkMap.cpp
Normal file
@@ -0,0 +1,937 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
// This code is mostly a port to C++ from public domain IronDoc C sources.
|
||||
// Note many code comments here come verbatim from cut-and-pasted IronDoc.
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
|
||||
class morkHashArrays {
|
||||
public:
|
||||
nsIMdbHeap* mHashArrays_Heap; // copy of mMap_Heap
|
||||
mork_count mHashArrays_Slots; // copy of mMap_Slots
|
||||
|
||||
mork_u1* mHashArrays_Keys; // copy of mMap_Keys
|
||||
mork_u1* mHashArrays_Vals; // copy of mMap_Vals
|
||||
morkAssoc* mHashArrays_Assocs; // copy of mMap_Assocs
|
||||
mork_change* mHashArrays_Changes; // copy of mMap_Changes
|
||||
morkAssoc** mHashArrays_Buckets; // copy of mMap_Buckets
|
||||
morkAssoc* mHashArrays_FreeList; // copy of mMap_FreeList
|
||||
|
||||
public:
|
||||
void finalize(morkEnv* ev);
|
||||
};
|
||||
|
||||
void morkHashArrays::finalize(morkEnv* ev)
|
||||
{
|
||||
nsIMdbEnv* menv = ev->AsMdbEnv();
|
||||
nsIMdbHeap* heap = mHashArrays_Heap;
|
||||
|
||||
if ( heap )
|
||||
{
|
||||
if ( mHashArrays_Keys )
|
||||
heap->Free(menv, mHashArrays_Keys);
|
||||
if ( mHashArrays_Vals )
|
||||
heap->Free(menv, mHashArrays_Vals);
|
||||
if ( mHashArrays_Assocs )
|
||||
heap->Free(menv, mHashArrays_Assocs);
|
||||
if ( mHashArrays_Changes )
|
||||
heap->Free(menv, mHashArrays_Changes);
|
||||
if ( mHashArrays_Buckets )
|
||||
heap->Free(menv, mHashArrays_Buckets);
|
||||
}
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkMap::CloseMorkNode(morkEnv* ev) // CloseMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkMap::~morkMap() // assert CloseMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mMap_FreeList==0);
|
||||
MORK_ASSERT(mMap_Buckets==0);
|
||||
MORK_ASSERT(mMap_Keys==0);
|
||||
MORK_ASSERT(mMap_Vals==0);
|
||||
MORK_ASSERT(mMap_Changes==0);
|
||||
MORK_ASSERT(mMap_Assocs==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkMap::CloseMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( heap ) /* need to free the arrays? */
|
||||
{
|
||||
nsIMdbEnv* menv = ev->AsMdbEnv();
|
||||
|
||||
if ( mMap_Keys )
|
||||
heap->Free(menv, mMap_Keys);
|
||||
|
||||
if ( mMap_Vals )
|
||||
heap->Free(menv, mMap_Vals);
|
||||
|
||||
if ( mMap_Assocs )
|
||||
heap->Free(menv, mMap_Assocs);
|
||||
|
||||
if ( mMap_Buckets )
|
||||
heap->Free(menv, mMap_Buckets);
|
||||
|
||||
if ( mMap_Changes )
|
||||
heap->Free(menv, mMap_Changes);
|
||||
}
|
||||
mMap_Keys = 0;
|
||||
mMap_Vals = 0;
|
||||
mMap_Buckets = 0;
|
||||
mMap_Assocs = 0;
|
||||
mMap_Changes = 0;
|
||||
mMap_FreeList = 0;
|
||||
MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm));
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
void
|
||||
morkMap::clear_map(morkEnv* ev, nsIMdbHeap* ioSlotHeap)
|
||||
{
|
||||
mMap_Tag = 0;
|
||||
mMap_Seed = 0;
|
||||
mMap_Slots = 0;
|
||||
mMap_Fill = 0;
|
||||
mMap_Keys = 0;
|
||||
mMap_Vals = 0;
|
||||
mMap_Assocs = 0;
|
||||
mMap_Changes = 0;
|
||||
mMap_Buckets = 0;
|
||||
mMap_FreeList = 0;
|
||||
MORK_MEMSET(&mMap_Form, 0, sizeof(morkMapForm));
|
||||
|
||||
mMap_Heap = 0;
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mMap_Heap);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
morkMap::morkMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
mork_size inKeySize, mork_size inValSize,
|
||||
mork_size inSlots, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mMap_Heap( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->clear_map(ev, ioSlotHeap);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mMap_Form.mMapForm_HoldChanges = inHoldChanges;
|
||||
|
||||
mMap_Form.mMapForm_KeySize = inKeySize;
|
||||
mMap_Form.mMapForm_ValSize = inValSize;
|
||||
mMap_Form.mMapForm_KeyIsIP = ( inKeySize == sizeof(mork_ip) );
|
||||
mMap_Form.mMapForm_ValIsIP = ( inValSize == sizeof(mork_ip) );
|
||||
|
||||
this->InitMap(ev, inSlots);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkMap::NewIterOutOfSyncError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("map iter out of sync");
|
||||
}
|
||||
|
||||
void morkMap::NewBadMapError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("bad morkMap tag");
|
||||
if ( !this )
|
||||
ev->NewError("nil morkMap instance");
|
||||
}
|
||||
|
||||
void morkMap::NewSlotsUnderflowWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("member count underflow");
|
||||
}
|
||||
|
||||
void morkMap::InitMap(morkEnv* ev, mork_size inSlots)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkHashArrays old;
|
||||
// MORK_MEMCPY(&mMap_Form, &inForm, sizeof(morkMapForm));
|
||||
if ( inSlots < 3 ) /* requested capacity absurdly small? */
|
||||
inSlots = 3; /* bump it up to a minimum practical level */
|
||||
else if ( inSlots > (128 * 1024) ) /* requested slots absurdly big? */
|
||||
inSlots = (128 * 1024); /* decrease it to a maximum practical level */
|
||||
|
||||
if ( this->new_arrays(ev, &old, inSlots) )
|
||||
mMap_Tag = morkMap_kTag;
|
||||
|
||||
MORK_MEMSET(&old, 0, sizeof(morkHashArrays)); // do NOT finalize
|
||||
}
|
||||
}
|
||||
|
||||
morkAssoc**
|
||||
morkMap::find(morkEnv* ev, const void* inKey, mork_u4 inHash) const
|
||||
{
|
||||
mork_u1* keys = mMap_Keys;
|
||||
mork_num keySize = this->FormKeySize();
|
||||
// morkMap_mEqual equal = this->FormEqual();
|
||||
|
||||
morkAssoc** ref = mMap_Buckets + (inHash % mMap_Slots);
|
||||
morkAssoc* assoc = *ref;
|
||||
while ( assoc ) /* look at another assoc in the bucket? */
|
||||
{
|
||||
mork_pos i = assoc - mMap_Assocs; /* index of this assoc */
|
||||
if ( this->Equal(ev, keys + (i * keySize), inKey) ) /* found? */
|
||||
return ref;
|
||||
|
||||
ref = &assoc->mAssoc_Next; /* consider next assoc slot in bucket */
|
||||
assoc = *ref; /* if this is null, then we are done */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*| get_assoc: read the key and/or value at index inPos
|
||||
|*/
|
||||
void
|
||||
morkMap::get_assoc(void* outKey, void* outVal, mork_pos inPos) const
|
||||
{
|
||||
mork_num valSize = this->FormValSize();
|
||||
if ( valSize && outVal ) /* map holds values? caller wants the value? */
|
||||
{
|
||||
const mork_u1* value = mMap_Vals + (valSize * inPos);
|
||||
if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */
|
||||
*((mork_ip*) outVal) = *((const mork_ip*) value);
|
||||
else
|
||||
MORK_MEMCPY(outVal, value, valSize);
|
||||
}
|
||||
if ( outKey ) /* caller wants the key? */
|
||||
{
|
||||
mork_num keySize = this->FormKeySize();
|
||||
const mork_u1* key = mMap_Keys + (keySize * inPos);
|
||||
if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */
|
||||
*((mork_ip*) outKey) = *((const mork_ip*) key);
|
||||
else
|
||||
MORK_MEMCPY(outKey, key, keySize);
|
||||
}
|
||||
}
|
||||
|
||||
/*| put_assoc: write the key and/or value at index inPos
|
||||
|*/
|
||||
void
|
||||
morkMap::put_assoc(const void* inKey, const void* inVal, mork_pos inPos) const
|
||||
{
|
||||
mork_num valSize = this->FormValSize();
|
||||
if ( valSize && inVal ) /* map holds values? caller sends a value? */
|
||||
{
|
||||
mork_u1* value = mMap_Vals + (valSize * inPos);
|
||||
if ( valSize == sizeof(mork_ip) && this->FormValIsIP() ) /* ip case? */
|
||||
*((mork_ip*) value) = *((const mork_ip*) inVal);
|
||||
else
|
||||
MORK_MEMCPY(value, inVal, valSize);
|
||||
}
|
||||
if ( inKey ) /* caller sends a key? */
|
||||
{
|
||||
mork_num keySize = this->FormKeySize();
|
||||
mork_u1* key = mMap_Keys + (keySize * inPos);
|
||||
if ( keySize == sizeof(mork_ip) && this->FormKeyIsIP() ) /* ip case? */
|
||||
*((mork_ip*) key) = *((const mork_ip*) inKey);
|
||||
else
|
||||
MORK_MEMCPY(key, inKey, keySize);
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
morkMap::clear_alloc(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
void* p = 0;
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( heap )
|
||||
{
|
||||
if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p )
|
||||
{
|
||||
MORK_MEMSET(p, 0, inSize);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (void*) 0;
|
||||
}
|
||||
|
||||
void*
|
||||
morkMap::alloc(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
void* p = 0;
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( heap )
|
||||
{
|
||||
if ( heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &p) == 0 && p )
|
||||
return p;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (void*) 0;
|
||||
}
|
||||
|
||||
/*| new_keys: allocate an array of inSlots new keys filled with zero.
|
||||
|*/
|
||||
mork_u1*
|
||||
morkMap::new_keys(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_num size = inSlots * this->FormKeySize();
|
||||
return (mork_u1*) this->clear_alloc(ev, size);
|
||||
}
|
||||
|
||||
/*| new_values: allocate an array of inSlots new values filled with zero.
|
||||
**| When values are zero sized, we just return a null pointer.
|
||||
|*/
|
||||
mork_u1*
|
||||
morkMap::new_values(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_u1* values = 0;
|
||||
mork_num size = inSlots * this->FormValSize();
|
||||
if ( size )
|
||||
values = (mork_u1*) this->clear_alloc(ev, size);
|
||||
return values;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMap::new_changes(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_change* changes = 0;
|
||||
mork_num size = inSlots * sizeof(mork_change);
|
||||
if ( size && mMap_Form.mMapForm_HoldChanges )
|
||||
changes = (mork_change*) this->clear_alloc(ev, size);
|
||||
return changes;
|
||||
}
|
||||
|
||||
/*| new_buckets: allocate an array of inSlots new buckets filled with zero.
|
||||
|*/
|
||||
morkAssoc**
|
||||
morkMap::new_buckets(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_num size = inSlots * sizeof(morkAssoc*);
|
||||
return (morkAssoc**) this->clear_alloc(ev, size);
|
||||
}
|
||||
|
||||
/*| new_assocs: allocate an array of inSlots new assocs, with each assoc
|
||||
**| linked together in a list with the first array element at the list head
|
||||
**| and the last element at the list tail. (morkMap::grow() needs this.)
|
||||
|*/
|
||||
morkAssoc*
|
||||
morkMap::new_assocs(morkEnv* ev, mork_num inSlots)
|
||||
{
|
||||
mork_num size = inSlots * sizeof(morkAssoc);
|
||||
morkAssoc* assocs = (morkAssoc*) this->alloc(ev, size);
|
||||
if ( assocs ) /* able to allocate the array? */
|
||||
{
|
||||
morkAssoc* a = assocs + (inSlots - 1); /* the last array element */
|
||||
a->mAssoc_Next = 0; /* terminate tail element of the list with null */
|
||||
while ( --a >= assocs ) /* another assoc to link into the list? */
|
||||
a->mAssoc_Next = a + 1; /* each points to the following assoc */
|
||||
}
|
||||
return assocs;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkMap::new_arrays(morkEnv* ev, morkHashArrays* old, mork_num inSlots)
|
||||
{
|
||||
mork_bool outNew = morkBool_kFalse;
|
||||
|
||||
/* see if we can allocate all the new arrays before we go any further: */
|
||||
morkAssoc** newBuckets = this->new_buckets(ev, inSlots);
|
||||
morkAssoc* newAssocs = this->new_assocs(ev, inSlots);
|
||||
mork_u1* newKeys = this->new_keys(ev, inSlots);
|
||||
mork_u1* newValues = this->new_values(ev, inSlots);
|
||||
mork_change* newChanges = this->new_changes(ev, inSlots);
|
||||
|
||||
/* it is okay for newChanges to be null when changes are not held: */
|
||||
mork_bool okayChanges = ( newChanges || !this->FormHoldChanges() );
|
||||
|
||||
/* it is okay for newValues to be null when values are zero sized: */
|
||||
mork_bool okayValues = ( newValues || !this->FormValSize() );
|
||||
|
||||
if ( newBuckets && newAssocs && newKeys && okayChanges && okayValues )
|
||||
{
|
||||
outNew = morkBool_kTrue; /* yes, we created all the arrays we need */
|
||||
|
||||
/* init the old hashArrays with slots from this hash table: */
|
||||
old->mHashArrays_Heap = mMap_Heap;
|
||||
|
||||
old->mHashArrays_Slots = mMap_Slots;
|
||||
old->mHashArrays_Keys = mMap_Keys;
|
||||
old->mHashArrays_Vals = mMap_Vals;
|
||||
old->mHashArrays_Assocs = mMap_Assocs;
|
||||
old->mHashArrays_Buckets = mMap_Buckets;
|
||||
old->mHashArrays_Changes = mMap_Changes;
|
||||
|
||||
/* now replace all our array slots with the new structures: */
|
||||
++mMap_Seed; /* note the map is now changed */
|
||||
mMap_Keys = newKeys;
|
||||
mMap_Vals = newValues;
|
||||
mMap_Buckets = newBuckets;
|
||||
mMap_Assocs = newAssocs;
|
||||
mMap_FreeList = newAssocs; /* all are free to start with */
|
||||
mMap_Changes = newChanges;
|
||||
mMap_Slots = inSlots;
|
||||
}
|
||||
else /* free the partial set of arrays that were actually allocated */
|
||||
{
|
||||
nsIMdbEnv* menv = ev->AsMdbEnv();
|
||||
nsIMdbHeap* heap = mMap_Heap;
|
||||
if ( newBuckets )
|
||||
heap->Free(menv, newBuckets);
|
||||
if ( newAssocs )
|
||||
heap->Free(menv, newAssocs);
|
||||
if ( newKeys )
|
||||
heap->Free(menv, newKeys);
|
||||
if ( newValues )
|
||||
heap->Free(menv, newValues);
|
||||
if ( newChanges )
|
||||
heap->Free(menv, newChanges);
|
||||
|
||||
MORK_MEMSET(old, 0, sizeof(morkHashArrays));
|
||||
}
|
||||
|
||||
return outNew;
|
||||
}
|
||||
|
||||
/*| grow: make the map arrays bigger by 33%. The old map is completely
|
||||
**| full, or else we would not have called grow() to get more space. This
|
||||
**| means the free list is empty, and also means every old key and value is in
|
||||
**| use in the old arrays. So every key and value must be copied to the new
|
||||
**| arrays, and since they are contiguous in the old arrays, we can efficiently
|
||||
**| bitwise copy them in bulk from the old arrays to the new arrays, without
|
||||
**| paying any attention to the structure of the old arrays.
|
||||
**|
|
||||
**|| The content of the old bucket and assoc arrays need not be copied because
|
||||
**| this information is going to be completely rebuilt by rehashing all the
|
||||
**| keys into their new buckets, given the new larger map capacity. The new
|
||||
**| bucket array from new_arrays() is assumed to contain all zeroes, which is
|
||||
**| necessary to ensure the lists in each bucket stay null terminated as we
|
||||
**| build the new linked lists. (Note no old bucket ordering is preserved.)
|
||||
**|
|
||||
**|| If the old capacity is N, then in the new arrays the assocs with indexes
|
||||
**| from zero to N-1 are still allocated and must be rehashed into the map.
|
||||
**| The new free list contains all the following assocs, starting with the new
|
||||
**| assoc link at index N. (We call the links in the link array "assocs"
|
||||
**| because allocating a link is the same as allocating the key/value pair
|
||||
**| with the same index as the link.)
|
||||
**|
|
||||
**|| The new free list is initialized simply by pointing at the first new link
|
||||
**| in the assoc array after the size of the old assoc array. This assumes
|
||||
**| that FeHashTable_new_arrays() has already linked all the new assocs into a
|
||||
**| list with the first at the head of the list and the last at the tail of the
|
||||
**| list. So by making the free list point to the first of the new uncopied
|
||||
**| assocs, the list is already well-formed.
|
||||
|*/
|
||||
mork_bool morkMap::grow(morkEnv* ev)
|
||||
{
|
||||
if ( mMap_Heap ) /* can we grow the map? */
|
||||
{
|
||||
mork_num newSlots = ((mMap_Slots * 4) / 3) + 1; /* +33% */
|
||||
morkHashArrays old; /* a place to temporarily hold all the old arrays */
|
||||
if ( this->new_arrays(ev, &old, newSlots) ) /* have more? */
|
||||
{
|
||||
// morkMap_mHash hash = this->FormHash(); /* for terse loop use */
|
||||
|
||||
/* figure out the bulk volume sizes of old keys and values to move: */
|
||||
mork_num oldSlots = old.mHashArrays_Slots; /* number of old assocs */
|
||||
mork_num keyBulk = oldSlots * this->FormKeySize(); /* key volume */
|
||||
mork_num valBulk = oldSlots * this->FormValSize(); /* values */
|
||||
|
||||
/* convenient variables for new arrays that need to be rehashed: */
|
||||
morkAssoc** newBuckets = mMap_Buckets; /* new all zeroes */
|
||||
morkAssoc* newAssocs = mMap_Assocs; /* hash into buckets */
|
||||
morkAssoc* newFreeList = newAssocs + oldSlots; /* new room is free */
|
||||
mork_u1* key = mMap_Keys; /* the first key to rehash */
|
||||
--newAssocs; /* back up one before preincrement used in while loop */
|
||||
|
||||
/* move all old keys and values to the new arrays: */
|
||||
MORK_MEMCPY(mMap_Keys, old.mHashArrays_Keys, keyBulk);
|
||||
if ( valBulk ) /* are values nonzero sized? */
|
||||
MORK_MEMCPY(mMap_Vals, old.mHashArrays_Vals, valBulk);
|
||||
|
||||
mMap_FreeList = newFreeList; /* remaining assocs are free */
|
||||
|
||||
while ( ++newAssocs < newFreeList ) /* rehash another old assoc? */
|
||||
{
|
||||
morkAssoc** top = newBuckets + (this->Hash(ev, key) % newSlots);
|
||||
key += this->FormKeySize(); /* the next key to rehash */
|
||||
newAssocs->mAssoc_Next = *top; /* link to prev bucket top */
|
||||
*top = newAssocs; /* push assoc on top of bucket */
|
||||
}
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
old.finalize(ev); /* remember to free the old arrays */
|
||||
}
|
||||
}
|
||||
else ev->OutOfMemoryError();
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
|
||||
mork_bool
|
||||
morkMap::Put(morkEnv* ev, const void* inKey, const void* inVal,
|
||||
void* outKey, void* outVal, mork_change** outChange)
|
||||
{
|
||||
mork_bool outPut = morkBool_kFalse;
|
||||
|
||||
if ( this->GoodMap() ) /* looks good? */
|
||||
{
|
||||
mork_u4 hash = this->Hash(ev, inKey);
|
||||
morkAssoc** ref = this->find(ev, inKey, hash);
|
||||
if ( ref ) /* assoc was found? reuse an existing assoc slot? */
|
||||
{
|
||||
outPut = morkBool_kTrue; /* inKey was indeed already inside the map */
|
||||
}
|
||||
else /* assoc not found -- need to allocate a new assoc slot */
|
||||
{
|
||||
morkAssoc* assoc = this->pop_free_assoc();
|
||||
if ( !assoc ) /* no slots remaining in free list? must grow map? */
|
||||
{
|
||||
if ( this->grow(ev) ) /* successfully made map larger? */
|
||||
assoc = this->pop_free_assoc();
|
||||
}
|
||||
if ( assoc ) /* allocated new assoc without error? */
|
||||
{
|
||||
ref = mMap_Buckets + (hash % mMap_Slots);
|
||||
assoc->mAssoc_Next = *ref; /* link to prev bucket top */
|
||||
*ref = assoc; /* push assoc on top of bucket */
|
||||
|
||||
++mMap_Fill; /* one more member in the collection */
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
}
|
||||
}
|
||||
if ( ref ) /* did not have an error during possible growth? */
|
||||
{
|
||||
mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */
|
||||
if ( outPut && (outKey || outVal) ) /* copy old before cobbering? */
|
||||
this->get_assoc(outKey, outVal, i);
|
||||
|
||||
this->put_assoc(inKey, inVal, i);
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
|
||||
if ( outChange )
|
||||
{
|
||||
if ( mMap_Changes )
|
||||
*outChange = mMap_Changes + i;
|
||||
else
|
||||
*outChange = this->FormDummyChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outPut;
|
||||
}
|
||||
|
||||
mork_num
|
||||
morkMap::CutAll(morkEnv* ev)
|
||||
{
|
||||
mork_num outCutAll = 0;
|
||||
|
||||
if ( this->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
mork_num slots = mMap_Slots;
|
||||
morkAssoc* before = mMap_Assocs - 1; /* before first member */
|
||||
morkAssoc* assoc = before + slots; /* the very last member */
|
||||
|
||||
++mMap_Seed; /* note the map is changed */
|
||||
|
||||
/* make the assoc array a linked list headed by first & tailed by last: */
|
||||
assoc->mAssoc_Next = 0; /* null terminate the new free list */
|
||||
while ( --assoc > before ) /* another assoc to link into the list? */
|
||||
assoc->mAssoc_Next = assoc + 1;
|
||||
mMap_FreeList = mMap_Assocs; /* all are free */
|
||||
|
||||
outCutAll = mMap_Fill; /* we'll cut all of them of course */
|
||||
|
||||
mMap_Fill = 0; /* the map is completely empty */
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outCutAll;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkMap::Cut(morkEnv* ev, const void* inKey,
|
||||
void* outKey, void* outVal, mork_change** outChange)
|
||||
{
|
||||
mork_bool outCut = morkBool_kFalse;
|
||||
|
||||
if ( this->GoodMap() ) /* looks good? */
|
||||
{
|
||||
mork_u4 hash = this->Hash(ev, inKey);
|
||||
morkAssoc** ref = this->find(ev, inKey, hash);
|
||||
if ( ref ) /* found an assoc for key? */
|
||||
{
|
||||
outCut = morkBool_kTrue;
|
||||
morkAssoc* assoc = *ref;
|
||||
mork_pos i = assoc - mMap_Assocs; /* index of assoc */
|
||||
*ref = assoc->mAssoc_Next; /* unlink the found assoc */
|
||||
this->push_free_assoc(assoc); /* and put it in free list */
|
||||
|
||||
if ( outChange )
|
||||
{
|
||||
if ( mMap_Changes )
|
||||
*outChange = mMap_Changes + i;
|
||||
else
|
||||
*outChange = this->FormDummyChange();
|
||||
}
|
||||
|
||||
++mMap_Seed; /* note the map has changed */
|
||||
if ( mMap_Fill ) /* the count shows nonzero members? */
|
||||
--mMap_Fill; /* one less member in the collection */
|
||||
else
|
||||
this->NewSlotsUnderflowWarning(ev);
|
||||
}
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outCut;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkMap::Get(morkEnv* ev, const void* inKey,
|
||||
void* outKey, void* outVal, mork_change** outChange)
|
||||
{
|
||||
mork_bool outGet = morkBool_kFalse;
|
||||
|
||||
if ( this->GoodMap() ) /* looks good? */
|
||||
{
|
||||
mork_u4 hash = this->Hash(ev, inKey);
|
||||
morkAssoc** ref = this->find(ev, inKey, hash);
|
||||
if ( ref ) /* found an assoc for inKey? */
|
||||
{
|
||||
mork_pos i = (*ref) - mMap_Assocs; /* index of assoc */
|
||||
outGet = morkBool_kTrue;
|
||||
this->get_assoc(outKey, outVal, i);
|
||||
if ( outChange )
|
||||
{
|
||||
if ( mMap_Changes )
|
||||
*outChange = mMap_Changes + i;
|
||||
else
|
||||
*outChange = this->FormDummyChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadMapError(ev);
|
||||
|
||||
return outGet;
|
||||
}
|
||||
|
||||
|
||||
morkMapIter::morkMapIter( )
|
||||
: mMapIter_Map( 0 )
|
||||
, mMapIter_Seed( 0 )
|
||||
|
||||
, mMapIter_Bucket( 0 )
|
||||
, mMapIter_AssocRef( 0 )
|
||||
, mMapIter_Assoc( 0 )
|
||||
, mMapIter_Next( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
morkMapIter::InitMapIter(morkEnv* ev, morkMap* ioMap)
|
||||
{
|
||||
mMapIter_Map = 0;
|
||||
mMapIter_Seed = 0;
|
||||
|
||||
mMapIter_Bucket = 0;
|
||||
mMapIter_AssocRef = 0;
|
||||
mMapIter_Assoc = 0;
|
||||
mMapIter_Next = 0;
|
||||
|
||||
if ( ioMap )
|
||||
{
|
||||
if ( ioMap->GoodMap() )
|
||||
{
|
||||
mMapIter_Map = ioMap;
|
||||
mMapIter_Seed = ioMap->mMap_Seed;
|
||||
}
|
||||
else ioMap->NewBadMapError(ev);
|
||||
}
|
||||
else ev->NilPointerError();
|
||||
}
|
||||
|
||||
morkMapIter::morkMapIter(morkEnv* ev, morkMap* ioMap)
|
||||
: mMapIter_Map( 0 )
|
||||
, mMapIter_Seed( 0 )
|
||||
|
||||
, mMapIter_Bucket( 0 )
|
||||
, mMapIter_AssocRef( 0 )
|
||||
, mMapIter_Assoc( 0 )
|
||||
, mMapIter_Next( 0 )
|
||||
{
|
||||
if ( ioMap )
|
||||
{
|
||||
if ( ioMap->GoodMap() )
|
||||
{
|
||||
mMapIter_Map = ioMap;
|
||||
mMapIter_Seed = ioMap->mMap_Seed;
|
||||
}
|
||||
else ioMap->NewBadMapError(ev);
|
||||
}
|
||||
else ev->NilPointerError();
|
||||
}
|
||||
|
||||
void
|
||||
morkMapIter::CloseMapIter(morkEnv* ev)
|
||||
{
|
||||
mMapIter_Map = 0;
|
||||
mMapIter_Seed = 0;
|
||||
|
||||
mMapIter_Bucket = 0;
|
||||
mMapIter_AssocRef = 0;
|
||||
mMapIter_Assoc = 0;
|
||||
mMapIter_Next = 0;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::First(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outFirst = 0;
|
||||
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
morkAssoc** bucket = map->mMap_Buckets;
|
||||
morkAssoc** end = bucket + map->mMap_Slots; /* one past last */
|
||||
|
||||
mMapIter_Seed = map->mMap_Seed; /* sync the seeds */
|
||||
|
||||
while ( bucket < end ) /* another bucket in which to look for assocs? */
|
||||
{
|
||||
morkAssoc* assoc = *bucket++;
|
||||
if ( assoc ) /* found the first map assoc in use? */
|
||||
{
|
||||
mork_pos i = assoc - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outFirst = ( c )? (c + i) : map->FormDummyChange();
|
||||
|
||||
mMapIter_Assoc = assoc; /* current assoc in iteration */
|
||||
mMapIter_Next = assoc->mAssoc_Next; /* more in bucket */
|
||||
mMapIter_Bucket = --bucket; /* bucket for this assoc */
|
||||
mMapIter_AssocRef = bucket; /* slot referencing assoc */
|
||||
|
||||
map->get_assoc(outKey, outVal, i);
|
||||
|
||||
break; /* end while loop */
|
||||
}
|
||||
}
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outFirst;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::Next(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outNext = 0;
|
||||
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
|
||||
{
|
||||
morkAssoc* here = mMapIter_Assoc; /* current assoc */
|
||||
if ( here ) /* iteration is not yet concluded? */
|
||||
{
|
||||
morkAssoc* next = mMapIter_Next;
|
||||
morkAssoc* assoc = next; /* default new mMapIter_Assoc */
|
||||
if ( next ) /* there are more assocs in the same bucket after Here? */
|
||||
{
|
||||
morkAssoc** ref = mMapIter_AssocRef;
|
||||
|
||||
/* (*HereRef) equals Here, except when Here has been cut, after
|
||||
** which (*HereRef) always equals Next. So if (*HereRef) is not
|
||||
** equal to Next, then HereRef still needs to be updated to point
|
||||
** somewhere else other than Here. Otherwise it is fine.
|
||||
*/
|
||||
if ( *ref != next ) /* Here was not cut? must update HereRef? */
|
||||
mMapIter_AssocRef = &here->mAssoc_Next;
|
||||
|
||||
mMapIter_Next = next->mAssoc_Next;
|
||||
}
|
||||
else /* look for the next assoc in the next nonempty bucket */
|
||||
{
|
||||
morkAssoc** bucket = map->mMap_Buckets;
|
||||
morkAssoc** end = bucket + map->mMap_Slots; /* beyond */
|
||||
mMapIter_Assoc = 0; /* default to no more assocs */
|
||||
bucket = mMapIter_Bucket; /* last exhausted bucket */
|
||||
mMapIter_Assoc = 0; /* default to iteration ended */
|
||||
|
||||
while ( ++bucket < end ) /* another bucket to search for assocs? */
|
||||
{
|
||||
assoc = *bucket;
|
||||
if ( assoc ) /* found another map assoc in use? */
|
||||
{
|
||||
mMapIter_Bucket = bucket;
|
||||
mMapIter_AssocRef = bucket; /* ref to assoc */
|
||||
mMapIter_Next = assoc->mAssoc_Next; /* more */
|
||||
|
||||
break; /* end while loop */
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( assoc ) /* did we find another assoc in the iteration? */
|
||||
{
|
||||
mMapIter_Assoc = assoc; /* current assoc */
|
||||
mork_pos i = assoc - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outNext = ( c )? (c + i) : map->FormDummyChange();
|
||||
|
||||
map->get_assoc( outKey, outVal, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else map->NewIterOutOfSyncError(ev);
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outNext;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::Here(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outHere = 0;
|
||||
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
|
||||
{
|
||||
morkAssoc* here = mMapIter_Assoc; /* current assoc */
|
||||
if ( here ) /* iteration is not yet concluded? */
|
||||
{
|
||||
mork_pos i = here - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outHere = ( c )? (c + i) : map->FormDummyChange();
|
||||
|
||||
map->get_assoc(outKey, outVal, i);
|
||||
}
|
||||
}
|
||||
else map->NewIterOutOfSyncError(ev);
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outHere;
|
||||
}
|
||||
|
||||
mork_change*
|
||||
morkMapIter::CutHere(morkEnv* ev, void* outKey, void* outVal)
|
||||
{
|
||||
mork_change* outCutHere = 0;
|
||||
morkMap* map = mMapIter_Map;
|
||||
|
||||
if ( map && map->GoodMap() ) /* map looks good? */
|
||||
{
|
||||
if ( mMapIter_Seed == map->mMap_Seed ) /* in sync? */
|
||||
{
|
||||
morkAssoc* here = mMapIter_Assoc; /* current assoc */
|
||||
if ( here ) /* iteration is not yet concluded? */
|
||||
{
|
||||
morkAssoc** ref = mMapIter_AssocRef;
|
||||
if ( *ref != mMapIter_Next ) /* not already cut? */
|
||||
{
|
||||
mork_pos i = here - map->mMap_Assocs;
|
||||
mork_change* c = map->mMap_Changes;
|
||||
outCutHere = ( c )? (c + i) : map->FormDummyChange();
|
||||
if ( outKey || outVal )
|
||||
map->get_assoc(outKey, outVal, i);
|
||||
|
||||
map->push_free_assoc(here); /* add to free list */
|
||||
*ref = mMapIter_Next; /* unlink here from bucket list */
|
||||
|
||||
/* note the map has changed, but we are still in sync: */
|
||||
mMapIter_Seed = ++map->mMap_Seed; /* sync */
|
||||
|
||||
if ( map->mMap_Fill ) /* still has nonzero value? */
|
||||
--map->mMap_Fill; /* one less member in the collection */
|
||||
else
|
||||
map->NewSlotsUnderflowWarning(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else map->NewIterOutOfSyncError(ev);
|
||||
}
|
||||
else map->NewBadMapError(ev);
|
||||
|
||||
return outCutHere;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
372
mozilla/db/mork/src/morkMap.h
Normal file
372
mozilla/db/mork/src/morkMap.h
Normal file
@@ -0,0 +1,372 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#define _MORKMAP_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* (These hash methods closely resemble those in public domain IronDoc.) */
|
||||
|
||||
/*| Equal: equal for hash table. Note equal(a,b) implies hash(a)==hash(b).
|
||||
|*/
|
||||
typedef mork_bool (* morkMap_mEqual)
|
||||
(const morkMap* self, morkEnv* ev, const void* inKeyA, const void* inKeyB);
|
||||
|
||||
/*| Hash: hash for hash table. Note equal(a,b) implies hash(a)==hash(b).
|
||||
|*/
|
||||
typedef mork_u4 (* morkMap_mHash)
|
||||
(const morkMap* self, morkEnv* ev, const void* inKey);
|
||||
|
||||
/*| IsNil: whether a key slot contains a "null" value denoting "no such key".
|
||||
|*/
|
||||
typedef mork_bool (* morkMap_mIsNil)
|
||||
(const morkMap* self, morkEnv* ev, const void* inKey);
|
||||
|
||||
/*| Note: notify regarding a refcounting change for a key or a value.
|
||||
|*/
|
||||
//typedef void (* morkMap_mNote)
|
||||
//(morkMap* self, morkEnv* ev, void* inKeyOrVal);
|
||||
|
||||
/*| morkMapForm: slots need to initialize a new dict. (This is very similar
|
||||
**| to the config object for public domain IronDoc hash tables.)
|
||||
|*/
|
||||
class morkMapForm { // a struct of callback method pointers for morkMap
|
||||
public:
|
||||
|
||||
// const void* mMapForm_NilKey; // externally defined 'nil' bit pattern
|
||||
|
||||
// void* mMapForm_NilBuf[ 8 ]; // potential place to put NilKey
|
||||
// If keys are no larger than 8*sizeof(void*), NilKey can be put in NilBuf.
|
||||
// Note this should be true for all Mork subclasses, and we plan usage so.
|
||||
|
||||
// These three methods must always be provided, so zero will cause errors:
|
||||
|
||||
// morkMap_mEqual mMapForm_Equal; // for comparing two keys for identity
|
||||
// morkMap_mHash mMapForm_Hash; // deterministic key to hash method
|
||||
// morkMap_mIsNil mMapForm_IsNil; // to query whether a key equals 'nil'
|
||||
|
||||
// If any of these method slots are nonzero, then morkMap will call the
|
||||
// appropriate one to notify dict users when a key or value is added or cut.
|
||||
// Presumably a caller wants to know this in order to perform refcounting or
|
||||
// some other kind of memory management. These methods are definitely only
|
||||
// called when references to keys or values are inserted or removed, and are
|
||||
// never called when the actual number of references does not change (such
|
||||
// as when added keys are already present or cut keys are alreading missing).
|
||||
//
|
||||
// morkMap_mNote mMapForm_AddKey; // if nonzero, notify about add key
|
||||
// morkMap_mNote mMapForm_CutKey; // if nonzero, notify about cut key
|
||||
// morkMap_mNote mMapForm_AddVal; // if nonzero, notify about add val
|
||||
// morkMap_mNote mMapForm_CutVal; // if nonzero, notify about cut val
|
||||
//
|
||||
// These note methods have been removed because it seems difficult to
|
||||
// guarantee suitable alignment of objects passed to notification methods.
|
||||
|
||||
// Note dict clients should pick key and val sizes that provide whatever
|
||||
// alignment will be required for an array of such keys and values.
|
||||
mork_size mMapForm_KeySize; // size of every key (cannot be zero)
|
||||
mork_size mMapForm_ValSize; // size of every val (can indeed be zero)
|
||||
|
||||
mork_bool mMapForm_HoldChanges; // support changes array in the map
|
||||
mork_change mMapForm_DummyChange; // change used for false HoldChanges
|
||||
mork_bool mMapForm_KeyIsIP; // key is mork_ip sized
|
||||
mork_bool mMapForm_ValIsIP; // key is mork_ip sized
|
||||
};
|
||||
|
||||
/*| morkAssoc: a canonical association slot in a morkMap. A single assoc
|
||||
**| instance does nothing except point to the next assoc in the same bucket
|
||||
**| of a hash table. Each assoc has only two interesting attributes: 1) the
|
||||
**| address of the assoc, and 2) the next assoc in a bucket's list. The assoc
|
||||
**| address is interesting because in the context of an array of such assocs,
|
||||
**| one can determine the index of a particular assoc in the array by address
|
||||
**| arithmetic, subtracting the array address from the assoc address. And the
|
||||
**| index of each assoc is the same index as the associated key and val slots
|
||||
**| in the associated arrays
|
||||
**|
|
||||
**|| Think of an assoc instance as really also containing a key slot and a val
|
||||
**| slot, where each key is mMap_Form.mMapForm_KeySize bytes in size, and
|
||||
**| each val is mMap_Form.mMapForm_ValSize in size. But the key and val
|
||||
**| slots are stored in separate arrays with indexes that are parallel to the
|
||||
**| indexes in the array of morkAssoc instances. We have taken the variable
|
||||
**| sized slots out of the morkAssoc structure, and put them into parallel
|
||||
**| arrays associated with each morkAssoc by array index. And this leaves us
|
||||
**| with only the link field to the next assoc in each assoc instance.
|
||||
|*/
|
||||
class morkAssoc {
|
||||
public:
|
||||
morkAssoc* mAssoc_Next;
|
||||
};
|
||||
|
||||
|
||||
#define morkDerived_kMap /*i*/ 0x4D70 /* ascii 'Mp' */
|
||||
|
||||
#define morkMap_kTag /*i*/ 0x6D4D6150 /* ascii 'mMaP' */
|
||||
|
||||
/*| morkMap: a hash table based on the public domain IronDoc hash table
|
||||
**| (which is in turn rather like a similar OpenDoc hash table).
|
||||
|*/
|
||||
class morkMap : public morkNode {
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
nsIMdbHeap* mMap_Heap; // strong ref to heap allocating all space
|
||||
mork_u4 mMap_Tag; // must equal morkMap_kTag
|
||||
|
||||
// When a morkMap instance is constructed, the dict form slots must be
|
||||
// provided in order to properly configure a dict with all runtime needs:
|
||||
|
||||
morkMapForm mMap_Form; // construction time parameterization
|
||||
|
||||
// Whenever the dict changes structure in a way that would affect any
|
||||
// iteration of the dict associations, the seed increments to show this:
|
||||
|
||||
mork_seed mMap_Seed; // counter for member and structural changes
|
||||
|
||||
// The current total assoc capacity of the dict is mMap_Slots, where
|
||||
// mMap_Fill of these slots are actually holding content, so mMap_Fill
|
||||
// is the actual membership count, and mMap_Slots is how larger membership
|
||||
// can become before the hash table must grow the buffers being used.
|
||||
|
||||
mork_count mMap_Slots; // count of slots in the hash table
|
||||
mork_fill mMap_Fill; // number of used slots in the hash table
|
||||
|
||||
// Key and value slots are bound to corresponding mMap_Assocs array slots.
|
||||
// Instead of having a single array like this: {key,val,next}[ mMap_Slots ]
|
||||
// we have instead three parallel arrays with essentially the same meaning:
|
||||
// {key}[ mMap_Slots ], {val}[ mMap_Slots ], {assocs}[ mMap_Slots ]
|
||||
|
||||
mork_u1* mMap_Keys; // mMap_Slots * mMapForm_KeySize buffer
|
||||
mork_u1* mMap_Vals; // mMap_Slots * mMapForm_ValSize buffer
|
||||
|
||||
// An assoc is "used" when it appears in a bucket's linked list of assocs.
|
||||
// Until an assoc is used, it appears in the FreeList linked list. Every
|
||||
// assoc that becomes used goes into the bucket determined by hashing the
|
||||
// key associated with a new assoc. The key associated with a new assoc
|
||||
// goes in to the slot in mMap_Keys which occupies exactly the same array
|
||||
// index as the array index of the used assoc in the mMap_Assocs array.
|
||||
|
||||
morkAssoc* mMap_Assocs; // mMap_Slots * sizeof(morkAssoc) buffer
|
||||
|
||||
// The changes array is only needed when the
|
||||
|
||||
mork_change* mMap_Changes; // mMap_Slots * sizeof(mork_change) buffer
|
||||
|
||||
// The Buckets array need not be the same length as the Assocs array, but we
|
||||
// usually do it that way so the average bucket depth is no more than one.
|
||||
// (We could pick a different policy, or make it parameterizable, but that's
|
||||
// tuning we can do some other time.)
|
||||
|
||||
morkAssoc** mMap_Buckets; // mMap_Slots * sizeof(morkAssoc*) buffer
|
||||
|
||||
// The length of the mMap_FreeList should equal (mMap_Slots - mMap_Fill).
|
||||
// We need a free list instead of a simpler representation because assocs
|
||||
// can be cut and returned to availability in any kind of unknown pattern.
|
||||
// (However, when assocs are first allocated, or when the dict is grown, we
|
||||
// know all new assocs are contiguous and can chain together adjacently.)
|
||||
|
||||
morkAssoc* mMap_FreeList; // list of unused mMap_Assocs array slots
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseMap() only if open
|
||||
virtual ~morkMap(); // assert that CloseMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkMap(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioNodeHeap,
|
||||
mork_size inKeySize, mork_size inValSize,
|
||||
mork_size inSlots, nsIMdbHeap* ioSlotHeap, mork_bool inHoldChanges);
|
||||
|
||||
void CloseMap(morkEnv* ev); // called by
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // poly map hash table methods
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const = 0;
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const = 0;
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // open utitity methods
|
||||
|
||||
mork_bool GoodMapTag() const { return mMap_Tag == morkMap_kTag; }
|
||||
mork_bool GoodMap() const
|
||||
{ return ( IsNode() && GoodMapTag() ); }
|
||||
|
||||
void NewIterOutOfSyncError(morkEnv* ev);
|
||||
void NewBadMapError(morkEnv* ev);
|
||||
void NewSlotsUnderflowWarning(morkEnv* ev);
|
||||
void InitMap(morkEnv* ev, mork_size inSlots);
|
||||
|
||||
protected: // internal utitity methods
|
||||
|
||||
friend class morkMapIter;
|
||||
void clear_map(morkEnv* ev, nsIMdbHeap* ioHeap);
|
||||
|
||||
void* alloc(morkEnv* ev, mork_size inSize);
|
||||
void* clear_alloc(morkEnv* ev, mork_size inSize);
|
||||
|
||||
void push_free_assoc(morkAssoc* ioAssoc)
|
||||
{
|
||||
ioAssoc->mAssoc_Next = mMap_FreeList;
|
||||
mMap_FreeList = ioAssoc;
|
||||
}
|
||||
|
||||
morkAssoc* pop_free_assoc()
|
||||
{
|
||||
morkAssoc* assoc = mMap_FreeList;
|
||||
if ( assoc )
|
||||
mMap_FreeList = assoc->mAssoc_Next;
|
||||
return assoc;
|
||||
}
|
||||
|
||||
morkAssoc** find(morkEnv* ev, const void* inKey, mork_u4 inHash) const;
|
||||
|
||||
mork_u1* new_keys(morkEnv* ev, mork_num inSlots);
|
||||
mork_u1* new_values(morkEnv* ev, mork_num inSlots);
|
||||
mork_change* new_changes(morkEnv* ev, mork_num inSlots);
|
||||
morkAssoc** new_buckets(morkEnv* ev, mork_num inSlots);
|
||||
morkAssoc* new_assocs(morkEnv* ev, mork_num inSlots);
|
||||
mork_bool new_arrays(morkEnv* ev, morkHashArrays* old, mork_num inSlots);
|
||||
|
||||
mork_bool grow(morkEnv* ev);
|
||||
|
||||
void get_assoc(void* outKey, void* outVal, mork_pos inPos) const;
|
||||
void put_assoc(const void* inKey, const void* inVal, mork_pos inPos) const;
|
||||
|
||||
public: // inlines to form slots
|
||||
// const void* FormNilKey() const { return mMap_Form.mMapForm_NilKey; }
|
||||
|
||||
// morkMap_mEqual FormEqual() const { return mMap_Form.mMapForm_Equal; }
|
||||
// morkMap_mHash FormHash() const { return mMap_Form.mMapForm_Hash; }
|
||||
// orkMap_mIsNil FormIsNil() const { return mMap_Form.mMapForm_IsNil; }
|
||||
|
||||
// morkMap_mNote FormAddKey() const { return mMap_Form.mMapForm_AddKey; }
|
||||
// morkMap_mNote FormCutKey() const { return mMap_Form.mMapForm_CutKey; }
|
||||
// morkMap_mNote FormAddVal() const { return mMap_Form.mMapForm_AddVal; }
|
||||
// morkMap_mNote FormCutVal() const { return mMap_Form.mMapForm_CutVal; }
|
||||
|
||||
mork_size FormKeySize() const { return mMap_Form.mMapForm_KeySize; }
|
||||
mork_size FormValSize() const { return mMap_Form.mMapForm_ValSize; }
|
||||
|
||||
mork_bool FormKeyIsIP() const { return mMap_Form.mMapForm_KeyIsIP; }
|
||||
mork_bool FormValIsIP() const { return mMap_Form.mMapForm_ValIsIP; }
|
||||
|
||||
mork_bool FormHoldChanges() const
|
||||
{ return mMap_Form.mMapForm_HoldChanges; }
|
||||
|
||||
mork_change* FormDummyChange()
|
||||
{ return &mMap_Form.mMapForm_DummyChange; }
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool Put(morkEnv* ev, const void* inKey, const void* inVal,
|
||||
void* outKey, void* outVal, mork_change** outChange);
|
||||
|
||||
mork_bool Cut(morkEnv* ev, const void* inKey,
|
||||
void* outKey, void* outVal, mork_change** outChange);
|
||||
|
||||
mork_bool Get(morkEnv* ev, const void* inKey,
|
||||
void* outKey, void* outVal, mork_change** outChange);
|
||||
|
||||
mork_num CutAll(morkEnv* ev);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkMap(const morkMap& other);
|
||||
morkMap& operator=(const morkMap& other);
|
||||
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakMap(morkMap* me,
|
||||
morkEnv* ev, morkMap** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongMap(morkMap* me,
|
||||
morkEnv* ev, morkMap** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
/*| morkMapIter: an iterator for morkMap and subclasses. This is not a node,
|
||||
**| and expected usage is as a member of some other node subclass, such as in
|
||||
**| a cursor subclass or a thumb subclass. Also, iters might be as temp stack
|
||||
**| objects when scanning the content of a map.
|
||||
|*/
|
||||
class morkMapIter{ // iterator for hash table map
|
||||
|
||||
protected:
|
||||
morkMap* mMapIter_Map; // map to iterate, NOT refcounted
|
||||
mork_seed mMapIter_Seed; // cached copy of map's seed
|
||||
|
||||
morkAssoc** mMapIter_Bucket; // one bucket in mMap_Buckets array
|
||||
morkAssoc** mMapIter_AssocRef; // usually *AtRef equals Here
|
||||
morkAssoc* mMapIter_Assoc; // the current assoc in an iteration
|
||||
morkAssoc* mMapIter_Next; // mMapIter_Assoc->mAssoc_Next */
|
||||
|
||||
public:
|
||||
morkMapIter(morkEnv* ev, morkMap* ioMap);
|
||||
void CloseMapIter(morkEnv* ev);
|
||||
|
||||
morkMapIter( ); // everything set to zero -- need to call InitMapIter()
|
||||
|
||||
protected: // we want all subclasses to provide typesafe wrappers:
|
||||
|
||||
void InitMapIter(morkEnv* ev, morkMap* ioMap);
|
||||
|
||||
// The morkAssoc returned below is always either mork_change* or
|
||||
// else nil (when there is no such assoc). We return a pointer to
|
||||
// the change rather than a simple bool, because callers might
|
||||
// want to access change info associated with an assoc.
|
||||
|
||||
mork_change* First(morkEnv* ev, void* outKey, void* outVal);
|
||||
mork_change* Next(morkEnv* ev, void* outKey, void* outVal);
|
||||
mork_change* Here(morkEnv* ev, void* outKey, void* outVal);
|
||||
|
||||
mork_change* CutHere(morkEnv* ev, void* outKey, void* outVal);
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKMAP_ */
|
||||
576
mozilla/db/mork/src/morkNode.cpp
Normal file
576
mozilla/db/mork/src/morkNode.cpp
Normal file
@@ -0,0 +1,576 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
/*3456789_123456789_123456789_123456789_123456789_123456789_123456789_12345678*/
|
||||
|
||||
/* ===== ===== ===== ===== morkUsage ===== ===== ===== ===== */
|
||||
|
||||
static morkUsage morkUsage_gHeap; // ensure EnsureReadyStaticUsage()
|
||||
const morkUsage& morkUsage::kHeap = morkUsage_gHeap;
|
||||
|
||||
static morkUsage morkUsage_gStack; // ensure EnsureReadyStaticUsage()
|
||||
const morkUsage& morkUsage::kStack = morkUsage_gStack;
|
||||
|
||||
static morkUsage morkUsage_gMember; // ensure EnsureReadyStaticUsage()
|
||||
const morkUsage& morkUsage::kMember = morkUsage_gMember;
|
||||
|
||||
static morkUsage morkUsage_gGlobal; // ensure EnsureReadyStaticUsage()
|
||||
const morkUsage& morkUsage::kGlobal = morkUsage_gGlobal;
|
||||
|
||||
static morkUsage morkUsage_gPool; // ensure EnsureReadyStaticUsage()
|
||||
const morkUsage& morkUsage::kPool = morkUsage_gPool;
|
||||
|
||||
static morkUsage morkUsage_gNone; // ensure EnsureReadyStaticUsage()
|
||||
const morkUsage& morkUsage::kNone = morkUsage_gNone;
|
||||
|
||||
// This must be structured to allow for non-zero values in global variables
|
||||
// just before static init time. We can only safely check for whether a
|
||||
// global has the address of some other global. Please, do not initialize
|
||||
// either of the variables below to zero, because this could break when a zero
|
||||
// is assigned at static init time, but after EnsureReadyStaticUsage() runs.
|
||||
|
||||
static mork_u4 morkUsage_g_static_init_target; // only address of this matters
|
||||
static mork_u4* morkUsage_g_static_init_done; // is address of target above?
|
||||
|
||||
#define morkUsage_do_static_init() \
|
||||
( morkUsage_g_static_init_done = &morkUsage_g_static_init_target )
|
||||
|
||||
#define morkUsage_need_static_init() \
|
||||
( morkUsage_g_static_init_done != &morkUsage_g_static_init_target )
|
||||
|
||||
/*static*/
|
||||
void morkUsage::EnsureReadyStaticUsage()
|
||||
{
|
||||
if ( morkUsage_need_static_init() )
|
||||
{
|
||||
morkUsage_do_static_init();
|
||||
|
||||
morkUsage_gHeap.InitUsage(morkUsage_kHeap);
|
||||
morkUsage_gStack.InitUsage(morkUsage_kStack);
|
||||
morkUsage_gMember.InitUsage(morkUsage_kMember);
|
||||
morkUsage_gGlobal.InitUsage(morkUsage_kGlobal);
|
||||
morkUsage_gPool.InitUsage(morkUsage_kPool);
|
||||
morkUsage_gNone.InitUsage(morkUsage_kNone);
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const morkUsage& morkUsage::GetHeap() // kHeap safe at static init time
|
||||
{
|
||||
EnsureReadyStaticUsage();
|
||||
return morkUsage_gHeap;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const morkUsage& morkUsage::GetStack() // kStack safe at static init time
|
||||
{
|
||||
EnsureReadyStaticUsage();
|
||||
return morkUsage_gStack;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const morkUsage& morkUsage::GetMember() // kMember safe at static init time
|
||||
{
|
||||
EnsureReadyStaticUsage();
|
||||
return morkUsage_gMember;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const morkUsage& morkUsage::GetGlobal() // kGlobal safe at static init time
|
||||
{
|
||||
EnsureReadyStaticUsage();
|
||||
return morkUsage_gGlobal;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const morkUsage& morkUsage::GetPool() // kPool safe at static init time
|
||||
{
|
||||
EnsureReadyStaticUsage();
|
||||
return morkUsage_gPool;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const morkUsage& morkUsage::GetNone() // kNone safe at static init time
|
||||
{
|
||||
EnsureReadyStaticUsage();
|
||||
return morkUsage_gNone;
|
||||
}
|
||||
|
||||
morkUsage::morkUsage()
|
||||
{
|
||||
if ( morkUsage_need_static_init() )
|
||||
{
|
||||
morkUsage::EnsureReadyStaticUsage();
|
||||
}
|
||||
}
|
||||
|
||||
morkUsage::morkUsage(mork_usage code)
|
||||
: mUsage_Code(code)
|
||||
{
|
||||
if ( morkUsage_need_static_init() )
|
||||
{
|
||||
morkUsage::EnsureReadyStaticUsage();
|
||||
}
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*static*/ void*
|
||||
morkNode::MakeNew(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev)
|
||||
{
|
||||
void* node = 0;
|
||||
if ( &ioHeap )
|
||||
{
|
||||
ioHeap.Alloc(ev->AsMdbEnv(), inSize, (void **) &node);
|
||||
if ( !node )
|
||||
ev->OutOfMemoryError();
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkNode::OnDeleteAssert(void* ioAddress) // cannot operator delete()
|
||||
{
|
||||
MORK_USED_1(ioAddress);
|
||||
MORK_ASSERT(morkBool_kFalse); // tell developer: must not delete nodes
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkNode::ZapOld(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
// relaces operator delete()
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->morkNode::~morkNode(); // first call polymorphic destructor
|
||||
if ( ioHeap ) // was this node heap allocated?
|
||||
ioHeap->Free(ev->AsMdbEnv(), this);
|
||||
else if ( mNode_Usage == morkUsage_kPool )
|
||||
{
|
||||
morkHandle* h = (morkHandle*) this;
|
||||
if ( h->IsHandle() && h->GoodHandleTag() )
|
||||
{
|
||||
if ( h->mHandle_Face )
|
||||
{
|
||||
ev->mEnv_HandlePool->ZapHandle(ev, h->mHandle_Face);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
/*public virtual*/ void
|
||||
morkNode::CloseMorkNode(morkEnv* ev) // CloseNode() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseNode(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkNode::~morkNode() // assert that CloseNode() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
mNode_Access = morkAccess_kDead;
|
||||
mNode_Usage = morkUsage_kNone;
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
// void CloseMorkNode(morkEnv* ev) = 0; // CloseNode() only if open
|
||||
// CloseMorkNode() is the polymorphic close method called when uses==0,
|
||||
// which must do NOTHING at all when IsOpenNode() is not true. Otherwise,
|
||||
// CloseMorkNode() should call a static close method specific to an object.
|
||||
// Each such static close method should either call inherited static close
|
||||
// methods, or else perform the consolidated effect of calling them, where
|
||||
// subclasses should closely track any changes in base classes with care.
|
||||
|
||||
|
||||
/*public non-poly*/
|
||||
morkNode::morkNode(const morkUsage& inUsage, nsIMdbHeap* ioHeap)
|
||||
: mNode_Heap( ioHeap )
|
||||
, mNode_Base( morkBase_kNode )
|
||||
, mNode_Derived ( 0 ) // until subclass sets appropriately
|
||||
, mNode_Access( morkAccess_kOpen )
|
||||
, mNode_Usage( inUsage.Code() )
|
||||
, mNode_Mutable( morkAble_kEnabled )
|
||||
, mNode_Load( morkLoad_kClean )
|
||||
, mNode_Uses( 1 )
|
||||
, mNode_Refs( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkNode::morkNode(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap)
|
||||
: mNode_Heap( ioHeap )
|
||||
, mNode_Base( morkBase_kNode )
|
||||
, mNode_Derived ( 0 ) // until subclass sets appropriately
|
||||
, mNode_Access( morkAccess_kOpen )
|
||||
, mNode_Usage( inUsage.Code() )
|
||||
, mNode_Mutable( morkAble_kEnabled )
|
||||
, mNode_Load( morkLoad_kClean )
|
||||
, mNode_Uses( 1 )
|
||||
, mNode_Refs( 1 )
|
||||
{
|
||||
if ( !ioHeap && mNode_Usage == morkUsage_kHeap )
|
||||
{
|
||||
this->NilHeapError(ev);
|
||||
}
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::RefsUnderUsesWarning(morkEnv* ev) const
|
||||
{
|
||||
ev->NewError("mNode_Refs < mNode_Uses");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::NonNodeError(morkEnv* ev) const // called when IsNode() is false
|
||||
{
|
||||
ev->NewError("non-morkNode");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::NonOpenNodeError(morkEnv* ev) const // when IsOpenNode() is false
|
||||
{
|
||||
ev->NewError("non-open-morkNode");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::NonMutableNodeError(morkEnv* ev) const // when IsMutable() is false
|
||||
{
|
||||
ev->NewError("non-mutable-morkNode");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::NilHeapError(morkEnv* ev) const // zero mNode_Heap w/ kHeap usage
|
||||
{
|
||||
ev->NewError("nil mNode_Heap");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::RefsOverflowWarning(morkEnv* ev) const // mNode_Refs overflow
|
||||
{
|
||||
ev->NewWarning("mNode_Refs overflow");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::UsesOverflowWarning(morkEnv* ev) const // mNode_Uses overflow
|
||||
{
|
||||
ev->NewWarning("mNode_Uses overflow");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::RefsUnderflowWarning(morkEnv* ev) const // mNode_Refs underflow
|
||||
{
|
||||
ev->NewWarning("mNode_Refs underflow");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkNode::UsesUnderflowWarning(morkEnv* ev) const // mNode_Uses underflow
|
||||
{
|
||||
ev->NewWarning("mNode_Uses underflow");
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkNode::CloseNode(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
this->MarkShut();
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
|
||||
void // utility method very similar to morkNode::SlotStrongNode():
|
||||
nsIMdbHeap_SlotStrongHeap(nsIMdbHeap* self, morkEnv* ev, nsIMdbHeap** ioSlot)
|
||||
// If *ioSlot is non-nil, that heap is released by CutStrongRef() and
|
||||
// then zeroed out. Then if this is non-nil, this is acquired by
|
||||
// calling AddStrongRef(), and if the return value shows success,
|
||||
// then this is put into slot *ioSlot. Note self can be nil, so we
|
||||
// permit expression 'nsIMdbHeap_SlotStrongHeap(0, ev, &slot)'.
|
||||
{
|
||||
nsIMdbEnv* menv = ev->AsMdbEnv();
|
||||
nsIMdbHeap* heap = *ioSlot;
|
||||
if ( heap )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
heap->CutStrongRef(menv);
|
||||
}
|
||||
if ( self && ev->Good() && (self->AddStrongRef(menv)==0) && ev->Good() )
|
||||
*ioSlot = self;
|
||||
}
|
||||
|
||||
/*public static*/ void
|
||||
morkNode::SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
|
||||
// If *ioSlot is non-nil, that node is released by CutStrongRef() and
|
||||
// then zeroed out. Then if me is non-nil, this is acquired by
|
||||
// calling AddStrongRef(), and if positive is returned to show success,
|
||||
// then me is put into slot *ioSlot. Note me can be nil, so we take
|
||||
// expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'.
|
||||
{
|
||||
morkNode* node = *ioSlot;
|
||||
if ( node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutStrongRef(ev);
|
||||
}
|
||||
if ( me && me->AddStrongRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
|
||||
/*public static*/ void
|
||||
morkNode::SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot)
|
||||
// If *ioSlot is non-nil, that node is released by CutWeakRef() and
|
||||
// then zeroed out. Then if me is non-nil, this is acquired by
|
||||
// calling AddWeakRef(), and if positive is returned to show success,
|
||||
// then me is put into slot *ioSlot. Note me can be nil, so we
|
||||
// expression 'morkNode::SlotWeakNode((morkNode*) 0, ev, &slot)'.
|
||||
{
|
||||
morkNode* node = *ioSlot;
|
||||
if ( node )
|
||||
{
|
||||
*ioSlot = 0;
|
||||
node->CutWeakRef(ev);
|
||||
}
|
||||
if ( me && me->AddWeakRef(ev) )
|
||||
*ioSlot = me;
|
||||
}
|
||||
|
||||
/*public non-poly*/ mork_uses
|
||||
morkNode::AddStrongRef(morkEnv* ev)
|
||||
{
|
||||
mork_uses outUses = 0;
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mork_uses uses = mNode_Uses;
|
||||
mork_refs refs = mNode_Refs;
|
||||
if ( refs < uses ) // need to fix broken refs/uses relation?
|
||||
{
|
||||
this->RefsUnderUsesWarning(ev);
|
||||
mNode_Refs = mNode_Uses = refs = uses;
|
||||
}
|
||||
if ( refs < morkNode_kMaxRefCount ) // not too great?
|
||||
{
|
||||
mNode_Refs = ++refs;
|
||||
mNode_Uses = ++uses;
|
||||
}
|
||||
else
|
||||
this->RefsOverflowWarning(ev);
|
||||
|
||||
outUses = uses;
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
return outUses;
|
||||
}
|
||||
|
||||
/*private non-poly*/ mork_bool
|
||||
morkNode::cut_use_count(morkEnv* ev) // just one part of CutStrongRef()
|
||||
{
|
||||
mork_bool didCut = morkBool_kFalse;
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mork_uses uses = mNode_Uses;
|
||||
if ( uses ) // not yet zero?
|
||||
mNode_Uses = --uses;
|
||||
else
|
||||
this->UsesUnderflowWarning(ev);
|
||||
|
||||
didCut = morkBool_kTrue;
|
||||
if ( !mNode_Uses ) // last use gone? time to close node?
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
if ( !mNode_Refs ) // no outstanding reference?
|
||||
{
|
||||
this->RefsUnderflowWarning(ev);
|
||||
++mNode_Refs; // prevent potential crash during close
|
||||
}
|
||||
this->CloseMorkNode(ev); // polymorphic self close
|
||||
// (Note CutNode() is not polymorphic -- so don't call that.)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
return didCut;
|
||||
}
|
||||
|
||||
/*public non-poly*/ mork_uses
|
||||
morkNode::CutStrongRef(morkEnv* ev)
|
||||
{
|
||||
mork_refs outRefs = 0;
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( this->cut_use_count(ev) )
|
||||
outRefs = this->CutWeakRef(ev);
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
return outRefs;
|
||||
}
|
||||
|
||||
/*public non-poly*/ mork_refs
|
||||
morkNode::AddWeakRef(morkEnv* ev)
|
||||
{
|
||||
mork_refs outRefs = 0;
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mork_refs refs = mNode_Refs;
|
||||
if ( refs < morkNode_kMaxRefCount ) // not too great?
|
||||
mNode_Refs = ++refs;
|
||||
else
|
||||
this->RefsOverflowWarning(ev);
|
||||
|
||||
outRefs = refs;
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
return outRefs;
|
||||
}
|
||||
|
||||
/*public non-poly*/ mork_refs
|
||||
morkNode::CutWeakRef(morkEnv* ev)
|
||||
{
|
||||
mork_refs outRefs = 0;
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mork_uses uses = mNode_Uses;
|
||||
mork_refs refs = mNode_Refs;
|
||||
if ( refs ) // not yet zero?
|
||||
mNode_Refs = --refs;
|
||||
else
|
||||
this->RefsUnderflowWarning(ev);
|
||||
|
||||
if ( refs < uses ) // need to fix broken refs/uses relation?
|
||||
{
|
||||
this->RefsUnderUsesWarning(ev);
|
||||
mNode_Refs = mNode_Uses = refs = uses;
|
||||
}
|
||||
|
||||
outRefs = refs;
|
||||
if ( !refs ) // last reference gone? time to destroy node?
|
||||
this->ZapOld(ev, mNode_Heap); // self destroy, use this no longer
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
return outRefs;
|
||||
}
|
||||
|
||||
static const char* morkNode_kBroken = "broken";
|
||||
|
||||
/*public non-poly*/ const char*
|
||||
morkNode::GetNodeAccessAsString() const // e.g. "open", "shut", etc.
|
||||
{
|
||||
const char* outString = morkNode_kBroken;
|
||||
switch( mNode_Access )
|
||||
{
|
||||
case morkAccess_kOpen: outString = "open"; break;
|
||||
case morkAccess_kClosing: outString = "closing"; break;
|
||||
case morkAccess_kShut: outString = "shut"; break;
|
||||
case morkAccess_kDead: outString = "dead"; break;
|
||||
}
|
||||
return outString;
|
||||
}
|
||||
|
||||
/*public non-poly*/ const char*
|
||||
morkNode::GetNodeUsageAsString() const // e.g. "heap", "stack", etc.
|
||||
{
|
||||
const char* outString = morkNode_kBroken;
|
||||
switch( mNode_Usage )
|
||||
{
|
||||
case morkUsage_kHeap: outString = "heap"; break;
|
||||
case morkUsage_kStack: outString = "stack"; break;
|
||||
case morkUsage_kMember: outString = "member"; break;
|
||||
case morkUsage_kGlobal: outString = "global"; break;
|
||||
case morkUsage_kPool: outString = "pool"; break;
|
||||
case morkUsage_kNone: outString = "none"; break;
|
||||
}
|
||||
return outString;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
274
mozilla/db/mork/src/morkNode.h
Normal file
274
mozilla/db/mork/src/morkNode.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#define _MORKNODE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkUsage_kHeap 'h'
|
||||
#define morkUsage_kStack 's'
|
||||
#define morkUsage_kMember 'm'
|
||||
#define morkUsage_kGlobal 'g'
|
||||
#define morkUsage_kPool 'p'
|
||||
#define morkUsage_kNone 'n'
|
||||
|
||||
class morkUsage {
|
||||
public:
|
||||
mork_usage mUsage_Code; // kHeap, kStack, kMember, or kGhost
|
||||
|
||||
public:
|
||||
morkUsage(mork_usage inCode);
|
||||
|
||||
morkUsage(); // does nothing except maybe call EnsureReadyStaticUsage()
|
||||
void InitUsage( mork_usage inCode)
|
||||
{ mUsage_Code = inCode; }
|
||||
|
||||
~morkUsage() { }
|
||||
mork_usage Code() const { return mUsage_Code; }
|
||||
|
||||
static void EnsureReadyStaticUsage();
|
||||
|
||||
public:
|
||||
static const morkUsage& kHeap; // morkUsage_kHeap
|
||||
static const morkUsage& kStack; // morkUsage_kStack
|
||||
static const morkUsage& kMember; // morkUsage_kMember
|
||||
static const morkUsage& kGlobal; // morkUsage_kGlobal
|
||||
static const morkUsage& kPool; // morkUsage_kPool
|
||||
static const morkUsage& kNone; // morkUsage_kNone
|
||||
|
||||
static const morkUsage& GetHeap(); // kHeap, safe at static init time
|
||||
static const morkUsage& GetStack(); // kStack, safe at static init time
|
||||
static const morkUsage& GetMember(); // kMember, safe at static init time
|
||||
static const morkUsage& GetGlobal(); // kGlobal, safe at static init time
|
||||
static const morkUsage& GetPool(); // kPool, safe at static init time
|
||||
static const morkUsage& GetNone(); // kNone, safe at static init time
|
||||
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkNode_kMaxRefCount 0x0FFFF /* count sticks if it hits this */
|
||||
|
||||
#define morkBase_kNode /*i*/ 0x4E64 /* ascii 'Nd' */
|
||||
|
||||
/*| morkNode: several groups of two-byte integers that track the basic
|
||||
**| status of an object that can be used to compose in-memory graphs.
|
||||
**| This is the base class for nsIMdbObject (which adds members that fit
|
||||
**| the needs of an nsIMdbObject subclass). The morkNode class is also used
|
||||
**| as the base class for other Mork db classes with no strong relation to
|
||||
**| the MDB class hierarchy.
|
||||
**|
|
||||
**|| Heap: the heap in which this node was allocated, when the usage equals
|
||||
**| morkUsage_kHeap to show dynamic allocation. Note this heap is NOT ref-
|
||||
**| counted, because that would be too great and complex a burden for all
|
||||
**| the nodes allocated in that heap. So heap users should take care to
|
||||
**| understand that nodes allocated in that heap are considered protected
|
||||
**| by some inclusive context in which all those nodes are allocated, and
|
||||
**| that context must maintain at least one strong refcount for the heap.
|
||||
**| Occasionally a node subclass will indeed wish to hold a refcounted
|
||||
**| reference to a heap, and possibly the same heap that is in mNode_Heap,
|
||||
**| but this is always done in a separate slot that explicitly refcounts,
|
||||
**| so we avoid confusing what is meant by the mNode_Heap slot.
|
||||
|*/
|
||||
class morkNode { // base class for constructing Mork object graphs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
nsIMdbHeap* mNode_Heap; // NON-refcounted heap pointer
|
||||
|
||||
mork_base mNode_Base; // must equal morkBase_kNode
|
||||
mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
mork_able mNode_Mutable; // can this node be modified?
|
||||
mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
mork_uses mNode_Uses; // refcount for strong refs
|
||||
mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
protected: // special case empty construction for morkHandleFrame
|
||||
friend class morkHandleFrame;
|
||||
morkNode() { }
|
||||
|
||||
public: // inlines for weird mNode_Mutable and mNode_Load constants
|
||||
|
||||
void SetFrozen() { mNode_Mutable = morkAble_kDisabled; }
|
||||
void SetMutable() { mNode_Mutable = morkAble_kEnabled; }
|
||||
void SetAsleep() { mNode_Mutable = morkAble_kAsleep; }
|
||||
|
||||
mork_bool IsFrozen() const { return mNode_Mutable == morkAble_kDisabled; }
|
||||
mork_bool IsMutable() const { return mNode_Mutable == morkAble_kEnabled; }
|
||||
mork_bool IsAsleep() const { return mNode_Mutable == morkAble_kAsleep; }
|
||||
|
||||
void SetClean() { mNode_Load = morkLoad_kClean; }
|
||||
void SetDirty() { mNode_Load = morkLoad_kDirty; }
|
||||
|
||||
mork_bool IsClean() const { return mNode_Load == morkLoad_kClean; }
|
||||
mork_bool IsDirty() const { return mNode_Load == morkLoad_kDirty; }
|
||||
|
||||
public: // morkNode memory management methods
|
||||
static void* MakeNew(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev);
|
||||
|
||||
static void OnDeleteAssert(void* ioAddress); // cannot operator delete()
|
||||
void ZapOld(morkEnv* ev, nsIMdbHeap* ioHeap); // replaces operator delete()
|
||||
// this->morkNode::~morkNode(); // first call polymorphic destructor
|
||||
// if ( ioHeap ) // was this node heap allocated?
|
||||
// ioHeap->Free(ev->AsMdbEnv(), this);
|
||||
|
||||
public: // morkNode memory management operators
|
||||
void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev)
|
||||
{ return morkNode::MakeNew(inSize, ioHeap, ev); }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
// do NOT call delete on morkNode instances. Call ZapOld() instead.
|
||||
|
||||
protected: // construction without an anv needed for first env constructed:
|
||||
morkNode(const morkUsage& inUsage, nsIMdbHeap* ioHeap);
|
||||
|
||||
// { ===== begin basic node interface =====
|
||||
public: // morkNode virtual methods
|
||||
// virtual FlushMorkNode(morkEnv* ev, morkStream* ioStream);
|
||||
// virtual WriteMorkNode(morkEnv* ev, morkStream* ioStream);
|
||||
|
||||
virtual ~morkNode(); // assert that CloseNode() executed earlier
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseNode() only if open
|
||||
|
||||
// CloseMorkNode() is the polymorphic close method called when uses==0,
|
||||
// which must do NOTHING at all when IsOpenNode() is not true. Otherwise,
|
||||
// CloseMorkNode() should call a static close method specific to an object.
|
||||
// Each such static close method should either call inherited static close
|
||||
// methods, or else perform the consolidated effect of calling them, where
|
||||
// subclasses should closely track any changes in base classes with care.
|
||||
|
||||
public: // morkNode construction
|
||||
morkNode(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap);
|
||||
void CloseNode(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkNode(const morkNode& other);
|
||||
morkNode& operator=(const morkNode& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsNode() const
|
||||
{ return mNode_Base == morkBase_kNode; }
|
||||
// } ===== end basic node methods =====
|
||||
|
||||
public: // public error & warning methods
|
||||
|
||||
void RefsUnderUsesWarning(morkEnv* ev) const; // call if mNode_Refs < mNode_Uses
|
||||
void NonNodeError(morkEnv* ev) const; // call when IsNode() is false
|
||||
void NilHeapError(morkEnv* ev) const; // zero mNode_Heap when usage is kHeap
|
||||
void NonOpenNodeError(morkEnv* ev) const; // call when IsOpenNode() is false
|
||||
|
||||
void NonMutableNodeError(morkEnv* ev) const; // when IsMutable() is false
|
||||
|
||||
void RefsOverflowWarning(morkEnv* ev) const; // call on mNode_Refs overflow
|
||||
void UsesOverflowWarning(morkEnv* ev) const; // call on mNode_Uses overflow
|
||||
void RefsUnderflowWarning(morkEnv* ev) const; // call on mNode_Refs underflow
|
||||
void UsesUnderflowWarning(morkEnv* ev) const; // call on mNode_Uses underflow
|
||||
|
||||
private: // private refcounting methods
|
||||
mork_bool cut_use_count(morkEnv* ev); // just one part of CutStrongRef()
|
||||
|
||||
public: // other morkNode methods
|
||||
|
||||
mork_bool GoodRefs() const { return mNode_Refs >= mNode_Uses; }
|
||||
mork_bool BadRefs() const { return mNode_Refs < mNode_Uses; }
|
||||
|
||||
mork_uses StrongRefsOnly() const { return mNode_Uses; }
|
||||
mork_refs WeakRefsOnly() const { return ( mNode_Refs - mNode_Uses ); }
|
||||
|
||||
// (this refcounting derives from public domain IronDoc node refcounts)
|
||||
mork_refs AddStrongRef(morkEnv* ev);
|
||||
mork_refs CutStrongRef(morkEnv* ev);
|
||||
mork_refs AddWeakRef(morkEnv* ev);
|
||||
mork_refs CutWeakRef(morkEnv* ev);
|
||||
|
||||
const char* GetNodeAccessAsString() const; // e.g. "open", "shut", etc.
|
||||
const char* GetNodeUsageAsString() const; // e.g. "heap", "stack", etc.
|
||||
|
||||
mork_usage NodeUsage() const { return mNode_Usage; }
|
||||
|
||||
mork_bool IsHeapNode() const
|
||||
{ return mNode_Usage == morkUsage_kHeap; }
|
||||
|
||||
mork_bool IsStackNode() const
|
||||
{ return mNode_Usage == morkUsage_kStack; }
|
||||
|
||||
mork_bool IsGlobalNode() const
|
||||
{ return mNode_Usage == morkUsage_kGlobal; }
|
||||
|
||||
mork_bool IsMemberNode() const
|
||||
{ return mNode_Usage == morkUsage_kMember; }
|
||||
|
||||
mork_bool IsOpenNode() const
|
||||
{ return mNode_Access == morkAccess_kOpen; }
|
||||
|
||||
mork_bool IsShutNode() const
|
||||
{ return mNode_Access == morkAccess_kShut; }
|
||||
|
||||
mork_bool IsDeadNode() const
|
||||
{ return mNode_Access == morkAccess_kDead; }
|
||||
|
||||
mork_bool IsClosingNode() const
|
||||
{ return mNode_Access == morkAccess_kClosing; }
|
||||
|
||||
mork_bool IsOpenOrClosingNode() const
|
||||
{ return IsOpenNode() || IsClosingNode(); }
|
||||
|
||||
mork_bool HasNodeAccess() const
|
||||
{ return ( IsOpenNode() || IsShutNode() || IsClosingNode() ); }
|
||||
|
||||
void MarkShut() { mNode_Access = morkAccess_kShut; }
|
||||
void MarkClosing() { mNode_Access = morkAccess_kClosing; }
|
||||
void MarkDead() { mNode_Access = morkAccess_kDead; }
|
||||
|
||||
public: // refcounting for typesafe subclass inline methods
|
||||
static void SlotWeakNode(morkNode* me, morkEnv* ev, morkNode** ioSlot);
|
||||
// If *ioSlot is non-nil, that node is released by CutWeakRef() and
|
||||
// then zeroed out. Then if me is non-nil, this is acquired by
|
||||
// calling AddWeakRef(), and if positive is returned to show success,
|
||||
// then this is put into slot *ioSlot. Note me can be nil, so we
|
||||
// permit expression '((morkNode*) 0L)->SlotWeakNode(ev, &slot)'.
|
||||
|
||||
static void SlotStrongNode(morkNode* me, morkEnv* ev, morkNode** ioSlot);
|
||||
// If *ioSlot is non-nil, that node is released by CutStrongRef() and
|
||||
// then zeroed out. Then if me is non-nil, this is acquired by
|
||||
// calling AddStrongRef(), and if positive is returned to show success,
|
||||
// then me is put into slot *ioSlot. Note me can be nil, so we take
|
||||
// expression 'morkNode::SlotStrongNode((morkNode*) 0, ev, &slot)'.
|
||||
};
|
||||
|
||||
extern void // utility method very similar to morkNode::SlotStrongNode():
|
||||
nsIMdbHeap_SlotStrongHeap(nsIMdbHeap* self, morkEnv* ev, nsIMdbHeap** ioSlot);
|
||||
// If *ioSlot is non-nil, that heap is released by CutStrongRef() and
|
||||
// then zeroed out. Then if me is non-nil, this is acquired by
|
||||
// calling AddStrongRef(), and if the return value shows success,
|
||||
// then me is put into slot *ioSlot. Note me can be nil, so we take
|
||||
// expression 'nsIMdbHeap_SlotStrongNode(0, ev, &slot)'.
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKNODE_ */
|
||||
173
mozilla/db/mork/src/morkNodeMap.cpp
Normal file
173
mozilla/db/mork/src/morkNodeMap.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#include "morkIntMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#include "morkNodeMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkNodeMap::CloseMorkNode(morkEnv* ev) // CloseNodeMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseNodeMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkNodeMap::~morkNodeMap() // assert CloseNodeMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkNodeMap::morkNodeMap(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkIntMap(ev, inUsage, /*valsize*/ sizeof(morkNode*), ioHeap, ioSlotHeap,
|
||||
/*inHoldChanges*/ morkBool_kTrue)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kNodeMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkNodeMap::CloseNodeMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CutAllNodes(ev);
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
mork_bool
|
||||
morkNodeMap::AddNode(morkEnv* ev, mork_token inToken, morkNode* ioNode)
|
||||
// the AddNode() method return value equals ev->Good().
|
||||
{
|
||||
if ( ioNode && ev->Good() )
|
||||
{
|
||||
morkNode* node = 0; // old val in the map
|
||||
|
||||
mork_bool put = this->Put(ev, &inToken, &ioNode,
|
||||
/*key*/ (void*) 0, &node, (mork_change**) 0);
|
||||
|
||||
if ( put ) // replaced an existing value for key inToken?
|
||||
{
|
||||
if ( node && node != ioNode ) // need to release old node?
|
||||
node->CutStrongRef(ev);
|
||||
}
|
||||
|
||||
if ( ev->Bad() || !ioNode->AddStrongRef(ev) )
|
||||
{
|
||||
// problems adding node or increasing refcount?
|
||||
this->Cut(ev, &inToken, // make sure not in map
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
}
|
||||
else if ( !ioNode )
|
||||
ev->NilPointerError();
|
||||
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkNodeMap::CutNode(morkEnv* ev, mork_token inToken)
|
||||
{
|
||||
morkNode* node = 0; // old val in the map
|
||||
mork_bool outCutNode = this->Cut(ev, &inToken,
|
||||
/*key*/ (void*) 0, &node, (mork_change**) 0);
|
||||
if ( node )
|
||||
node->CutStrongRef(ev);
|
||||
|
||||
return outCutNode;
|
||||
}
|
||||
|
||||
morkNode*
|
||||
morkNodeMap::GetNode(morkEnv* ev, mork_token inToken)
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
{
|
||||
morkNode* node = 0; // old val in the map
|
||||
this->Get(ev, &inToken, /*key*/ (void*) 0, &node, (mork_change**) 0);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
mork_num
|
||||
morkNodeMap::CutAllNodes(morkEnv* ev)
|
||||
// CutAllNodes() releases all the reference node values.
|
||||
{
|
||||
mork_num outSlots = mMap_Slots;
|
||||
mork_token key = 0; // old key token in the map
|
||||
morkNode* val = 0; // old val node in the map
|
||||
|
||||
mork_change* c = 0;
|
||||
morkNodeMapIter i(ev, this);
|
||||
for ( c = i.FirstNode(ev, &key, &val); c ; c = i.NextNode(ev, &key, &val) )
|
||||
{
|
||||
if ( val )
|
||||
val->CutStrongRef(ev);
|
||||
i.CutHereNode(ev, /*key*/ (mork_token*) 0, /*val*/ (morkNode**) 0);
|
||||
}
|
||||
|
||||
return outSlots;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
111
mozilla/db/mork/src/morkNodeMap.h
Normal file
111
mozilla/db/mork/src/morkNodeMap.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#define _MORKNODEMAP_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKINTMAP_
|
||||
#include "morkIntMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kNodeMap /*i*/ 0x6E4D /* ascii 'nM' */
|
||||
|
||||
#define morkNodeMap_kStartSlotCount 512
|
||||
|
||||
/*| morkNodeMap: maps mork_token -> morkNode
|
||||
|*/
|
||||
class morkNodeMap : public morkIntMap { // for mapping tokens to nodes
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseNodeMap() only if open
|
||||
virtual ~morkNodeMap(); // assert that CloseNodeMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkNodeMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseNodeMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsNodeMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kNodeMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
// use the Equal() and Hash() for mork_u4 inherited from morkIntMap
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
protected: // we want all subclasses to provide typesafe wrappers:
|
||||
|
||||
mork_bool AddNode(morkEnv* ev, mork_token inToken, morkNode* ioNode);
|
||||
// the AddNode() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutNode(morkEnv* ev, mork_token inToken);
|
||||
// The CutNode() boolean return indicates whether removal happened.
|
||||
|
||||
morkNode* GetNode(morkEnv* ev, mork_token inToken);
|
||||
// Note the returned node does NOT have an increase in refcount for this.
|
||||
|
||||
mork_num CutAllNodes(morkEnv* ev);
|
||||
// CutAllNodes() releases all the reference node values.
|
||||
};
|
||||
|
||||
class morkNodeMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkNodeMapIter(morkEnv* ev, morkNodeMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkNodeMapIter( ) : morkMapIter() { }
|
||||
void InitNodeMapIter(morkEnv* ev, morkNodeMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change*
|
||||
FirstNode(morkEnv* ev, mork_token* outToken, morkNode** outNode)
|
||||
{ return this->First(ev, outToken, outNode); }
|
||||
|
||||
mork_change*
|
||||
NextNode(morkEnv* ev, mork_token* outToken, morkNode** outNode)
|
||||
{ return this->Next(ev, outToken, outNode); }
|
||||
|
||||
mork_change*
|
||||
HereNode(morkEnv* ev, mork_token* outToken, morkNode** outNode)
|
||||
{ return this->Here(ev, outToken, outNode); }
|
||||
|
||||
mork_change*
|
||||
CutHereNode(morkEnv* ev, mork_token* outToken, morkNode** outNode)
|
||||
{ return this->CutHere(ev, outToken, outNode); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKNODEMAP_ */
|
||||
119
mozilla/db/mork/src/morkObject.cpp
Normal file
119
mozilla/db/mork/src/morkObject.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkObject::CloseMorkNode(morkEnv* ev) // CloseObject() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkObject::~morkObject() // assert CloseObject() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mObject_Handle==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkObject::morkObject(const morkUsage& inUsage, nsIMdbHeap* ioHeap)
|
||||
: morkNode(inUsage, ioHeap)
|
||||
, mObject_Handle( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkObject::morkObject(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap, morkHandle* ioHandle)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mObject_Handle( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioHandle )
|
||||
morkHandle::SlotWeakHandle(ioHandle, ev, &mObject_Handle);
|
||||
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kObject;
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkObject::CloseObject(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( !this->IsShutNode() )
|
||||
{
|
||||
if ( mObject_Handle )
|
||||
morkHandle::SlotWeakHandle((morkHandle*) 0L, ev, &mObject_Handle);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
|
||||
//void morkObject::NewNilHandleError(morkEnv* ev) // mObject_Handle is nil
|
||||
//{
|
||||
// ev->NewError("nil mObject_Handle");
|
||||
//}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
94
mozilla/db/mork/src/morkObject.h
Normal file
94
mozilla/db/mork/src/morkObject.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#define _MORKOBJECT_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kObject /*i*/ 0x6F42 /* ascii 'oB' */
|
||||
|
||||
/*| morkObject: subclass of morkNode that adds knowledge of db suite factory
|
||||
**| and containing port to those objects that are exposed as instances of
|
||||
**| nsIMdbObject in the public interface.
|
||||
|*/
|
||||
class morkObject : public morkNode {
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkHandle* mObject_Handle; // weak ref to handle for this object
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseObject() only if open
|
||||
virtual ~morkObject(); // assert that CloseObject() executed earlier
|
||||
|
||||
protected: // special case construction of first env without preceding env
|
||||
morkObject(const morkUsage& inUsage, nsIMdbHeap* ioHeap);
|
||||
|
||||
public: // morkEnv construction & destruction
|
||||
morkObject(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkHandle* ioHandle); // ioHandle can be nil
|
||||
void CloseObject(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkObject(const morkObject& other);
|
||||
morkObject& operator=(const morkObject& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsObject() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kObject; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// void NewNilHandleError(morkEnv* ev); // mObject_Handle is nil
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakObject(morkObject* me,
|
||||
morkEnv* ev, morkObject** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongObject(morkObject* me,
|
||||
morkEnv* ev, morkObject** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKOBJECT_ */
|
||||
412
mozilla/db/mork/src/morkParser.cpp
Normal file
412
mozilla/db/mork/src/morkParser.cpp
Normal file
@@ -0,0 +1,412 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTREAM_
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#include "morkSink.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkParser::CloseMorkNode(morkEnv* ev) /*i*/ // CloseParser() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseParser(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkParser::~morkParser() /*i*/ // assert CloseParser() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mParser_Heap==0);
|
||||
MORK_ASSERT(mParser_Stream==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkParser::morkParser(morkEnv* ev, /*i*/
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStream* ioStream, mdb_count inBytesPerParseSegment,
|
||||
nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mParser_Heap( 0 )
|
||||
, mParser_Stream( 0 )
|
||||
, mParser_MoreGranularity( inBytesPerParseSegment )
|
||||
, mParser_State( morkParser_kStartState )
|
||||
|
||||
, mParser_GroupContentStartPos( 0 )
|
||||
|
||||
, mParser_TableId( 0 )
|
||||
, mParser_RowId( 0 )
|
||||
|
||||
, mParser_InPort( morkBool_kFalse )
|
||||
, mParser_InDict( morkBool_kFalse )
|
||||
, mParser_InCell( morkBool_kFalse )
|
||||
, mParser_InMeta( morkBool_kFalse )
|
||||
|
||||
, mParser_InPortRow( morkBool_kFalse )
|
||||
, mParser_IsBroken( morkBool_kFalse )
|
||||
, mParser_IsDone( morkBool_kFalse )
|
||||
|
||||
, mParser_Alias()
|
||||
|
||||
, mParser_ScopeSpool(ev, ioHeap)
|
||||
, mParser_ValueSpool(ev, ioHeap)
|
||||
, mParser_ColumnSpool(ev, ioHeap)
|
||||
, mParser_StringSpool(ev, ioHeap)
|
||||
|
||||
, mParser_ScopeSink(ev, &mParser_ScopeSpool)
|
||||
, mParser_ValueSink(ev, &mParser_ValueSpool)
|
||||
, mParser_ColumnSink(ev, &mParser_ColumnSpool)
|
||||
, mParser_StringSink(ev, &mParser_StringSpool)
|
||||
|
||||
, mParser_AliasYarn(ev, morkUsage_kMember, ioHeap)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
|
||||
if ( inBytesPerParseSegment < morkParser_kMinGranularity )
|
||||
inBytesPerParseSegment = morkParser_kMinGranularity;
|
||||
else if ( inBytesPerParseSegment > morkParser_kMaxGranularity )
|
||||
inBytesPerParseSegment = morkParser_kMaxGranularity;
|
||||
|
||||
mParser_MoreGranularity = inBytesPerParseSegment;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mParser_Tag = morkParser_kTag;
|
||||
mNode_Derived = morkDerived_kParser;
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkParser::CloseParser(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( !this->IsShutNode() )
|
||||
{
|
||||
mParser_ScopeSpool.CloseSpool(ev);
|
||||
mParser_ValueSpool.CloseSpool(ev);
|
||||
mParser_ColumnSpool.CloseSpool(ev);
|
||||
mParser_StringSpool.CloseSpool(ev);
|
||||
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mParser_Heap);
|
||||
morkStream::SlotStrongStream((morkStream*) 0, ev, &mParser_Stream);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkParser::SetParserStream(morkEnv* ev, morkStream* ioStream)
|
||||
{
|
||||
morkStream* stream = mParser_Stream;
|
||||
if ( stream )
|
||||
{
|
||||
mParser_Stream = 0;
|
||||
stream->CutStrongRef(ev);
|
||||
}
|
||||
if ( ioStream && ioStream->AddStrongRef(ev) )
|
||||
mParser_Stream = ioStream;
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkParser::NonGoodParserError(morkEnv* ev) // when GoodParserTag() is false
|
||||
{
|
||||
ev->NewError("non-morkNode");
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkParser::NonUsableParserError(morkEnv* ev) //
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
if ( this->GoodParserTag() )
|
||||
{
|
||||
// okay
|
||||
}
|
||||
else
|
||||
this->NonGoodParserError(ev);
|
||||
}
|
||||
else
|
||||
this->NonOpenNodeError(ev);
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkParser::StartParse(morkEnv* ev)
|
||||
{
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkParser::StopParse(morkEnv* ev)
|
||||
{
|
||||
if ( mParser_InCell )
|
||||
{
|
||||
mParser_InCell = morkBool_kFalse;
|
||||
mParser_CellSpan.SetEndWithEnd(mParser_PortSpan);
|
||||
this->OnCellEnd(ev, mParser_CellSpan);
|
||||
}
|
||||
if ( mParser_InMeta )
|
||||
{
|
||||
mParser_InMeta = morkBool_kFalse;
|
||||
mParser_MetaSpan.SetEndWithEnd(mParser_PortSpan);
|
||||
this->OnMetaEnd(ev, mParser_MetaSpan);
|
||||
}
|
||||
if ( mParser_InPortRow )
|
||||
{
|
||||
mParser_InPortRow = morkBool_kFalse;
|
||||
mParser_RowSpan.SetEndWithEnd(mParser_PortSpan);
|
||||
this->OnPortRowEnd(ev, mParser_RowSpan);
|
||||
}
|
||||
if ( mParser_RowId )
|
||||
{
|
||||
mParser_RowId = 0;
|
||||
mParser_RowSpan.SetEndWithEnd(mParser_PortSpan);
|
||||
this->OnRowEnd(ev, mParser_RowSpan);
|
||||
}
|
||||
if ( mParser_TableId )
|
||||
{
|
||||
mParser_TableId = 0;
|
||||
mParser_TableSpan.SetEndWithEnd(mParser_PortSpan);
|
||||
this->OnTableEnd(ev, mParser_TableSpan);
|
||||
}
|
||||
if ( mParser_GroupId )
|
||||
{
|
||||
mParser_GroupId = 0;
|
||||
mParser_GroupSpan.SetEndWithEnd(mParser_PortSpan);
|
||||
this->OnGroupAbortEnd(ev, mParser_GroupSpan);
|
||||
}
|
||||
if ( mParser_InPort )
|
||||
{
|
||||
mParser_InPort = morkBool_kFalse;
|
||||
this->OnPortEnd(ev, mParser_PortSpan);
|
||||
}
|
||||
}
|
||||
|
||||
///*protected non-poly*/ int
|
||||
//morkParser::NextChar(morkEnv* ev)
|
||||
//{
|
||||
//}
|
||||
|
||||
/*protected non-poly*/ int
|
||||
morkParser::NextChar(morkEnv* ev) // next non-white content
|
||||
{
|
||||
register int c; // the most heavily used character variable
|
||||
int outChar = -1; // the byte to return from this method
|
||||
int d; // the byte after c on some occasions
|
||||
morkStream* s = mParser_Stream;
|
||||
if ( s )
|
||||
{
|
||||
while ( outChar == -1 && ev->Good() )
|
||||
{
|
||||
while ( (c = s->Getc(ev)) != EOF && ev->Good() )
|
||||
{
|
||||
if ( c == 0xA || c == 0xD ) // end of line?
|
||||
{
|
||||
this->AddLine();
|
||||
d = s->Getc(ev); // look for another byte in #xA #xD, or #xD #xA
|
||||
if (( d == 0xA || d == 0xD ) && c != d ) // eat this one too?
|
||||
{
|
||||
}
|
||||
else if ( d != EOF ) // not trying to push back end of file
|
||||
s->Ungetc(d);
|
||||
}
|
||||
}
|
||||
|
||||
if ( c == '/' ) // maybe start of comment?
|
||||
{
|
||||
int depth = 0;
|
||||
}
|
||||
else if ( c == '\\' ) // maybe start of line continuation?
|
||||
{
|
||||
if ( (c = s->Getc(ev)) == 0xA || c == 0xD )
|
||||
;
|
||||
}
|
||||
|
||||
if ( c == EOF ) // reached end of file?
|
||||
{
|
||||
if ( outChar == -1 )
|
||||
outChar = 1; // end while loop
|
||||
mParser_DoMore = morkBool_kFalse;
|
||||
mParser_IsDone = morkBool_kTrue;
|
||||
}
|
||||
}
|
||||
|
||||
this->SetHerePos(s->Tell(ev));
|
||||
}
|
||||
else // nil stream pointer
|
||||
{
|
||||
ev->NilPointerError();
|
||||
mParser_State = morkParser_kBrokenState;
|
||||
mParser_DoMore = morkBool_kFalse;
|
||||
mParser_IsDone = morkBool_kTrue;
|
||||
mParser_IsBroken = morkBool_kTrue;
|
||||
}
|
||||
return outChar;
|
||||
}
|
||||
|
||||
/*protected non-poly*/ void
|
||||
morkParser::ParseLoop(morkEnv* ev)
|
||||
{
|
||||
mParser_Change = morkChange_kNil;
|
||||
mParser_DoMore = morkBool_kTrue;
|
||||
|
||||
while ( mParser_DoMore )
|
||||
{
|
||||
switch ( mParser_State )
|
||||
{
|
||||
case morkParser_kCellState: // 0
|
||||
break;
|
||||
case morkParser_kMetaState: // 1
|
||||
break;
|
||||
case morkParser_kRowState: // 2
|
||||
break;
|
||||
case morkParser_kTableState: // 3
|
||||
break;
|
||||
case morkParser_kDictState: // 4
|
||||
break;
|
||||
case morkParser_kPortState: // 5
|
||||
break;
|
||||
|
||||
case morkParser_kStartState: // 6
|
||||
{
|
||||
morkStream* s = mParser_Stream;
|
||||
if ( s && s->IsNode() && s->IsOpenNode() )
|
||||
{
|
||||
this->StartParse(ev);
|
||||
mParser_State = morkParser_kPortState;
|
||||
}
|
||||
else
|
||||
{
|
||||
mParser_State = morkParser_kBrokenState;
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case morkParser_kDoneState: // 7
|
||||
mParser_DoMore = morkBool_kFalse;
|
||||
mParser_IsDone = morkBool_kTrue;
|
||||
this->StopParse(ev);
|
||||
break;
|
||||
case morkParser_kBrokenState: // 8
|
||||
mParser_DoMore = morkBool_kFalse;
|
||||
mParser_IsBroken = morkBool_kTrue;
|
||||
this->StopParse(ev);
|
||||
break;
|
||||
default: // ?
|
||||
MORK_ASSERT(morkBool_kFalse);
|
||||
mParser_State = morkParser_kBrokenState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ mdb_count
|
||||
morkParser::ParseMore( // return count of bytes consumed now
|
||||
morkEnv* ev, // context
|
||||
mork_pos* outPos, // current byte pos in the stream afterwards
|
||||
mork_bool* outDone, // is parsing finished?
|
||||
mork_bool* outBroken // is parsing irreparably dead and broken?
|
||||
)
|
||||
{
|
||||
mdb_count outCount = 0;
|
||||
if ( this->IsNode() && this->GoodParserTag() && this->IsOpenNode() )
|
||||
{
|
||||
mork_pos startPos = this->HerePos();
|
||||
|
||||
if ( !mParser_IsDone && !mParser_IsBroken )
|
||||
this->ParseLoop(ev);
|
||||
|
||||
mork_pos endPos = this->HerePos();
|
||||
if ( outDone )
|
||||
*outDone = mParser_IsDone;
|
||||
if ( outBroken )
|
||||
*outBroken = mParser_IsBroken;
|
||||
if ( outPos )
|
||||
*outPos = endPos;
|
||||
|
||||
if ( endPos > startPos )
|
||||
outCount = endPos - startPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->NonUsableParserError(ev);
|
||||
if ( outDone )
|
||||
*outDone = morkBool_kTrue;
|
||||
if ( outBroken )
|
||||
*outBroken = morkBool_kTrue;
|
||||
if ( outPos )
|
||||
*outPos = 0;
|
||||
}
|
||||
return outCount;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
450
mozilla/db/mork/src/morkParser.h
Normal file
450
mozilla/db/mork/src/morkParser.h
Normal file
@@ -0,0 +1,450 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#define _MORKPARSER_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPARSER_
|
||||
#include "morkParser.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#include "morkSink.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKYARN_
|
||||
#include "morkYarn.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*=============================================================================
|
||||
* morkPlace: stream byte position and stream line count
|
||||
*/
|
||||
|
||||
class morkPlace {
|
||||
public:
|
||||
mork_pos mPlace_Pos; // byte offset in an input stream
|
||||
mork_line mPlace_Line; // line count in an input stream
|
||||
|
||||
void ClearPlace()
|
||||
{
|
||||
mPlace_Pos = 0; mPlace_Line = 0;
|
||||
}
|
||||
|
||||
void SetPlace(mork_pos inPos, mork_line inLine)
|
||||
{
|
||||
mPlace_Pos = inPos; mPlace_Line = inLine;
|
||||
}
|
||||
|
||||
morkPlace() { mPlace_Pos = 0; mPlace_Line = 0; }
|
||||
|
||||
morkPlace(mork_pos inPos, mork_line inLine)
|
||||
{ mPlace_Pos = inPos; mPlace_Line = inLine; }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkGlitch: stream place and error comment describing a parsing error
|
||||
*/
|
||||
|
||||
class morkGlitch {
|
||||
public:
|
||||
morkPlace mGlitch_Place; // place in stream where problem happened
|
||||
const char* mGlitch_Comment; // null-terminated ASCII C string
|
||||
|
||||
morkGlitch() { mGlitch_Comment = 0; }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkAlias: all possible ways needed to express an alias ID in Mork syntax
|
||||
*/
|
||||
|
||||
/*| morkAlias: an abstraction of all the variations we might need to support
|
||||
**| in order to present an ID through the parser interface most cheaply and
|
||||
**| with minimum transformation away from the original text format.
|
||||
**|
|
||||
**|| An ID can have one of four forms:
|
||||
**| 1) idHex (mAlias_Oid.mOid_Id <- idHex)
|
||||
**| 2) idHex:^scopeHex (mAlias_Oid.mOid_Id <- idHex, mOid_Scope <- scopeHex)
|
||||
**| 3) idHex:scopeName (mAlias_Oid.mOid_Id <- idHex, mAlias_Buf <- scopeName)
|
||||
**| 4) columnName (mAlias_Buf <- columnName, for columns in cells only)
|
||||
**|
|
||||
**|| Typically, mAlias_Oid.mOid_Id will hold a nonzero integer value for
|
||||
**| an ID, but we might have an optional scope specified by either an integer
|
||||
**| in hex format, or a string name. (Note that while the first ID can be
|
||||
**| scoped variably, any integer ID for a scope is assumed always located in
|
||||
**| the same scope, so the second ID need not be disambiguated.)
|
||||
**|
|
||||
**|| The only time mAlias_Oid.mOid_Id is ever zero is when mAlias_Buf alone
|
||||
**| is nonzero, to indicate an explicit string instead of an alias appeared.
|
||||
**| This case happens to make the representation of columns in cells somewhat
|
||||
**| easier to represent, since columns can just appear as a string name; and
|
||||
**| this unifies those interfaces with row and table APIs expecting IDs.
|
||||
**|
|
||||
**|| So when the parser passes an instance of morkAlias to a subclass, the
|
||||
**| mAlias_Oid.mOid_Id slot should usually be nonzero. And the other two
|
||||
**| slots, mAlias_Oid.mOid_Scope and mAlias_Buf, might both be zero, or at
|
||||
**| most one of them will be nonzero to indicate an explicit scope; the
|
||||
**| parser is responsible for ensuring at most one of these is nonzero.
|
||||
|*/
|
||||
class morkAlias {
|
||||
public:
|
||||
mdbOid mAlias_Oid; // mOid_Scope is zero when not specified
|
||||
const morkBuf* mAlias_Buf; // points to some specific buf subclass
|
||||
|
||||
morkAlias()
|
||||
{ mAlias_Oid.mOid_Scope = 0; mAlias_Oid.mOid_Id = morkId_kMinusOne;
|
||||
mAlias_Buf = 0; }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkSpan: start and end stream byte position and stream line count
|
||||
*/
|
||||
|
||||
class morkSpan {
|
||||
public:
|
||||
morkPlace mSpan_Start;
|
||||
morkPlace mSpan_End;
|
||||
|
||||
public: // methods
|
||||
|
||||
public: // inlines
|
||||
morkSpan() { } // use inline empty constructor for each place
|
||||
|
||||
void SetSpan(mork_pos inFromPos, mork_line inFromLine,
|
||||
mork_pos inToPos, mork_line inToLine)
|
||||
{
|
||||
mSpan_Start.SetPlace(inFromPos, inFromLine);
|
||||
mSpan_End.SetPlace(inToPos,inToLine);
|
||||
}
|
||||
|
||||
// setting end, useful to terminate a span using current port span end:
|
||||
void SetEndWithEnd(const morkSpan& inSpan) // end <- span.end
|
||||
{ mSpan_End = inSpan.mSpan_End; }
|
||||
|
||||
// setting start, useful to initiate a span using current port span end:
|
||||
void SetStartWithEnd(const morkSpan& inSpan) // start <- span.end
|
||||
{ mSpan_Start = inSpan.mSpan_End; }
|
||||
|
||||
void ClearSpan()
|
||||
{
|
||||
mSpan_Start.mPlace_Pos = 0; mSpan_Start.mPlace_Line = 0;
|
||||
mSpan_End.mPlace_Pos = 0; mSpan_End.mPlace_Line = 0;
|
||||
}
|
||||
|
||||
morkSpan(mork_pos inFromPos, mork_line inFromLine,
|
||||
mork_pos inToPos, mork_line inToLine)
|
||||
: mSpan_Start(inFromPos, inFromLine), mSpan_End(inToPos, inToLine)
|
||||
{ /* empty implementation */ }
|
||||
};
|
||||
|
||||
/*=============================================================================
|
||||
* morkParser: for parsing Mork text syntax
|
||||
*/
|
||||
|
||||
#define morkParser_kMinGranularity 512 /* parse at least half 0.5K at once */
|
||||
#define morkParser_kMaxGranularity (64 * 1024) /* parse at most 64 K at once */
|
||||
|
||||
#define morkDerived_kParser /*i*/ 0x5073 /* ascii 'Ps' */
|
||||
#define morkParser_kTag /*i*/ 0x70417253 /* ascii 'pArS' */
|
||||
|
||||
// These are states for the simple parsing virtual machine. Needless to say,
|
||||
// these must be distinct, and preferrably in a contiguous integer range.
|
||||
// Don't change these constants without looking at switch statements in code.
|
||||
#define morkParser_kCellState 0 /* cell is tightest scope */
|
||||
#define morkParser_kMetaState 1 /* meta is tightest scope */
|
||||
#define morkParser_kRowState 2 /* row is tightest scope */
|
||||
#define morkParser_kTableState 3 /* table is tightest scope */
|
||||
#define morkParser_kDictState 4 /* dict is tightest scope */
|
||||
#define morkParser_kPortState 5 /* port is tightest scope */
|
||||
|
||||
#define morkParser_kStartState 6 /* parsing has not yet begun */
|
||||
#define morkParser_kDoneState 7 /* parsing is complete */
|
||||
#define morkParser_kBrokenState 8 /* parsing is to broken to work */
|
||||
|
||||
class morkParser /*d*/ : public morkNode {
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected morkParser members
|
||||
|
||||
nsIMdbHeap* mParser_Heap; // refcounted heap used for allocation
|
||||
morkStream* mParser_Stream; // refcounted input stream
|
||||
|
||||
mork_u4 mParser_Tag; // must equal morkParser_kTag
|
||||
mork_count mParser_MoreGranularity; // constructor inBytesPerParseSegment
|
||||
|
||||
mork_u4 mParser_State; // state where parser should resume
|
||||
|
||||
// after finding ends of group transactions, we can re-seek the start:
|
||||
mork_pos mParser_GroupContentStartPos; // start of this group
|
||||
|
||||
mork_gid mParser_GroupId; // group ID if inside a group
|
||||
mork_tid mParser_TableId; // table ID if inside a table
|
||||
mork_rid mParser_RowId; // row ID if inside a row
|
||||
|
||||
mork_bool mParser_InPort; // called OnNewPort but not OnPortEnd?
|
||||
mork_bool mParser_InDict; // called OnNewDict but not OnDictEnd?
|
||||
mork_bool mParser_InCell; // called OnNewCell but not OnCellEnd?
|
||||
mork_bool mParser_InMeta; // called OnNewMeta but not OnMetaEnd?
|
||||
|
||||
mork_bool mParser_InPortRow; // called OnNewPortRow but not OnPortRowEnd?
|
||||
mork_bool mParser_IsBroken; // has the parse become broken?
|
||||
mork_bool mParser_IsDone; // has the parse finished?
|
||||
mork_bool mParser_DoMore; // mParser_MoreGranularity not exhausted?
|
||||
|
||||
mork_change mParser_Change; // driven by modifier in text
|
||||
|
||||
morkAlias mParser_Alias; // current alias being parsed
|
||||
// note that mParser_Alias.mAlias_Buf points at mParser_ScopeSpool below:
|
||||
|
||||
// blob spools allocated in mParser_Heap
|
||||
morkSpool mParser_ScopeSpool; // place to accumulate ID scope blobs
|
||||
morkSpool mParser_ValueSpool; // place to accumulate value blobs
|
||||
morkSpool mParser_ColumnSpool; // place to accumulate column blobs
|
||||
morkSpool mParser_StringSpool; // place to accumulate string blobs
|
||||
|
||||
morkSpoolSink mParser_ScopeSink; // writes to mParser_ScopeSpool
|
||||
morkSpoolSink mParser_ValueSink; // writes to mParser_ValueSpool
|
||||
morkSpoolSink mParser_ColumnSink; // writes to mParser_ColumnSpool
|
||||
morkSpoolSink mParser_StringSink; // writes to mParser_StringSpool
|
||||
|
||||
// yarns allocated in mParser_Heap
|
||||
morkYarn mParser_AliasYarn; // place to receive from AliasToYarn()
|
||||
|
||||
// span showing current ongoing file position status:
|
||||
morkSpan mParser_PortSpan; // span of current db port file
|
||||
|
||||
// various spans denoting nested subspaces inside the file's port span:
|
||||
morkSpan mParser_GroupSpan; // span of current transaction group
|
||||
morkSpan mParser_DictSpan;
|
||||
morkSpan mParser_AliasSpan;
|
||||
morkSpan mParser_MetaSpan;
|
||||
morkSpan mParser_TableSpan;
|
||||
morkSpan mParser_RowSpan;
|
||||
morkSpan mParser_CellSpan;
|
||||
morkSpan mParser_ColumnSpan;
|
||||
morkSpan mParser_SlotSpan;
|
||||
|
||||
private: // convenience inlines
|
||||
|
||||
mork_pos HerePos() const
|
||||
{ return mParser_PortSpan.mSpan_End.mPlace_Pos; }
|
||||
|
||||
void SetHerePos(mork_pos inPos)
|
||||
{ mParser_PortSpan.mSpan_End.mPlace_Pos = inPos; }
|
||||
|
||||
void AddLine()
|
||||
{ ++ mParser_PortSpan.mSpan_End.mPlace_Line; }
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseParser() only if open
|
||||
virtual ~morkParser(); // assert that CloseParser() executed earlier
|
||||
|
||||
public: // morkYarn construction & destruction
|
||||
morkParser(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStream* ioStream, // the readonly stream for input bytes
|
||||
mdb_count inBytesPerParseSegment, // target for ParseMore()
|
||||
nsIMdbHeap* ioSlotHeap);
|
||||
|
||||
void CloseParser(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkParser(const morkParser& other);
|
||||
morkParser& operator=(const morkParser& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsParser() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kParser; }
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
void NonParserTypeError(morkEnv* ev);
|
||||
|
||||
public: // other type methods
|
||||
mork_bool GoodParserTag() const { return mParser_Tag == morkParser_kTag; }
|
||||
void NonGoodParserError(morkEnv* ev);
|
||||
void NonUsableParserError(morkEnv* ev);
|
||||
// call when IsNode() or GoodParserTag() is false
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // in virtual morkParser methods, data flow subclass to parser
|
||||
|
||||
virtual void AliasToYarn(morkEnv* ev,
|
||||
const morkAlias& inAlias, // typically an alias to concat with strings
|
||||
mdbYarn* outYarn) = 0;
|
||||
// The parser might ask that some aliases be turned into yarns, so they
|
||||
// can be concatenated into longer blobs under some circumstances. This
|
||||
// is an alternative to using a long and complex callback for many parts
|
||||
// for a single cell value.
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // out virtual morkParser methods, data flow parser to subclass
|
||||
|
||||
// The virtual methods below will be called in a pattern corresponding
|
||||
// to the following grammar isomorphic to the Mork grammar. There should
|
||||
// be no exceptions, so subclasses can rely on seeing an appropriate "end"
|
||||
// method whenever some "new" method has been seen earlier. In the event
|
||||
// that some error occurs that causes content to be flushed, or sudden early
|
||||
// termination of a larger containing entity, we will always call a more
|
||||
// enclosed "end" method before we call an "end" method with greater scope.
|
||||
|
||||
// Note the "mp" prefix stands for "Mork Parser":
|
||||
|
||||
// mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
|
||||
// mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
|
||||
// mp:Group ::= OnNewGroup mp:GroupItem* mp:GroupEnd
|
||||
// mp:GroupItem ::= mp:Content | OnGroupGlitch
|
||||
// mp:GroupEnd ::= OnGroupCommitEnd | OnGroupAbortEnd
|
||||
// mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
|
||||
// mp:PortRow ::= OnNewPortRow mp:RowItem* OnPortRowEnd
|
||||
// mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
|
||||
// mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
|
||||
// mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
|
||||
// mp:TableItem ::= mp:Row | mp:Meta | OnTableGlitch
|
||||
// mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
|
||||
// mp:MetaItem ::= mp:Cell | OnMetaGlitch
|
||||
// mp:Row ::= OnNewRow mp:RowItem* OnRowEnd
|
||||
// mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
|
||||
// mp:Cell ::= OnNewCell mp:CellItem? OnCellEnd
|
||||
// mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
|
||||
// mp:Slot ::= OnValue | OnValueAlias | OnRowAlias | OnTableAlias
|
||||
|
||||
|
||||
// Note that in interfaces below, mork_change parameters kAdd and kNil
|
||||
// both mean about the same thing by default. Only kCut is interesting,
|
||||
// because this usually means to remove members instead of adding them.
|
||||
|
||||
virtual void OnNewPort(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnPortGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid) = 0;
|
||||
virtual void OnGroupGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnGroupCommitEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
virtual void OnGroupAbortEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewPortRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnPortRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnPortRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewTable(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnTableGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnTableEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewMeta(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnMetaGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnMetaEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewRow(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnRowGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnRowEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnNewDict(morkEnv* ev, const morkPlace& inPlace) = 0;
|
||||
virtual void OnDictGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnDictEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnAliasGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
|
||||
virtual void OnNewCell(morkEnv* ev, const morkPlace& inPlace,
|
||||
const morkAlias& inAlias, mork_change inChange) = 0;
|
||||
virtual void OnCellGlitch(morkEnv* ev, const morkGlitch& inGlitch) = 0;
|
||||
virtual void OnCellForm(morkEnv* ev, mork_cscode inCharsetFormat) = 0;
|
||||
virtual void OnCellEnd(morkEnv* ev, const morkSpan& inSpan) = 0;
|
||||
|
||||
virtual void OnValue(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkBuf& inBuf) = 0;
|
||||
|
||||
virtual void OnValueAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnRowAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
virtual void OnTableAlias(morkEnv* ev, const morkSpan& inSpan,
|
||||
const morkAlias& inAlias) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected parser helper methods
|
||||
|
||||
void ParseLoop(morkEnv* ev); // find parse continuation and resume
|
||||
|
||||
void StartParse(morkEnv* ev); // prepare for parsing
|
||||
void StopParse(morkEnv* ev); // terminate parsing & call needed methods
|
||||
|
||||
int NextChar(morkEnv* ev); // next non-white content
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkParser methods
|
||||
|
||||
void SetParserStream(morkEnv* ev, morkStream* ioStream);
|
||||
|
||||
mdb_count ParseMore( // return count of bytes consumed now
|
||||
morkEnv* ev, // context
|
||||
mork_pos* outPos, // current byte pos in the stream afterwards
|
||||
mork_bool* outDone, // is parsing finished?
|
||||
mork_bool* outBroken // is parsing irreparably dead and broken?
|
||||
);
|
||||
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakParser(morkParser* me,
|
||||
morkEnv* ev, morkParser** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongParser(morkParser* me,
|
||||
morkEnv* ev, morkParser** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKPARSER_ */
|
||||
366
mozilla/db/mork/src/morkPool.cpp
Normal file
366
mozilla/db/mork/src/morkPool.cpp
Normal file
@@ -0,0 +1,366 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKDEQUE_
|
||||
#include "morkDeque.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkPool::CloseMorkNode(morkEnv* ev) // ClosePool() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->ClosePool(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkPool::~morkPool() // assert ClosePool() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPool::morkPool(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(inUsage, ioHeap)
|
||||
, mPool_Heap( ioSlotHeap )
|
||||
{
|
||||
// mPool_Heap is NOT refcounted
|
||||
MORK_ASSERT(ioSlotHeap);
|
||||
if ( ioSlotHeap )
|
||||
mNode_Derived = morkDerived_kPool;
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPool::morkPool(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mPool_Heap( ioSlotHeap )
|
||||
{
|
||||
if ( ioSlotHeap )
|
||||
{
|
||||
// mPool_Heap is NOT refcounted:
|
||||
// nsIMdbHeap_SlotStrongHeap(ioSlotHeap, ev, &mPool_Heap);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kPool;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkPool::ClosePool(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
// mPool_Heap is NOT refcounted:
|
||||
// nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mPool_Heap);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
|
||||
// alloc and free individual instances of handles (inside hand frames):
|
||||
morkHandleFace*
|
||||
morkPool::NewHandle(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
void* newBlock = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), inSize, (void**) &newBlock);
|
||||
return (morkHandleFace*) newBlock;
|
||||
}
|
||||
|
||||
void
|
||||
morkPool::ZapHandle(morkEnv* ev, morkHandleFace* ioHandle)
|
||||
{
|
||||
if ( ioHandle )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioHandle);
|
||||
}
|
||||
|
||||
// alloc and free individual instances of rows:
|
||||
morkRow*
|
||||
morkPool::NewRow(morkEnv* ev) // allocate a new row instance
|
||||
{
|
||||
morkRow* newRow = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkRow), (void**) &newRow);
|
||||
if ( newRow )
|
||||
MORK_MEMSET(newRow, 0, sizeof(morkRow));
|
||||
|
||||
if ( newRow )
|
||||
{
|
||||
}
|
||||
return newRow;
|
||||
}
|
||||
|
||||
void
|
||||
morkPool::ZapRow(morkEnv* ev, morkRow* ioRow) // free old row instance
|
||||
{
|
||||
if ( ioRow )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioRow);
|
||||
}
|
||||
|
||||
// alloc and free entire vectors of cells (not just one cell at a time)
|
||||
morkCell*
|
||||
morkPool::NewCells(morkEnv* ev, mork_size inSize)
|
||||
{
|
||||
morkCell* newCells = 0;
|
||||
mork_size size = inSize * sizeof(morkCell);
|
||||
if ( size )
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newCells);
|
||||
|
||||
// note morkAtom depends on having nil stored in all new mCell_Atom slots:
|
||||
if ( newCells )
|
||||
MORK_MEMSET(newCells, 0, size);
|
||||
return newCells;
|
||||
}
|
||||
|
||||
void
|
||||
morkPool::ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize)
|
||||
{
|
||||
if ( ioVector )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioVector);
|
||||
}
|
||||
|
||||
// resize (grow or trim) cell vectors inside a containing row instance
|
||||
mork_bool
|
||||
morkPool::AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize)
|
||||
{
|
||||
// note strong implementation similarity to morkArray::Grow()
|
||||
|
||||
mork_fill fill = ioRow->mRow_Length;
|
||||
if ( ev->Good() && fill < inNewSize ) // need more cells?
|
||||
{
|
||||
morkCell* newCells = this->NewCells(ev, inNewSize);
|
||||
if ( newCells )
|
||||
{
|
||||
morkCell* c = newCells; // for iterating during copy
|
||||
morkCell* oldCells = ioRow->mRow_Cells;
|
||||
morkCell* end = oldCells + fill; // copy all the old cells
|
||||
while ( oldCells < end )
|
||||
{
|
||||
*c++ = *oldCells++; // bitwise copy each old cell struct
|
||||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length >= inNewSize );
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkPool::CutRowCells(morkEnv* ev, morkRow* ioRow,
|
||||
mork_size inNewSize)
|
||||
{
|
||||
mork_fill fill = ioRow->mRow_Length;
|
||||
if ( ev->Good() && fill > inNewSize ) // need fewer cells?
|
||||
{
|
||||
morkCell* newCells = this->NewCells(ev, inNewSize);
|
||||
if ( newCells )
|
||||
{
|
||||
morkCell* oldCells = ioRow->mRow_Cells;
|
||||
morkCell* oldEnd = oldCells + fill; // one past all old cells
|
||||
morkCell* newEnd = oldCells + inNewSize; // copy only kept old cells
|
||||
while ( oldCells < newEnd )
|
||||
{
|
||||
*newCells++ = *oldCells++; // bitwise copy each old cell struct
|
||||
}
|
||||
while ( oldCells < oldEnd )
|
||||
{
|
||||
if ( oldCells->mCell_Atom ) // need to unref old cell atom?
|
||||
oldCells->SetAtom(ev, (morkAtom*) 0, this); // unref cell atom
|
||||
++oldCells;
|
||||
}
|
||||
oldCells = ioRow->mRow_Cells;
|
||||
ioRow->mRow_Cells = newCells;
|
||||
ioRow->mRow_Length = inNewSize;
|
||||
++ioRow->mRow_Seed;
|
||||
|
||||
this->ZapCells(ev, oldCells, fill);
|
||||
}
|
||||
}
|
||||
return ( ev->Good() && ioRow->mRow_Length <= inNewSize );
|
||||
}
|
||||
|
||||
// alloc & free individual instances of atoms (lots of atom subclasses):
|
||||
void
|
||||
morkPool::ZapAtom(morkEnv* ev, morkAtom* ioAtom) // any subclass (by kind)
|
||||
{
|
||||
if ( ioAtom )
|
||||
mPool_Heap->Free(ev->AsMdbEnv(), ioAtom);
|
||||
}
|
||||
|
||||
morkOidAtom*
|
||||
morkPool::NewRowOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
morkOidAtom* newAtom = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom),(void**) &newAtom);
|
||||
if ( newAtom )
|
||||
newAtom->InitRowOidAtom(ev, inOid);
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkOidAtom*
|
||||
morkPool::NewTableOidAtom(morkEnv* ev, const mdbOid& inOid)
|
||||
{
|
||||
morkOidAtom* newAtom = 0;
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), sizeof(morkOidAtom), (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
newAtom->InitTableOidAtom(ev, inOid);
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkPool::NewAnonAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm)
|
||||
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
|
||||
// anon atom will be created, and otherwise a 'big' anon atom.
|
||||
{
|
||||
morkAtom* newAtom = 0;
|
||||
mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 );
|
||||
mork_size size = ( needBig )?
|
||||
morkBigAnonAtom::SizeForFill(inBuf.mBuf_Fill) :
|
||||
morkWeeAnonAtom::SizeForFill(inBuf.mBuf_Fill);
|
||||
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
{
|
||||
if ( needBig )
|
||||
((morkBigAnonAtom*) newAtom)->InitBigAnonAtom(ev, inBuf, inForm);
|
||||
else
|
||||
((morkWeeAnonAtom*) newAtom)->InitWeeAnonAtom(ev, inBuf);
|
||||
}
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkPool::NewBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid)
|
||||
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
|
||||
// book atom will be created, and otherwise a 'big' book atom.
|
||||
{
|
||||
morkBookAtom* newAtom = 0;
|
||||
mork_bool needBig = ( inForm || inBuf.mBuf_Fill > 255 );
|
||||
mork_size size = ( needBig )?
|
||||
morkBigBookAtom::SizeForFill(inBuf.mBuf_Fill) :
|
||||
morkWeeBookAtom::SizeForFill(inBuf.mBuf_Fill);
|
||||
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
{
|
||||
if ( needBig )
|
||||
((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev,
|
||||
inBuf, inForm, ioSpace, inAid);
|
||||
else
|
||||
((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev,
|
||||
inBuf, ioSpace, inAid);
|
||||
}
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
morkBookAtom*
|
||||
morkPool::NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom)
|
||||
// make the smallest kind of book atom that can hold content in inAtom.
|
||||
// The inAtom parameter is often expected to be a staged book atom in
|
||||
// the store, which was used to search an atom space for existing atoms.
|
||||
{
|
||||
morkBookAtom* newAtom = 0;
|
||||
mork_cscode form = inAtom.mBigBookAtom_Form;
|
||||
mork_fill fill = inAtom.mBigBookAtom_Size;
|
||||
mork_bool needBig = ( form || fill > 255 );
|
||||
mork_size size = ( needBig )?
|
||||
morkBigBookAtom::SizeForFill(fill) :
|
||||
morkWeeBookAtom::SizeForFill(fill);
|
||||
|
||||
mPool_Heap->Alloc(ev->AsMdbEnv(), size, (void**) &newAtom);
|
||||
if ( newAtom )
|
||||
{
|
||||
morkBuf buf(inAtom.mBigBookAtom_Body, fill);
|
||||
if ( needBig )
|
||||
((morkBigBookAtom*) newAtom)->InitBigBookAtom(ev,
|
||||
buf, form, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id);
|
||||
else
|
||||
((morkWeeBookAtom*) newAtom)->InitWeeBookAtom(ev,
|
||||
buf, inAtom.mBookAtom_Space, inAtom.mBookAtom_Id);
|
||||
}
|
||||
return newAtom;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
158
mozilla/db/mork/src/morkPool.h
Normal file
158
mozilla/db/mork/src/morkPool.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#define _MORKPOOL_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKDEQUE_
|
||||
#include "morkDeque.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class morkHandle;
|
||||
class morkHandleFrame;
|
||||
class morkHandleFace; // just an opaque cookie type
|
||||
class morkBigBookAtom;
|
||||
|
||||
#define morkDerived_kPool /*i*/ 0x706C /* ascii 'pl' */
|
||||
|
||||
/*| morkPool: a place to manage pools of non-node objects that are memory
|
||||
**| managed out of large chunks of space, so that per-object management
|
||||
**| space overhead has no signficant cost.
|
||||
|*/
|
||||
class morkPool : public morkNode {
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
nsIMdbHeap* mPool_Heap; // NON-refcounted heap instance
|
||||
|
||||
morkDeque mPool_Blocks; // linked list of large blocks from heap
|
||||
|
||||
// These two lists contain instances of morkHandleFrame:
|
||||
morkDeque mPool_UsedHandleFrames; // handle frames currently being used
|
||||
morkDeque mPool_FreeHandleFrames; // handle frames currently in free list
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // ClosePool() only if open
|
||||
virtual ~morkPool(); // assert that ClosePool() executed earlier
|
||||
|
||||
public: // morkPool construction & destruction
|
||||
morkPool(const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
nsIMdbHeap* ioSlotHeap);
|
||||
morkPool(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
nsIMdbHeap* ioSlotHeap);
|
||||
void ClosePool(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkPool(const morkPool& other);
|
||||
morkPool& operator=(const morkPool& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsPool() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kPool; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
void NonPoolTypeError(morkEnv* ev);
|
||||
|
||||
public: // morkNode memory management operators
|
||||
void* operator new(size_t inSize, nsIMdbHeap& ioHeap, morkEnv* ev)
|
||||
{ return morkNode::MakeNew(inSize, ioHeap, ev); }
|
||||
|
||||
void* operator new(size_t inSize)
|
||||
{ return ::operator new(inSize); }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
// do NOT call delete on morkNode instances. Call ZapOld() instead.
|
||||
|
||||
public: // other pool methods
|
||||
|
||||
// alloc and free individual instances of handles (inside hand frames):
|
||||
morkHandleFace* NewHandle(morkEnv* ev, mork_size inSize);
|
||||
void ZapHandle(morkEnv* ev, morkHandleFace* ioHandle);
|
||||
|
||||
// alloc and free individual instances of rows:
|
||||
morkRow* NewRow(morkEnv* ev); // allocate a new row instance
|
||||
void ZapRow(morkEnv* ev, morkRow* ioRow); // free old row instance
|
||||
|
||||
// alloc and free entire vectors of cells (not just one cell at a time)
|
||||
morkCell* NewCells(morkEnv* ev, mork_size inSize);
|
||||
void ZapCells(morkEnv* ev, morkCell* ioVector, mork_size inSize);
|
||||
|
||||
// resize (grow or trim) cell vectors inside a containing row instance
|
||||
mork_bool AddRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize);
|
||||
mork_bool CutRowCells(morkEnv* ev, morkRow* ioRow, mork_size inNewSize);
|
||||
|
||||
// alloc & free individual instances of atoms (lots of atom subclasses):
|
||||
void ZapAtom(morkEnv* ev, morkAtom* ioAtom); // any subclass (by kind)
|
||||
|
||||
morkOidAtom* NewRowOidAtom(morkEnv* ev, const mdbOid& inOid);
|
||||
morkOidAtom* NewTableOidAtom(morkEnv* ev, const mdbOid& inOid);
|
||||
|
||||
morkAtom* NewAnonAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm);
|
||||
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
|
||||
// anon atom will be created, and otherwise a 'big' anon atom.
|
||||
|
||||
morkBookAtom* NewBookAtom(morkEnv* ev, const morkBuf& inBuf,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace, mork_aid inAid);
|
||||
// if inForm is zero, and inBuf.mBuf_Fill is less than 256, then a 'wee'
|
||||
// book atom will be created, and otherwise a 'big' book atom.
|
||||
|
||||
morkBookAtom* NewBookAtomCopy(morkEnv* ev, const morkBigBookAtom& inAtom);
|
||||
// make the smallest kind of book atom that can hold content in inAtom.
|
||||
// The inAtom parameter is often expected to be a staged book atom in
|
||||
// the store, which was used to search an atom space for existing atoms.
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakPool(morkPool* me,
|
||||
morkEnv* ev, morkPool** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongPool(morkPool* me,
|
||||
morkEnv* ev, morkPool** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKPOOL_ */
|
||||
145
mozilla/db/mork/src/morkPortTableCursor.cpp
Normal file
145
mozilla/db/mork/src/morkPortTableCursor.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPORTTABLECURSOR_
|
||||
#include "morkPortTableCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINPORTTABLECURSOR_
|
||||
#include "orkinPortTableCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkPortTableCursor::CloseMorkNode(morkEnv* ev) // ClosePortTableCursor() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->ClosePortTableCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkPortTableCursor::~morkPortTableCursor() // ClosePortTableCursor() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPortTableCursor::morkPortTableCursor(morkEnv* ev,
|
||||
const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkStore* ioStore, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, nsIMdbHeap* ioSlotHeap)
|
||||
: morkCursor(ev, inUsage, ioHeap)
|
||||
, mPortTableCursor_Store( 0 )
|
||||
, mPortTableCursor_RowScope( inRowScope )
|
||||
, mPortTableCursor_TableKind( inTableKind )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioStore )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = 0; // let the iterator do it's own seed handling
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mPortTableCursor_Store);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kPortTableCursor;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkPortTableCursor::ClosePortTableCursor(morkEnv* ev)
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = 0;
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mPortTableCursor_Store);
|
||||
this->CloseCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkPortTableCursor::NonPortTableCursorTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkPortTableCursor");
|
||||
}
|
||||
|
||||
orkinPortTableCursor*
|
||||
morkPortTableCursor::AcquirePortTableCursorHandle(morkEnv* ev)
|
||||
{
|
||||
orkinPortTableCursor* outCursor = 0;
|
||||
orkinPortTableCursor* c = (orkinPortTableCursor*) mObject_Handle;
|
||||
if ( c ) // have an old handle?
|
||||
c->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
c = orkinPortTableCursor::MakePortTableCursor(ev, this);
|
||||
mObject_Handle = c;
|
||||
}
|
||||
if ( c )
|
||||
outCursor = c;
|
||||
return outCursor;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
103
mozilla/db/mork/src/morkPortTableCursor.h
Normal file
103
mozilla/db/mork/src/morkPortTableCursor.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKPORTTABLECURSOR_
|
||||
#define _MORKPORTTABLECURSOR_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class orkinPortTableCursor;
|
||||
#define morkDerived_kPortTableCursor /*i*/ 0x7443 /* ascii 'tC' */
|
||||
|
||||
class morkPortTableCursor : public morkCursor { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkFactory* mObject_Factory; // weak ref to suite factory
|
||||
|
||||
// mork_seed mCursor_Seed;
|
||||
// mork_pos mCursor_Pos;
|
||||
// mork_bool mCursor_DoFailOnSeedOutOfSync;
|
||||
// mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
morkStore* mPortTableCursor_Store; // weak ref to store
|
||||
|
||||
mdb_scope mPortTableCursor_RowScope;
|
||||
mdb_kind mPortTableCursor_TableKind;
|
||||
|
||||
// $$$ need use a map iter for covering tables in port map (hash table)
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // ClosePortTableCursor()
|
||||
virtual ~morkPortTableCursor(); // assert that close executed earlier
|
||||
|
||||
public: // morkPortTableCursor construction & destruction
|
||||
morkPortTableCursor(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkStore* ioStore, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, nsIMdbHeap* ioSlotHeap);
|
||||
void ClosePortTableCursor(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkPortTableCursor(const morkPortTableCursor& other);
|
||||
morkPortTableCursor& operator=(const morkPortTableCursor& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsPortTableCursor() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kPortTableCursor; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // other cell cursor methods
|
||||
|
||||
static void NonPortTableCursorTypeError(morkEnv* ev);
|
||||
|
||||
orkinPortTableCursor* AcquirePortTableCursorHandle(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakPortTableCursor(morkPortTableCursor* me,
|
||||
morkEnv* ev, morkPortTableCursor** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongPortTableCursor(morkPortTableCursor* me,
|
||||
morkEnv* ev, morkPortTableCursor** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKPORTTABLECURSOR_ */
|
||||
388
mozilla/db/mork/src/morkRow.cpp
Normal file
388
mozilla/db/mork/src/morkRow.cpp
Normal file
@@ -0,0 +1,388 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELLOBJECT_
|
||||
#include "morkCellObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWCELLCURSOR_
|
||||
#include "morkRowCellCursor.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
mork_u2
|
||||
morkRow::AddTableUse(morkEnv* ev)
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not already maxed out?
|
||||
++mRow_TableUses;
|
||||
|
||||
return mRow_TableUses;
|
||||
}
|
||||
|
||||
mork_u2
|
||||
morkRow::CutTableUse(morkEnv* ev)
|
||||
{
|
||||
if ( mRow_TableUses ) // any outstanding uses to cut?
|
||||
{
|
||||
if ( mRow_TableUses < morkRow_kMaxTableUses ) // not frozen at max?
|
||||
--mRow_TableUses;
|
||||
}
|
||||
else
|
||||
this->TableUsesUnderflowWarning(ev);
|
||||
|
||||
return mRow_TableUses;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRow::TableUsesUnderflowWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("mRow_TableUses underflow");
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
morkRow::NonRowTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkRow");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRow::NonRowTypeWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("non morkRow");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRow::LengthBeyondMaxError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mRow_Length over max");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRow::ZeroColumnError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError(" zero mork_column");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRow::NilCellsError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mRow_Cells");
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
|
||||
mork_size inLength, morkPool* ioPool)
|
||||
// if inLength is nonzero, cells will be allocated from ioPool
|
||||
{
|
||||
if ( ioSpace && ioPool && inOid )
|
||||
{
|
||||
if ( inLength <= morkRow_kMaxLength )
|
||||
{
|
||||
if ( inOid->mOid_Id != morkRow_kMinusOneRid )
|
||||
{
|
||||
mRow_Space = ioSpace;
|
||||
mRow_Object = 0;
|
||||
mRow_Cells = 0;
|
||||
mRow_Oid = *inOid;
|
||||
|
||||
mRow_Length = inLength;
|
||||
mRow_Seed = (mork_u2) this; // "random" assignment
|
||||
|
||||
mRow_TableUses = 0;
|
||||
mRow_Load = morkLoad_kClean;
|
||||
mRow_Tag = morkRow_kTag;
|
||||
|
||||
if ( inLength )
|
||||
mRow_Cells = ioPool->NewCells(ev, inLength);
|
||||
}
|
||||
else
|
||||
ioSpace->MinusOneRidError(ev);
|
||||
}
|
||||
else
|
||||
this->LengthBeyondMaxError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
morkRowObject*
|
||||
morkRow::GetRowObject(morkEnv* ev, morkStore* ioStore)
|
||||
{
|
||||
morkRowObject* ro = mRow_Object;
|
||||
if ( !ro ) // need new row object?
|
||||
{
|
||||
nsIMdbHeap* heap = ioStore->mPort_Heap;
|
||||
ro = new (*heap, ev)
|
||||
morkRowObject(ev, morkUsage::kHeap, heap, this, ioStore);
|
||||
mRow_Object = ro;
|
||||
}
|
||||
return ro;
|
||||
}
|
||||
|
||||
nsIMdbRow*
|
||||
morkRow::AcquireRowHandle(morkEnv* ev, morkStore* ioStore)
|
||||
{
|
||||
morkRowObject* object = this->GetRowObject(ev, ioStore);
|
||||
if ( object )
|
||||
return object->AcquireRowHandle(ev);
|
||||
|
||||
return (nsIMdbRow*) 0;
|
||||
}
|
||||
|
||||
nsIMdbCell*
|
||||
morkRow::AcquireCellHandle(morkEnv* ev, morkCell* ioCell,
|
||||
mdb_column inCol, mork_pos inPos)
|
||||
{
|
||||
nsIMdbHeap* heap = ev->mEnv_Heap;
|
||||
morkCellObject* cellObj = new (*heap, ev)
|
||||
morkCellObject(ev, morkUsage::kHeap, heap, this, ioCell, inCol, inPos);
|
||||
if ( cellObj )
|
||||
return cellObj->AcquireCellHandle(ev);
|
||||
|
||||
return (nsIMdbCell*) 0;
|
||||
}
|
||||
|
||||
morkCell*
|
||||
morkRow::NewCell(morkEnv* ev, mdb_column inColumn,
|
||||
mork_pos* outPos, morkStore* ioStore)
|
||||
{
|
||||
++mRow_Seed; // intend to change structure of mRow_Cells
|
||||
mork_pos length = (mork_pos) mRow_Length;
|
||||
*outPos = length;
|
||||
morkPool* pool = ioStore->StorePool();
|
||||
if ( pool->AddRowCells(ev, this, length + 1) )
|
||||
{
|
||||
morkCell* cell = mRow_Cells + length;
|
||||
cell->SetColumnAndChange(inColumn, morkChange_kAdd);
|
||||
return cell;
|
||||
}
|
||||
|
||||
return (morkCell*) 0;
|
||||
}
|
||||
|
||||
morkCell*
|
||||
morkRow::CellAt(morkEnv* ev, mork_pos inPos) const
|
||||
{
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells && inPos < mRow_Length )
|
||||
{
|
||||
return cells + inPos;
|
||||
}
|
||||
return (morkCell*) 0;
|
||||
}
|
||||
|
||||
morkCell*
|
||||
morkRow::GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const
|
||||
{
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
morkCell* end = cells + mRow_Length;
|
||||
while ( cells < end )
|
||||
{
|
||||
mork_column col = cells->GetColumn();
|
||||
if ( col == inColumn ) // found the desired column?
|
||||
{
|
||||
*outPos = cells - mRow_Cells;
|
||||
return cells;
|
||||
}
|
||||
else
|
||||
++cells;
|
||||
}
|
||||
}
|
||||
*outPos = -1;
|
||||
return (morkCell*) 0;
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::EmptyAllCells(morkEnv* ev)
|
||||
{
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkPool* pool = store->StorePool();
|
||||
morkCell* end = cells + mRow_Length;
|
||||
--cells; // prepare for preincrement:
|
||||
while ( ++cells < end )
|
||||
{
|
||||
if ( cells->mCell_Atom )
|
||||
cells->SetAtom(ev, (morkAtom*) 0, pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::AddRow(morkEnv* ev, const morkRow* inSourceRow)
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
// $$$$$ need to iterate over inSourceRow cells adding them to this row.
|
||||
// When the atoms are book atoms, we can just incr the use count.
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::OnZeroTableUse(morkEnv* ev)
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
{
|
||||
// OK, this is a P1 showstopper bug, so I'll comment it out.
|
||||
// ev->NewWarning("need to implement OnZeroTableUse");
|
||||
}
|
||||
|
||||
void
|
||||
morkRow::DirtyAllRowContent(morkEnv* ev)
|
||||
{
|
||||
this->SetRowDirty();
|
||||
|
||||
morkCell* cells = mRow_Cells;
|
||||
if ( cells )
|
||||
{
|
||||
morkCell* end = cells + mRow_Length;
|
||||
--cells; // prepare for preincrement:
|
||||
while ( ++cells < end )
|
||||
{
|
||||
cells->SetCellDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
morkStore*
|
||||
morkRow::GetRowSpaceStore(morkEnv* ev) const
|
||||
{
|
||||
morkRowSpace* rowSpace = mRow_Space;
|
||||
if ( rowSpace )
|
||||
{
|
||||
morkStore* store = rowSpace->mSpace_Store;
|
||||
if ( store )
|
||||
{
|
||||
if ( store->IsStore() )
|
||||
{
|
||||
return store;
|
||||
}
|
||||
else
|
||||
store->NonStoreTypeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (morkStore*) 0;
|
||||
}
|
||||
|
||||
void morkRow::AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mork_pos pos = -1;
|
||||
morkCell* cell = this->GetCell(ev, inColumn, &pos);
|
||||
if ( !cell ) // column does not yet exist?
|
||||
cell = this->NewCell(ev, inColumn, &pos, ioStore);
|
||||
else
|
||||
++mRow_Seed;
|
||||
|
||||
if ( cell )
|
||||
{
|
||||
// cell->SetYarn(ev, inYarn, ioStore);
|
||||
morkAtom* atom = ioStore->YarnToAtom(ev, inYarn);
|
||||
if ( atom )
|
||||
cell->SetAtom(ev, atom, ioStore->StorePool()); // refcounts atom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
morkRowCellCursor*
|
||||
morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos)
|
||||
{
|
||||
morkRowCellCursor* outCursor = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkStore* store = this->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
{
|
||||
morkRowObject* rowObj = this->GetRowObject(ev, store);
|
||||
if ( rowObj )
|
||||
{
|
||||
nsIMdbHeap* heap = store->mPort_Heap;
|
||||
morkRowCellCursor* cursor = new (*heap, ev)
|
||||
morkRowCellCursor(ev, morkUsage::kHeap, heap, rowObj);
|
||||
|
||||
if ( cursor )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
cursor->mCursor_Pos = inPos;
|
||||
outCursor = cursor;
|
||||
}
|
||||
else
|
||||
cursor->CutStrongRef(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outCursor;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
143
mozilla/db/mork/src/morkRow.h
Normal file
143
mozilla/db/mork/src/morkRow.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#define _MORKROW_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class nsIMdbRow;
|
||||
class nsIMdbCell;
|
||||
#define morkDerived_kRow /*i*/ 0x5277 /* ascii 'Rw' */
|
||||
|
||||
#define morkRow_kMaxTableUses 0x0FFFF /* max for 16-bit unsigned int */
|
||||
#define morkRow_kMaxLength 0x0FFFF /* max for 16-bit unsigned int */
|
||||
#define morkRow_kMinusOneRid ((mork_rid) -1)
|
||||
|
||||
#define morkRow_kTag 'r' /* magic signature for mRow_Tag */
|
||||
|
||||
|
||||
class morkRow { // row of cells
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
morkRowSpace* mRow_Space; // mRow_Space->mSpace_Scope is the row scope
|
||||
morkRowObject* mRow_Object; // refcount & other state for object sharing
|
||||
morkCell* mRow_Cells;
|
||||
mdbOid mRow_Oid;
|
||||
|
||||
mork_u2 mRow_Length; // physical count of cells in mRow_Cells
|
||||
mork_u2 mRow_Seed; // count changes in mRow_Cells structure
|
||||
|
||||
mork_u2 mRow_TableUses; // persistent references from tables
|
||||
mork_load mRow_Load; // is this row clean or dirty?
|
||||
mork_u1 mRow_Tag; // one-byte tag (need u4 alignment pad)
|
||||
|
||||
public: // other row methods
|
||||
morkRow( ) { }
|
||||
morkRow(const mdbOid* inOid) :mRow_Oid(*inOid) { }
|
||||
void InitRow(morkEnv* ev, const mdbOid* inOid, morkRowSpace* ioSpace,
|
||||
mork_size inLength, morkPool* ioPool);
|
||||
// if inLength is nonzero, cells will be allocated from ioPool
|
||||
|
||||
morkRowObject* GetRowObject(morkEnv* ev, morkStore* ioStore);
|
||||
nsIMdbRow* AcquireRowHandle(morkEnv* ev, morkStore* ioStore);
|
||||
nsIMdbCell* AcquireCellHandle(morkEnv* ev, morkCell* ioCell,
|
||||
mdb_column inColumn, mork_pos inPos);
|
||||
|
||||
mork_u2 AddTableUse(morkEnv* ev);
|
||||
mork_u2 CutTableUse(morkEnv* ev);
|
||||
|
||||
void SetRowClean() { mRow_Load = morkLoad_kClean; }
|
||||
void SetRowDirty() { mRow_Load = morkLoad_kDirty; }
|
||||
|
||||
mork_bool IsRowClean() const { return mRow_Load == morkLoad_kClean; }
|
||||
mork_bool IsRowDirty() const { return mRow_Load == morkLoad_kDirty; }
|
||||
|
||||
public: // internal row methods
|
||||
|
||||
morkCell* NewCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos,
|
||||
morkStore* ioStore);
|
||||
morkCell* GetCell(morkEnv* ev, mdb_column inColumn, mork_pos* outPos) const;
|
||||
morkCell* CellAt(morkEnv* ev, mork_pos inPos) const;
|
||||
|
||||
public: // external row methods
|
||||
|
||||
void DirtyAllRowContent(morkEnv* ev);
|
||||
|
||||
morkStore* GetRowSpaceStore(morkEnv* ev) const;
|
||||
|
||||
void AddColumn(morkEnv* ev, mdb_column inColumn,
|
||||
const mdbYarn* inYarn, morkStore* ioStore);
|
||||
|
||||
morkRowCellCursor* NewRowCellCursor(morkEnv* ev, mdb_pos inPos);
|
||||
|
||||
void EmptyAllCells(morkEnv* ev);
|
||||
void AddRow(morkEnv* ev, const morkRow* inSourceRow);
|
||||
|
||||
void OnZeroTableUse(morkEnv* ev);
|
||||
// OnZeroTableUse() is called when CutTableUse() returns zero.
|
||||
|
||||
public: // dynamic typing
|
||||
|
||||
mork_bool IsRow() const { return mRow_Tag == morkRow_kTag; }
|
||||
|
||||
public: // hash and equal
|
||||
|
||||
mork_u4 HashRow() const
|
||||
{
|
||||
return (mRow_Oid.mOid_Scope << 16) ^ mRow_Oid.mOid_Id;
|
||||
}
|
||||
|
||||
mork_u4 EqualRow(const morkRow* ioRow) const
|
||||
{
|
||||
return
|
||||
(
|
||||
( mRow_Oid.mOid_Scope == ioRow->mRow_Oid.mOid_Scope )
|
||||
&& ( mRow_Oid.mOid_Id == ioRow->mRow_Oid.mOid_Id )
|
||||
);
|
||||
}
|
||||
|
||||
mork_u4 EqualOid(const mdbOid* ioOid) const
|
||||
{
|
||||
return
|
||||
(
|
||||
( mRow_Oid.mOid_Scope == ioOid->mOid_Scope )
|
||||
&& ( mRow_Oid.mOid_Id == ioOid->mOid_Id )
|
||||
);
|
||||
}
|
||||
|
||||
public: // errors
|
||||
static void ZeroColumnError(morkEnv* ev);
|
||||
static void LengthBeyondMaxError(morkEnv* ev);
|
||||
static void NilCellsError(morkEnv* ev);
|
||||
static void NonRowTypeError(morkEnv* ev);
|
||||
static void NonRowTypeWarning(morkEnv* ev);
|
||||
static void TableUsesUnderflowWarning(morkEnv* ev);
|
||||
|
||||
private: // copying is not allowed
|
||||
morkRow(const morkRow& other);
|
||||
morkRow& operator=(const morkRow& other);
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKROW_ */
|
||||
165
mozilla/db/mork/src/morkRowCellCursor.cpp
Normal file
165
mozilla/db/mork/src/morkRowCellCursor.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWCELLCURSOR_
|
||||
#include "morkRowCellCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINROWCELLCURSOR_
|
||||
#include "orkinRowCellCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkRowCellCursor::CloseMorkNode(morkEnv* ev) // CloseRowCellCursor() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseRowCellCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkRowCellCursor::~morkRowCellCursor() // CloseRowCellCursor() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkRowCellCursor::morkRowCellCursor(morkEnv* ev,
|
||||
const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkRowObject* ioRowObject)
|
||||
: morkCursor(ev, inUsage, ioHeap)
|
||||
, mRowCellCursor_RowObject( 0 )
|
||||
, mRowCellCursor_Col( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioRowObject )
|
||||
{
|
||||
morkRow* row = ioRowObject->mRowObject_Row;
|
||||
if ( row )
|
||||
{
|
||||
if ( row->IsRow() )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = row->mRow_Seed;
|
||||
|
||||
morkRowObject::SlotStrongRowObject(ioRowObject, ev,
|
||||
&mRowCellCursor_RowObject);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowCellCursor;
|
||||
}
|
||||
else
|
||||
row->NonRowTypeError(ev);
|
||||
}
|
||||
else
|
||||
ioRowObject->NilRowError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkRowCellCursor::CloseRowCellCursor(morkEnv* ev)
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = 0;
|
||||
morkRowObject::SlotStrongRowObject((morkRowObject*) 0, ev,
|
||||
&mRowCellCursor_RowObject);
|
||||
this->CloseCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkRowCellCursor::NonRowCellCursorTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkRowCellCursor");
|
||||
}
|
||||
|
||||
orkinRowCellCursor*
|
||||
morkRowCellCursor::AcquireRowCellCursorHandle(morkEnv* ev)
|
||||
{
|
||||
orkinRowCellCursor* outCursor = 0;
|
||||
orkinRowCellCursor* c = (orkinRowCellCursor*) mObject_Handle;
|
||||
if ( c ) // have an old handle?
|
||||
c->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
c = orkinRowCellCursor::MakeRowCellCursor(ev, this);
|
||||
mObject_Handle = c;
|
||||
}
|
||||
if ( c )
|
||||
outCursor = c;
|
||||
return outCursor;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
97
mozilla/db/mork/src/morkRowCellCursor.h
Normal file
97
mozilla/db/mork/src/morkRowCellCursor.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKROWCELLCURSOR_
|
||||
#define _MORKROWCELLCURSOR_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class orkinRowCellCursor;
|
||||
#define morkDerived_kRowCellCursor /*i*/ 0x6343 /* ascii 'cC' */
|
||||
|
||||
class morkRowCellCursor : public morkCursor { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkFactory* mObject_Factory; // weak ref to suite factory
|
||||
|
||||
// mork_seed mCursor_Seed;
|
||||
// mork_pos mCursor_Pos;
|
||||
// mork_bool mCursor_DoFailOnSeedOutOfSync;
|
||||
// mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkRowObject* mRowCellCursor_RowObject; // strong ref to row
|
||||
mork_column mRowCellCursor_Col; // col of cell last at mCursor_Pos
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseRowCellCursor()
|
||||
virtual ~morkRowCellCursor(); // assert that close executed earlier
|
||||
|
||||
public: // morkRowCellCursor construction & destruction
|
||||
morkRowCellCursor(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkRowObject* ioRowObject);
|
||||
void CloseRowCellCursor(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkRowCellCursor(const morkRowCellCursor& other);
|
||||
morkRowCellCursor& operator=(const morkRowCellCursor& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsRowCellCursor() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kRowCellCursor; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonRowCellCursorTypeError(morkEnv* ev);
|
||||
|
||||
public: // other cell cursor methods
|
||||
orkinRowCellCursor* AcquireRowCellCursorHandle(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakRowCellCursor(morkRowCellCursor* me,
|
||||
morkEnv* ev, morkRowCellCursor** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongRowCellCursor(morkRowCellCursor* me,
|
||||
morkEnv* ev, morkRowCellCursor** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKROWCELLCURSOR_ */
|
||||
171
mozilla/db/mork/src/morkRowMap.cpp
Normal file
171
mozilla/db/mork/src/morkRowMap.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkRowMap::CloseMorkNode(morkEnv* ev) // CloseRowMap() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseRowMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkRowMap::~morkRowMap() // assert CloseRowMap() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkRowMap::morkRowMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots)
|
||||
: morkMap(ev, inUsage, ioHeap,
|
||||
/*inKeySize*/ sizeof(morkRow*), /*inValSize*/ 0,
|
||||
inSlots, ioSlotHeap, /*inHoldChanges*/ morkBool_kFalse)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowMap;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkRowMap::CloseRowMap(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
this->CloseMap(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
/*virtual*/ mork_bool //
|
||||
morkRowMap::Equal(morkEnv* ev, const void* inKeyA,
|
||||
const void* inKeyB) const
|
||||
{
|
||||
return (*(const morkRow**) inKeyA)->EqualRow(*(const morkRow**) inKeyB);
|
||||
}
|
||||
|
||||
/*virtual*/ mork_u4 //
|
||||
morkRowMap::Hash(morkEnv* ev, const void* inKey) const
|
||||
{
|
||||
return (*(const morkRow**) inKey)->HashRow();
|
||||
}
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
|
||||
mork_bool
|
||||
morkRowMap::AddRow(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Put(ev, &ioRow, /*val*/ (void*) 0,
|
||||
/*key*/ (void*) 0, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::CutOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow row(inOid);
|
||||
morkRow* key = &row;
|
||||
morkRow* oldKey = 0;
|
||||
this->Cut(ev, &key, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::CutRow(morkEnv* ev, const morkRow* ioRow)
|
||||
{
|
||||
morkRow* oldKey = 0;
|
||||
this->Cut(ev, &ioRow, &oldKey, /*val*/ (void*) 0,
|
||||
(mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::GetOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow row(inOid);
|
||||
morkRow* key = &row;
|
||||
morkRow* oldKey = 0;
|
||||
this->Get(ev, &key, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowMap::GetRow(morkEnv* ev, const morkRow* ioRow)
|
||||
{
|
||||
morkRow* oldKey = 0;
|
||||
this->Get(ev, &ioRow, &oldKey, /*val*/ (void*) 0, (mork_change**) 0);
|
||||
|
||||
return oldKey;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
112
mozilla/db/mork/src/morkRowMap.h
Normal file
112
mozilla/db/mork/src/morkRowMap.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#define _MORKROWMAP_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kRowMap /*i*/ 0x724D /* ascii 'rM' */
|
||||
|
||||
/*| morkRowMap: maps a set of morkRow by contained Oid
|
||||
|*/
|
||||
class morkRowMap : public morkMap { // for mapping row IDs to rows
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseRowMap() only if open
|
||||
virtual ~morkRowMap(); // assert that CloseRowMap() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkRowMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_size inSlots);
|
||||
void CloseRowMap(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsRowMap() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kRowMap; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
// { ===== begin morkMap poly interface =====
|
||||
virtual mork_bool // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Equal(morkEnv* ev, const void* inKeyA, const void* inKeyB) const;
|
||||
// implemented using morkRow::EqualRow()
|
||||
|
||||
virtual mork_u4 // note: equal(a,b) implies hash(a) == hash(b)
|
||||
Hash(morkEnv* ev, const void* inKey) const;
|
||||
// implemented using morkRow::HashRow()
|
||||
// } ===== end morkMap poly interface =====
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddRow(morkEnv* ev, morkRow* ioRow);
|
||||
// AddRow() returns ev->Good()
|
||||
|
||||
morkRow* CutOid(morkEnv* ev, const mdbOid* inOid);
|
||||
// CutRid() returns the row removed equal to inRid, if there was one
|
||||
|
||||
morkRow* CutRow(morkEnv* ev, const morkRow* ioRow);
|
||||
// CutRow() returns the row removed equal to ioRow, if there was one
|
||||
|
||||
morkRow* GetOid(morkEnv* ev, const mdbOid* inOid);
|
||||
// GetOid() returns the row equal to inRid, or else nil
|
||||
|
||||
morkRow* GetRow(morkEnv* ev, const morkRow* ioRow);
|
||||
// GetRow() returns the row equal to ioRow, or else nil
|
||||
|
||||
// note the rows are owned elsewhere, usuall by morkRowSpace
|
||||
};
|
||||
|
||||
class morkRowMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkRowMapIter(morkEnv* ev, morkRowMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkRowMapIter( ) : morkMapIter() { }
|
||||
void InitRowMapIter(morkEnv* ev, morkRowMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change* FirstRow(morkEnv* ev, morkRow** outRowPtr)
|
||||
{ return this->First(ev, outRowPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* NextRow(morkEnv* ev, morkRow** outRowPtr)
|
||||
{ return this->Next(ev, outRowPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* HereRow(morkEnv* ev, morkRow** outRowPtr)
|
||||
{ return this->Here(ev, outRowPtr, /*val*/ (void*) 0); }
|
||||
|
||||
mork_change* CutHereRow(morkEnv* ev, morkRow** outRowPtr)
|
||||
{ return this->CutHere(ev, outRowPtr, /*val*/ (void*) 0); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKROWMAP_ */
|
||||
170
mozilla/db/mork/src/morkRowObject.cpp
Normal file
170
mozilla/db/mork/src/morkRowObject.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINROW_
|
||||
#include "orkinRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkRowObject::CloseMorkNode(morkEnv* ev) // CloseRowObject() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseRowObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkRowObject::~morkRowObject() // assert CloseRowObject() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkRowObject::morkRowObject(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkRow* ioRow, morkStore* ioStore)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mRowObject_Row( 0 )
|
||||
, mRowObject_Store( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioRow && ioStore )
|
||||
{
|
||||
mRowObject_Row = ioRow;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mRowObject_Store);
|
||||
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowObject;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkRowObject::CloseRowObject(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkRow* row = mRowObject_Row;
|
||||
mRowObject_Row = 0;
|
||||
this->CloseObject(ev);
|
||||
this->MarkShut();
|
||||
|
||||
if ( row )
|
||||
{
|
||||
if ( row->mRow_Object == this )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&row->mRow_Object);
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev,
|
||||
&mRowObject_Store);
|
||||
}
|
||||
else
|
||||
MORK_ASSERT(morkBool_kFalse);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkRowObject::NonRowObjectTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkRowObject");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRowObject::NilRowError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mRowObject_Row");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRowObject::NilStoreError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mRowObject_Store");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRowObject::RowObjectRowNotSelfError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mRowObject_Row->mRow_Object != self");
|
||||
}
|
||||
|
||||
|
||||
nsIMdbRow*
|
||||
morkRowObject::AcquireRowHandle(morkEnv* ev) // mObject_Handle
|
||||
{
|
||||
nsIMdbRow* outRow = 0;
|
||||
orkinRow* r = (orkinRow*) mObject_Handle;
|
||||
if ( r ) // have an old handle?
|
||||
r->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
r = orkinRow::MakeRow(ev, this);
|
||||
mObject_Handle = r;
|
||||
}
|
||||
if ( r )
|
||||
outRow = r;
|
||||
return outRow;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
82
mozilla/db/mork/src/morkRowObject.h
Normal file
82
mozilla/db/mork/src/morkRowObject.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#define _MORKROWOBJECT_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class nsIMdbRow;
|
||||
#define morkDerived_kRowObject /*i*/ 0x724F /* ascii 'rO' */
|
||||
|
||||
class morkRowObject : public morkObject { //
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
morkRow* mRowObject_Row; // non-refcounted alias to morkRow
|
||||
morkStore* mRowObject_Store; // weak ref to store containing row
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseRowObject() only if open
|
||||
virtual ~morkRowObject(); // assert that CloseRowObject() executed earlier
|
||||
|
||||
public: // morkRowObject construction & destruction
|
||||
morkRowObject(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkRow* ioRow, morkStore* ioStore);
|
||||
void CloseRowObject(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkRowObject(const morkRowObject& other);
|
||||
morkRowObject& operator=(const morkRowObject& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsRowObject() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kRowObject; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonRowObjectTypeError(morkEnv* ev);
|
||||
static void NilRowError(morkEnv* ev);
|
||||
static void NilStoreError(morkEnv* ev);
|
||||
static void RowObjectRowNotSelfError(morkEnv* ev);
|
||||
|
||||
public: // other row node methods
|
||||
|
||||
nsIMdbRow* AcquireRowHandle(morkEnv* ev); // mObject_Handle
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakRowObject(morkRowObject* me,
|
||||
morkEnv* ev, morkRowObject** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongRowObject(morkRowObject* me,
|
||||
morkEnv* ev, morkRowObject** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKROWOBJECT_ */
|
||||
382
mozilla/db/mork/src/morkRowSpace.cpp
Normal file
382
mozilla/db/mork/src/morkRowSpace.cpp
Normal file
@@ -0,0 +1,382 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#include "morkSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#include "morkNodeMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkRowSpace::CloseMorkNode(morkEnv* ev) // CloseRowSpace() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseRowSpace(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkRowSpace::~morkRowSpace() // assert CloseRowSpace() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkRowSpace::morkRowSpace(morkEnv* ev,
|
||||
const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkSpace(ev, inUsage, inScope, ioStore, ioHeap, ioSlotHeap)
|
||||
, mRowSpace_Tables(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
|
||||
, mRowSpace_Rows(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
|
||||
morkRowSpace_kStartRowMapSlotCount)
|
||||
, mRowSpace_NextTableId( 1 )
|
||||
, mRowSpace_NextRowId( 1 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowSpace;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkRowSpace::CloseRowSpace(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mRowSpace_Tables.CloseMorkNode(ev);
|
||||
|
||||
morkStore* store = mSpace_Store;
|
||||
if ( store )
|
||||
this->CutAllRows(ev, &store->mStore_Pool);
|
||||
|
||||
mRowSpace_Rows.CloseMorkNode(ev);
|
||||
this->CloseSpace(ev);
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkRowSpace::NonRowSpaceTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkRowSpace");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRowSpace::ZeroKindError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("zero table kind");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRowSpace::ZeroScopeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("zero row scope");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRowSpace::ZeroTidError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("zero table ID");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkRowSpace::MinusOneRidError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("row ID is -1");
|
||||
}
|
||||
|
||||
///*static*/ void
|
||||
//morkRowSpace::ExpectAutoIdOnlyError(morkEnv* ev)
|
||||
//{
|
||||
// ev->NewError("zero row ID");
|
||||
//}
|
||||
|
||||
///*static*/ void
|
||||
//morkRowSpace::ExpectAutoIdNeverError(morkEnv* ev)
|
||||
//{
|
||||
//}
|
||||
|
||||
mork_num
|
||||
morkRowSpace::CutAllRows(morkEnv* ev, morkPool* ioPool)
|
||||
{
|
||||
mork_num outSlots = mRowSpace_Rows.mMap_Fill;
|
||||
morkRow* r = 0; // old key row in the map
|
||||
|
||||
mork_change* c = 0;
|
||||
morkRowMapIter i(ev, &mRowSpace_Rows);
|
||||
for ( c = i.FirstRow(ev, &r); c && ev->Good();
|
||||
c = i.NextRow(ev, &r) )
|
||||
{
|
||||
if ( r->IsRow() )
|
||||
{
|
||||
if ( r->mRow_Object )
|
||||
{
|
||||
morkRowObject::SlotWeakRowObject((morkRowObject*) 0, ev,
|
||||
&r->mRow_Object);
|
||||
}
|
||||
if ( r )
|
||||
ioPool->ZapRow(ev, r);
|
||||
}
|
||||
else
|
||||
r->NonRowTypeWarning(ev);
|
||||
|
||||
i.CutHereRow(ev, /*key*/ (morkRow**) 0);
|
||||
}
|
||||
|
||||
return outSlots;
|
||||
}
|
||||
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::FindTableByKind(morkEnv* ev, mork_kind inTableKind)
|
||||
{
|
||||
if ( inTableKind )
|
||||
{
|
||||
mork_tid* key = 0; // nil pointer to suppress key access
|
||||
morkTable* table = 0; // old table in the map
|
||||
|
||||
mork_change* c = 0;
|
||||
morkTableMapIter i(ev, &mRowSpace_Tables);
|
||||
for ( c = i.FirstTable(ev, key, &table); c && ev->Good();
|
||||
c = i.NextTable(ev, key, &table) )
|
||||
{
|
||||
if ( table->mTable_Kind == inTableKind )
|
||||
return table;
|
||||
}
|
||||
}
|
||||
else
|
||||
this->ZeroKindError(ev);
|
||||
|
||||
return (morkTable*) 0;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkRowSpace::NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique)
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
|
||||
if ( inTableKind )
|
||||
{
|
||||
if ( inMustBeUnique ) // need to look for existing table first?
|
||||
outTable = this->FindTableByKind(ev, inTableKind);
|
||||
|
||||
if ( !outTable && ev->Good() )
|
||||
{
|
||||
mork_tid id = this->MakeNewTableId(ev);
|
||||
if ( id )
|
||||
{
|
||||
nsIMdbHeap* heap = mSpace_Store->mPort_Heap;
|
||||
morkTable* table = new(*heap, ev)
|
||||
morkTable(ev, morkUsage::kHeap, heap, mSpace_Store, heap, this,
|
||||
id, inTableKind, inMustBeUnique);
|
||||
if ( table )
|
||||
{
|
||||
if ( mRowSpace_Tables.AddTable(ev, table) )
|
||||
outTable = table;
|
||||
else
|
||||
table->CutStrongRef(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this->ZeroKindError(ev);
|
||||
|
||||
return outTable;
|
||||
}
|
||||
|
||||
mork_tid
|
||||
morkRowSpace::MakeNewTableId(morkEnv* ev)
|
||||
{
|
||||
mork_tid outTid = 0;
|
||||
mork_tid id = mRowSpace_NextTableId;
|
||||
mork_num count = 9; // try up to eight times
|
||||
|
||||
while ( !outTid && --count ) // still trying to find an unused table ID?
|
||||
{
|
||||
if ( !mRowSpace_Tables.GetTable(ev, id) )
|
||||
outTid = id;
|
||||
else
|
||||
{
|
||||
MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems
|
||||
++id;
|
||||
}
|
||||
}
|
||||
|
||||
mRowSpace_NextTableId = id + 1;
|
||||
return outTid;
|
||||
}
|
||||
|
||||
mork_rid
|
||||
morkRowSpace::MakeNewRowId(morkEnv* ev)
|
||||
{
|
||||
mork_rid outRid = 0;
|
||||
mork_rid id = mRowSpace_NextRowId;
|
||||
mork_num count = 9; // try up to eight times
|
||||
mdbOid oid;
|
||||
oid.mOid_Scope = mSpace_Scope;
|
||||
|
||||
while ( !outRid && --count ) // still trying to find an unused row ID?
|
||||
{
|
||||
oid.mOid_Id = id;
|
||||
if ( !mRowSpace_Rows.GetOid(ev, &oid) )
|
||||
outRid = id;
|
||||
else
|
||||
{
|
||||
MORK_ASSERT(morkBool_kFalse); // alert developer about ID problems
|
||||
++id;
|
||||
}
|
||||
}
|
||||
|
||||
mRowSpace_NextRowId = id + 1;
|
||||
return outRid;
|
||||
}
|
||||
|
||||
|
||||
morkRow*
|
||||
morkRowSpace::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow* outRow = mRowSpace_Rows.GetOid(ev, inOid);
|
||||
MORK_ASSERT(outRow==0);
|
||||
if ( !outRow && ev->Good() )
|
||||
{
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
morkRow* row = pool->NewRow(ev);
|
||||
if ( row )
|
||||
{
|
||||
row->InitRow(ev, inOid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
outRow = row;
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
}
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkRowSpace::NewRow(morkEnv* ev)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mork_rid id = this->MakeNewRowId(ev);
|
||||
if ( id )
|
||||
{
|
||||
mdbOid oid;
|
||||
oid.mOid_Scope = mSpace_Scope;
|
||||
oid.mOid_Id = id;
|
||||
morkPool* pool = this->GetSpaceStorePool();
|
||||
morkRow* row = pool->NewRow(ev);
|
||||
if ( row )
|
||||
{
|
||||
row->InitRow(ev, &oid, this, /*length*/ 0, pool);
|
||||
|
||||
if ( ev->Good() && mRowSpace_Rows.AddRow(ev, row) )
|
||||
outRow = row;
|
||||
else
|
||||
pool->ZapRow(ev, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
morkRowSpaceMap::~morkRowSpaceMap()
|
||||
{
|
||||
}
|
||||
|
||||
morkRowSpaceMap::morkRowSpaceMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kRowSpaceMap;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
203
mozilla/db/mork/src/morkRowSpace.h
Normal file
203
mozilla/db/mork/src/morkRowSpace.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#define _MORKROWSPACE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#include "morkSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#include "morkNodeMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kRowSpace /*i*/ 0x7253 /* ascii 'rS' */
|
||||
|
||||
#define morkRowSpace_kStartRowMapSlotCount 512
|
||||
|
||||
/*| morkRowSpace:
|
||||
|*/
|
||||
class morkRowSpace : public morkSpace { //
|
||||
|
||||
// public: // slots inherited from morkSpace (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkStore* mSpace_Store; // weak ref to containing store
|
||||
// mork_scope mSpace_Scope; // the scope for this space
|
||||
|
||||
// mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs
|
||||
// mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs
|
||||
// mork_u1 mSpace_Pad[ 2 ]; // pad to u4 alignment
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkRowMap mRowSpace_Rows; // hash table of morkRow instances
|
||||
morkTableMap mRowSpace_Tables; // all the tables in this row scope
|
||||
|
||||
mork_tid mRowSpace_NextTableId; // for auto-assigning table IDs
|
||||
mork_rid mRowSpace_NextRowId; // for auto-assigning row IDs
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseRowSpace() only if open
|
||||
virtual ~morkRowSpace(); // assert that CloseRowSpace() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
morkRowSpace(morkEnv* ev, const morkUsage& inUsage, mork_scope inScope,
|
||||
morkStore* ioStore, nsIMdbHeap* ioNodeHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseRowSpace(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsRowSpace() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kRowSpace; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonRowSpaceTypeError(morkEnv* ev);
|
||||
static void ZeroScopeError(morkEnv* ev);
|
||||
static void ZeroKindError(morkEnv* ev);
|
||||
static void ZeroTidError(morkEnv* ev);
|
||||
static void MinusOneRidError(morkEnv* ev);
|
||||
|
||||
//static void ExpectAutoIdOnlyError(morkEnv* ev);
|
||||
//static void ExpectAutoIdNeverError(morkEnv* ev);
|
||||
|
||||
public: // other space methods
|
||||
|
||||
mork_num CutAllRows(morkEnv* ev, morkPool* ioPool);
|
||||
// CutAllRows() puts all rows and cells back into the pool.
|
||||
|
||||
morkTable* NewTable(morkEnv* ev, mork_kind inTableKind,
|
||||
mdb_bool inMustBeUnique);
|
||||
|
||||
morkTable* FindTableByKind(morkEnv* ev, mork_kind inTableKind);
|
||||
morkTable* FindTableByTid(morkEnv* ev, mork_tid inTid)
|
||||
{ return mRowSpace_Tables.GetTable(ev, inTid); }
|
||||
|
||||
mork_tid MakeNewTableId(morkEnv* ev);
|
||||
mork_rid MakeNewRowId(morkEnv* ev);
|
||||
|
||||
// morkRow* FindRowByRid(morkEnv* ev, mork_rid inRid)
|
||||
// { return (morkRow*) mRowSpace_Rows.GetRow(ev, inRid); }
|
||||
|
||||
morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid);
|
||||
morkRow* NewRow(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakRowSpace(morkRowSpace* me,
|
||||
morkEnv* ev, morkRowSpace** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongRowSpace(morkRowSpace* me,
|
||||
morkEnv* ev, morkRowSpace** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kRowSpaceMap /*i*/ 0x725A /* ascii 'rZ' */
|
||||
|
||||
/*| morkRowSpaceMap: maps mork_scope -> morkRowSpace
|
||||
|*/
|
||||
class morkRowSpaceMap : public morkNodeMap { // for mapping tokens to tables
|
||||
|
||||
public:
|
||||
|
||||
virtual ~morkRowSpaceMap();
|
||||
morkRowSpaceMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddRowSpace(morkEnv* ev, morkRowSpace* ioRowSpace)
|
||||
{ return this->AddNode(ev, ioRowSpace->mSpace_Scope, ioRowSpace); }
|
||||
// the AddRowSpace() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutRowSpace(morkEnv* ev, mork_scope inScope)
|
||||
{ return this->CutNode(ev, inScope); }
|
||||
// The CutRowSpace() boolean return indicates whether removal happened.
|
||||
|
||||
morkRowSpace* GetRowSpace(morkEnv* ev, mork_scope inScope)
|
||||
{ return (morkRowSpace*) this->GetNode(ev, inScope); }
|
||||
// Note the returned space does NOT have an increase in refcount for this.
|
||||
|
||||
mork_num CutAllRowSpaces(morkEnv* ev)
|
||||
{ return this->CutAllNodes(ev); }
|
||||
// CutAllRowSpaces() releases all the referenced table values.
|
||||
};
|
||||
|
||||
class morkRowSpaceMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkRowSpaceMapIter(morkEnv* ev, morkRowSpaceMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkRowSpaceMapIter( ) : morkMapIter() { }
|
||||
void InitRowSpaceMapIter(morkEnv* ev, morkRowSpaceMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change*
|
||||
FirstRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace)
|
||||
{ return this->First(ev, outScope, outRowSpace); }
|
||||
|
||||
mork_change*
|
||||
NextRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace)
|
||||
{ return this->Next(ev, outScope, outRowSpace); }
|
||||
|
||||
mork_change*
|
||||
HereRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace)
|
||||
{ return this->Here(ev, outScope, outRowSpace); }
|
||||
|
||||
mork_change*
|
||||
CutHereRowSpace(morkEnv* ev, mork_scope* outScope, morkRowSpace** outRowSpace)
|
||||
{ return this->CutHere(ev, outScope, outRowSpace); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKROWSPACE_ */
|
||||
113
mozilla/db/mork/src/morkSink.cpp
Normal file
113
mozilla/db/mork/src/morkSink.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#include "morkSink.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*virtual*/ morkSink::~morkSink()
|
||||
{
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpoolSink::FlushSink(morkEnv* ev) // probably does nothing
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*virtual*/ void
|
||||
morkSpoolSink::SpillPutc(morkEnv* ev, int c) // grow spool and write byte
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// public: // public non-poly morkSink methods
|
||||
|
||||
/*virtual*/
|
||||
morkSpoolSink::~morkSpoolSink()
|
||||
// Zero all slots to show this sink is disabled, but destroy no memory.
|
||||
// Note it is typically unnecessary to flush this spool sink, since all
|
||||
// content is written directly to the spool without any buffering.
|
||||
{
|
||||
}
|
||||
|
||||
morkSpoolSink::morkSpoolSink(morkEnv* ev, morkSpool* ioSpool)
|
||||
// After installing the spool, calls Seek(ev, 0) to prepare for writing.
|
||||
: morkSink()
|
||||
, mSpoolSink_Spool( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioSpool )
|
||||
{
|
||||
// ev->StubMethodOnlyError();
|
||||
mSink_At = 0;
|
||||
mSink_End = 0;
|
||||
mSpoolSink_Spool = ioSpool;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
// ----- All boolean return values below are equal to ev->Good(): -----
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::Seek(morkEnv* ev, mork_pos inPos)
|
||||
// Changed the current write position in spool's buffer to inPos.
|
||||
// For example, to start writing the spool from scratch, use inPos==0.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
// write inSize bytes of inBuf to current position inside spool's buffer
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkSpoolSink::PutString(morkEnv* ev, const char* inString)
|
||||
// call Write() with inBuf=inString and inSize=strlen(inString),
|
||||
// unless inString is null, in which case we then do nothing at all.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
169
mozilla/db/mork/src/morkSink.h
Normal file
169
mozilla/db/mork/src/morkSink.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKSINK_
|
||||
#define _MORKSINK_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*| morkSink is intended to be a very cheap buffered i/o sink which
|
||||
**| writes to bufs and other strings a single byte at a time. The
|
||||
**| basic idea is that writing a single byte has a very cheap average
|
||||
**| cost, because a polymophic function call need only occur when the
|
||||
**| space between At and End is exhausted. The rest of the time a
|
||||
**| very cheap inline method will write a byte, and then bump a pointer.
|
||||
**|
|
||||
**|| At: the current position in some sequence of bytes at which to
|
||||
**| write the next byte put into the sink. Presumably At points into
|
||||
**| the private storage of some space which is not yet filled (except
|
||||
**| when At reaches End, and the overflow must then spill). Note both
|
||||
**| At and End are zeroed in the destructor to help show that a sink
|
||||
**| is no longer usable; this is safe because At==End causes the case
|
||||
**| where SpillPutc() is called to handled an exhausted buffer space.
|
||||
**|
|
||||
**|| End: an address one byte past the last byte which can be written
|
||||
**| without needing to make a buffer larger than previously. When At
|
||||
**| and End are equal, this means there is no space to write a byte,
|
||||
**| and that some underlying buffer space must be grown before another
|
||||
**| byte can be written. Note At must always be less than or equal to
|
||||
**| End, and otherwise an important invariant has failed severely.
|
||||
**|
|
||||
**|| Buf: this original class slot has been commented out in the new
|
||||
**| and more abstract version of this sink class, but the general idea
|
||||
**| behind this slot should be explained to help design subclasses.
|
||||
**| Each subclass should provide space into which At and End can point,
|
||||
**| where End is beyond the last writable byte, and At is less than or
|
||||
**| equal to this point inside the same buffer. With some kinds of
|
||||
**| medium, such as writing to an instance of morkBlob, it is feasible
|
||||
**| to point directly into the final resting place for all the content
|
||||
**| written to the medium. Other mediums such as files, which write
|
||||
**| only through function calls, will typically need a local buffer
|
||||
**| to efficiently accumulate many bytes between such function calls.
|
||||
**|
|
||||
**|| FlushSink: this flush method should move any buffered content to
|
||||
**| it's final destination. For example, for buffered writes to a
|
||||
**| string medium, where string methods are function calls and not just
|
||||
**| inline macros, it is faster to accumulate many bytes in a small
|
||||
**| local buffer and then move these en masse later in a single call.
|
||||
**|
|
||||
**|| SpillPutc: when At is greater than or equal to End, this means an
|
||||
**| underlying buffer has become full, so the buffer must be flushed
|
||||
**| before a new byte can be written. The intention is that SpillPutc()
|
||||
**| will be equivalent to calling FlushSink() followed by another call
|
||||
**| to Putc(), where the flush is expected to make At less then End once
|
||||
**| again. Except that FlushSink() need not make the underlying buffer
|
||||
**| any larger, and SpillPutc() typically must make room for more bytes.
|
||||
**| Note subclasses might want to guard against the case that both At
|
||||
**| and End are null, which happens when a sink is destroyed, which sets
|
||||
**| both these pointers to null as an indication the sink is disabled.
|
||||
|*/
|
||||
class morkSink {
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public sink virtual methods
|
||||
|
||||
virtual void FlushSink(morkEnv* ev) = 0;
|
||||
virtual void SpillPutc(morkEnv* ev, int c) = 0;
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // member variables
|
||||
|
||||
mork_u1* mSink_At; // pointer into mSink_Buf
|
||||
mork_u1* mSink_End; // one byte past last content byte
|
||||
|
||||
// define morkSink_kBufSize 256 /* small enough to go on stack */
|
||||
|
||||
// mork_u1 mSink_Buf[ morkSink_kBufSize + 4 ];
|
||||
// want plus one for any needed end null byte; use plus 4 for alignment
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkSink methods
|
||||
|
||||
virtual ~morkSink(); // zero both At and End; virtual for subclasses
|
||||
morkSink() { } // does nothing; subclasses must set At and End suitably
|
||||
|
||||
void Putc(morkEnv* ev, int c)
|
||||
{
|
||||
if ( mSink_At < mSink_End )
|
||||
*mSink_At++ = (mork_u1) c;
|
||||
else
|
||||
this->SpillPutc(ev, c);
|
||||
}
|
||||
};
|
||||
|
||||
/*| morkSpoolSink: an output sink that efficiently writes individual bytes
|
||||
**| or entire byte sequences to a spool instance, which grows as needed by
|
||||
**| using the heap instance in the spool to grow the internal buffer.
|
||||
**|
|
||||
**|| Note we do not "own" the spool referenced by mSpoolSink_Spool, and
|
||||
**| the lifetime of the spool is expected to equal or exceed that of this
|
||||
**| sink by some external means. Typical usage might involve keeping an
|
||||
**| instance of morkSpool and an instance of morkSpoolSink in the same
|
||||
**| owning parent object, which uses the sink with the associated spool.
|
||||
|*/
|
||||
class morkSpoolSink : public morkSink { // for buffered i/o to a morkSpool
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public sink virtual methods
|
||||
|
||||
virtual void FlushSink(morkEnv* ev); // probably does nothing
|
||||
virtual void SpillPutc(morkEnv* ev, int c); // grow spool and write byte
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // member variables
|
||||
morkSpool* mSpoolSink_Spool; // destination medium for written bytes
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkSink methods
|
||||
|
||||
virtual ~morkSpoolSink();
|
||||
// Zero all slots to show this sink is disabled, but destroy no memory.
|
||||
// Note it is typically unnecessary to flush this spool sink, since all
|
||||
// content is written directly to the spool without any buffering.
|
||||
|
||||
morkSpoolSink(morkEnv* ev, morkSpool* ioSpool);
|
||||
// After installing the spool, calls Seek(ev, 0) to prepare for writing.
|
||||
|
||||
// ----- All boolean return values below are equal to ev->Good(): -----
|
||||
|
||||
mork_bool Seek(morkEnv* ev, mork_pos inPos);
|
||||
// Changed the current write position in spool's buffer to inPos.
|
||||
// For example, to start writing the spool from scratch, use inPos==0.
|
||||
|
||||
mork_bool Write(morkEnv* ev, const void* inBuf, mork_size inSize);
|
||||
// write inSize bytes of inBuf to current position inside spool's buffer
|
||||
|
||||
mork_bool PutBuf(morkEnv* ev, const morkBuf& inBuffer)
|
||||
{ return this->Write(ev, inBuffer.mBuf_Body, inBuffer.mBuf_Fill); }
|
||||
|
||||
mork_bool PutString(morkEnv* ev, const char* inString);
|
||||
// call Write() with inBuf=inString and inSize=strlen(inString),
|
||||
// unless inString is null, in which case we then do nothing at all.
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKSINK_ */
|
||||
141
mozilla/db/mork/src/morkSpace.cpp
Normal file
141
mozilla/db/mork/src/morkSpace.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#include "morkSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkSpace::CloseMorkNode(morkEnv* ev) // CloseSpace() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseSpace(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkSpace::~morkSpace() // assert CloseSpace() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mSpace_Scope==0);
|
||||
MORK_ASSERT(mSpace_Store==0);
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
//morkSpace::morkSpace(morkEnv* ev, const morkUsage& inUsage,
|
||||
// nsIMdbHeap* ioNodeHeap, const morkMapForm& inForm,
|
||||
// nsIMdbHeap* ioSlotHeap)
|
||||
//: morkNode(ev, inUsage, ioNodeHeap)
|
||||
//, mSpace_Map(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap)
|
||||
//{
|
||||
// ev->StubMethodOnlyError();
|
||||
//}
|
||||
|
||||
/*public non-poly*/
|
||||
morkSpace::morkSpace(morkEnv* ev,
|
||||
const morkUsage& inUsage, mork_scope inScope, morkStore* ioStore,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
, mSpace_Store( 0 )
|
||||
, mSpace_Scope( inScope )
|
||||
, mSpace_DoAutoIDs( morkBool_kFalse )
|
||||
, mSpace_HaveDoneAutoIDs( morkBool_kFalse )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioStore )
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mSpace_Store);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kSpace;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkSpace::CloseSpace(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mSpace_Store);
|
||||
mSpace_Scope = 0;
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkSpace::NonAsciiSpaceScopeName(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("mSpace_Scope > 0x7F");
|
||||
}
|
||||
|
||||
morkPool* morkSpace::GetSpaceStorePool() const
|
||||
{
|
||||
return &mSpace_Store->mStore_Pool;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
103
mozilla/db/mork/src/morkSpace.h
Normal file
103
mozilla/db/mork/src/morkSpace.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#define _MORKSPACE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkSpace_kInitialSpaceSlots /*i*/ 1024 /* default */
|
||||
#define morkDerived_kSpace /*i*/ 0x5370 /* ascii 'Sp' */
|
||||
|
||||
/*| morkSpace:
|
||||
|*/
|
||||
class morkSpace : public morkNode { //
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkStore* mSpace_Store; // weak ref to containing store
|
||||
|
||||
mork_scope mSpace_Scope; // the scope for this space
|
||||
|
||||
mork_bool mSpace_DoAutoIDs; // whether db should assign member IDs
|
||||
mork_bool mSpace_HaveDoneAutoIDs; // whether actually auto assigned IDs
|
||||
mork_u1 mSpace_Pad[ 2 ]; // pad to u4 alignment
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseSpace() only if open
|
||||
virtual ~morkSpace(); // assert that CloseSpace() executed earlier
|
||||
|
||||
public: // morkMap construction & destruction
|
||||
//morkSpace(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioNodeHeap,
|
||||
// const morkMapForm& inForm, nsIMdbHeap* ioSlotHeap);
|
||||
|
||||
morkSpace(morkEnv* ev, const morkUsage& inUsage,mork_scope inScope,
|
||||
morkStore* ioStore, nsIMdbHeap* ioNodeHeap, nsIMdbHeap* ioSlotHeap);
|
||||
void CloseSpace(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsSpace() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kSpace; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // other space methods
|
||||
|
||||
static void NonAsciiSpaceScopeName(morkEnv* ev);
|
||||
|
||||
morkPool* GetSpaceStorePool() const;
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakSpace(morkSpace* me,
|
||||
morkEnv* ev, morkSpace** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongSpace(morkSpace* me,
|
||||
morkEnv* ev, morkSpace** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKSPACE_ */
|
||||
818
mozilla/db/mork/src/morkStore.cpp
Normal file
818
mozilla/db/mork/src/morkStore.cpp
Normal file
@@ -0,0 +1,818 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBLOB_
|
||||
#include "morkBlob.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINSTORE_
|
||||
#include "orkinStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFACTORY_
|
||||
#include "morkFactory.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#include "morkNodeMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKBUILDER_
|
||||
#include "morkBuilder.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTREAM_
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPORTTABLECURSOR_
|
||||
#include "morkPortTableCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkPort::CloseMorkNode(morkEnv* ev) // ClosePort() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->ClosePort(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkPort::~morkPort() // assert ClosePort() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
MORK_ASSERT(mPort_Factory==0);
|
||||
MORK_ASSERT(mPort_Heap==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkPort::morkPort(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioNodeHeap, // the heap (if any) for this node instance
|
||||
morkFactory* inFactory, // the factory for this
|
||||
nsIMdbHeap* ioPortHeap // the heap to hold all content in the port
|
||||
)
|
||||
: morkObject(ev, inUsage, ioNodeHeap, (morkHandle*) 0)
|
||||
, mPort_Env( ev )
|
||||
, mPort_Factory( 0 )
|
||||
, mPort_Heap( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( inFactory && ioPortHeap )
|
||||
{
|
||||
morkFactory::SlotWeakFactory(inFactory, ev, &mPort_Factory);
|
||||
nsIMdbHeap_SlotStrongHeap(ioPortHeap, ev, &mPort_Heap);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kPort;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkPort::ClosePort(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkFactory::SlotWeakFactory((morkFactory*) 0, ev, &mPort_Factory);
|
||||
nsIMdbHeap_SlotStrongHeap((nsIMdbHeap*) 0, ev, &mPort_Heap);
|
||||
this->CloseObject(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkStore::CloseMorkNode(morkEnv* ev) // ClosePort() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseStore(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkStore::~morkStore() // assert CloseStore() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
MORK_ASSERT(mStore_File==0);
|
||||
MORK_ASSERT(mStore_InStream==0);
|
||||
MORK_ASSERT(mStore_OutStream==0);
|
||||
MORK_ASSERT(mStore_Builder==0);
|
||||
MORK_ASSERT(mStore_OidAtomSpace==0);
|
||||
MORK_ASSERT(mStore_GroundAtomSpace==0);
|
||||
MORK_ASSERT(mStore_GroundColumnSpace==0);
|
||||
MORK_ASSERT(mStore_RowSpaces.IsShutNode());
|
||||
MORK_ASSERT(mStore_AtomSpaces.IsShutNode());
|
||||
MORK_ASSERT(mStore_Pool.IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkStore::morkStore(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioNodeHeap, // the heap (if any) for this node instance
|
||||
morkFactory* inFactory, // the factory for this
|
||||
nsIMdbHeap* ioPortHeap // the heap to hold all content in the port
|
||||
)
|
||||
: morkPort(ev, inUsage, ioNodeHeap, inFactory, ioPortHeap)
|
||||
, mStore_File( 0 )
|
||||
, mStore_InStream( 0 )
|
||||
, mStore_OutStream( 0 )
|
||||
, mStore_Builder( 0 )
|
||||
, mStore_OidAtomSpace( 0 )
|
||||
, mStore_GroundAtomSpace( 0 )
|
||||
, mStore_GroundColumnSpace( 0 )
|
||||
, mStore_RowSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_AtomSpaces(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
, mStore_Pool(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioPortHeap)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mNode_Derived = morkDerived_kStore;
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_CharsetToken = this->StringToToken(ev, "charset");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_AtomScopeToken = this->StringToToken(ev, "atomScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_RowScopeToken = this->StringToToken(ev, "rowScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_TableScopeToken = this->StringToToken(ev, "tableScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_ColumnScopeToken = this->StringToToken(ev, "columnScope");
|
||||
|
||||
if ( ev->Good() )
|
||||
mStore_TableKindToken = this->StringToToken(ev, "tableKind");
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkStore::CloseStore(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkFile* file = mStore_File;
|
||||
if ( file && file->IsOpenNode() )
|
||||
file->CloseMorkNode(ev);
|
||||
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mStore_OidAtomSpace);
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mStore_GroundAtomSpace);
|
||||
morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace*) 0, ev,
|
||||
&mStore_GroundColumnSpace);
|
||||
mStore_RowSpaces.CloseMorkNode(ev);
|
||||
mStore_AtomSpaces.CloseMorkNode(ev);
|
||||
morkBuilder::SlotStrongBuilder((morkBuilder*) 0, ev, &mStore_Builder);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
|
||||
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_InStream);
|
||||
morkStream::SlotStrongStream((morkStream*) 0, ev, &mStore_OutStream);
|
||||
|
||||
mStore_Pool.CloseMorkNode(ev);
|
||||
this->ClosePort(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
void
|
||||
morkStore::RenumberAllCollectableContent(morkEnv* ev)
|
||||
{
|
||||
// do nothing currently
|
||||
}
|
||||
|
||||
nsIMdbStore*
|
||||
morkStore::AcquireStoreHandle(morkEnv* ev)
|
||||
{
|
||||
nsIMdbStore* outStore = 0;
|
||||
orkinStore* s = (orkinStore*) mObject_Handle;
|
||||
if ( s ) // have an old handle?
|
||||
s->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
s = orkinStore::MakeStore(ev, this);
|
||||
mObject_Handle = s;
|
||||
}
|
||||
if ( s )
|
||||
outStore = s;
|
||||
return outStore;
|
||||
}
|
||||
|
||||
|
||||
morkMaxBookAtom*
|
||||
morkStore::StageYarnAsBookAtom(morkEnv* ev, const mdbYarn* inYarn,
|
||||
morkAtomSpace* ioSpace)
|
||||
{
|
||||
if ( inYarn && inYarn->mYarn_Buf )
|
||||
{
|
||||
mork_size length = inYarn->mYarn_Fill;
|
||||
if ( length <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
morkBuf buf(inYarn->mYarn_Buf, length);
|
||||
mork_aid dummyAid = 1;
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, buf,
|
||||
inYarn->mYarn_Form, ioSpace, dummyAid);
|
||||
return &mStore_BookAtom;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (morkMaxBookAtom*) 0;
|
||||
}
|
||||
|
||||
morkMaxBookAtom*
|
||||
morkStore::StageStringAsBookAtom(morkEnv* ev, const char* inString,
|
||||
mork_cscode inForm, morkAtomSpace* ioSpace)
|
||||
// StageStringAsBookAtom() returns &mStore_BookAtom if inString is small
|
||||
// enough, such that strlen(inString) < morkBookAtom_kMaxBodySize. And
|
||||
// content inside mStore_BookAtom will be the valid atom format for
|
||||
// inString. This method is the standard way to stage a string as an
|
||||
// atom for searching or adding new atoms into an atom space hash table.
|
||||
{
|
||||
if ( inString )
|
||||
{
|
||||
mork_size length = MORK_STRLEN(inString);
|
||||
if ( length <= morkBookAtom_kMaxBodySize )
|
||||
{
|
||||
morkBuf buf(inString, length);
|
||||
mork_aid dummyAid = 1;
|
||||
mStore_BookAtom.InitMaxBookAtom(ev, buf, inForm, ioSpace, dummyAid);
|
||||
return &mStore_BookAtom;
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return (morkMaxBookAtom*) 0;
|
||||
}
|
||||
|
||||
morkAtomSpace* morkStore::LazyGetOidAtomSpace(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_OidAtomSpace )
|
||||
{
|
||||
}
|
||||
return mStore_OidAtomSpace;
|
||||
}
|
||||
|
||||
morkAtomSpace* morkStore::LazyGetGroundAtomSpace(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_GroundAtomSpace )
|
||||
{
|
||||
mork_scope atomScope = morkStore_kGroundAtomSpace;
|
||||
nsIMdbHeap* heap = mPort_Heap;
|
||||
morkAtomSpace* space = new(*heap, ev)
|
||||
morkAtomSpace(ev, morkUsage::kHeap, atomScope, this, heap, heap);
|
||||
|
||||
if ( space ) // successful space creation?
|
||||
{
|
||||
mStore_GroundAtomSpace = space; // transfer strong ref to this slot
|
||||
mStore_AtomSpaces.AddAtomSpace(ev, space);
|
||||
}
|
||||
}
|
||||
return mStore_GroundAtomSpace;
|
||||
}
|
||||
|
||||
morkAtomSpace* morkStore::LazyGetGroundColumnSpace(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_GroundColumnSpace )
|
||||
{
|
||||
mork_scope atomScope = morkStore_kGroundColumnSpace;
|
||||
nsIMdbHeap* heap = mPort_Heap;
|
||||
morkAtomSpace* space = new(*heap, ev)
|
||||
morkAtomSpace(ev, morkUsage::kHeap, atomScope, this, heap, heap);
|
||||
|
||||
if ( space ) // successful space creation?
|
||||
{
|
||||
mStore_GroundColumnSpace = space; // transfer strong ref to this slot
|
||||
mStore_AtomSpaces.AddAtomSpace(ev, space);
|
||||
}
|
||||
}
|
||||
return mStore_GroundColumnSpace;
|
||||
}
|
||||
|
||||
morkStream* morkStore::LazyGetInStream(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_InStream )
|
||||
{
|
||||
morkFile* file = mStore_File;
|
||||
if ( file )
|
||||
{
|
||||
morkStream* stream = new(*mPort_Heap, ev)
|
||||
morkStream(ev, morkUsage::kHeap, mPort_Heap, file,
|
||||
morkStore_kStreamBufSize, /*frozen*/ morkBool_kTrue);
|
||||
if ( stream )
|
||||
{
|
||||
mStore_InStream = stream; // transfer strong ref to this slot
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilStoreFileError(ev);
|
||||
}
|
||||
return mStore_InStream;
|
||||
}
|
||||
|
||||
morkStream* morkStore::LazyGetOutStream(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_OutStream )
|
||||
{
|
||||
morkFile* file = mStore_File;
|
||||
if ( file )
|
||||
{
|
||||
morkStream* stream = new(*mPort_Heap, ev)
|
||||
morkStream(ev, morkUsage::kHeap, mPort_Heap, file,
|
||||
morkStore_kStreamBufSize, /*frozen*/ morkBool_kFalse);
|
||||
if ( stream )
|
||||
{
|
||||
mStore_InStream = stream; // transfer strong ref to this slot
|
||||
}
|
||||
}
|
||||
else
|
||||
this->NilStoreFileError(ev);
|
||||
}
|
||||
return mStore_OutStream;
|
||||
}
|
||||
|
||||
morkBuilder* morkStore::LazyGetBuilder(morkEnv* ev)
|
||||
{
|
||||
if ( !mStore_Builder )
|
||||
{
|
||||
morkStream* stream = this->LazyGetInStream(ev);
|
||||
if ( stream )
|
||||
{
|
||||
nsIMdbHeap* heap = mPort_Heap;
|
||||
morkBuilder* builder = new(*heap, ev)
|
||||
morkBuilder(ev, morkUsage::kHeap, heap, stream,
|
||||
morkBuilder_kDefaultBytesPerParseSegment, heap, this);
|
||||
if ( builder )
|
||||
{
|
||||
mStore_Builder = builder; // transfer strong ref to this slot
|
||||
}
|
||||
}
|
||||
}
|
||||
return mStore_Builder;
|
||||
}
|
||||
|
||||
morkRowSpace*
|
||||
morkStore::LazyGetRowSpace(morkEnv* ev, mdb_scope inRowScope)
|
||||
{
|
||||
morkRowSpace* outSpace = mStore_RowSpaces.GetRowSpace(ev, inRowScope);
|
||||
if ( !outSpace && ev->Good() ) // try to make new space?
|
||||
{
|
||||
nsIMdbHeap* heap = mPort_Heap;
|
||||
outSpace = new(*heap, ev)
|
||||
morkRowSpace(ev, morkUsage::kHeap, inRowScope, this, heap, heap);
|
||||
|
||||
if ( outSpace ) // successful space creation?
|
||||
{
|
||||
// note adding to node map creates it's own strong ref...
|
||||
if ( mStore_RowSpaces.AddRowSpace(ev, outSpace) )
|
||||
outSpace->CutStrongRef(ev); // ...so we can drop our strong ref
|
||||
}
|
||||
}
|
||||
return outSpace;
|
||||
}
|
||||
|
||||
morkAtomSpace*
|
||||
morkStore::LazyGetAtomSpace(morkEnv* ev, mdb_scope inAtomScope)
|
||||
{
|
||||
morkAtomSpace* outSpace = mStore_AtomSpaces.GetAtomSpace(ev, inAtomScope);
|
||||
if ( !outSpace && ev->Good() ) // try to make new space?
|
||||
{
|
||||
if ( inAtomScope == morkStore_kGroundAtomSpace )
|
||||
outSpace = this->LazyGetGroundAtomSpace(ev);
|
||||
|
||||
else if ( inAtomScope == morkStore_kGroundColumnSpace )
|
||||
outSpace = this->LazyGetGroundColumnSpace(ev);
|
||||
else
|
||||
{
|
||||
nsIMdbHeap* heap = mPort_Heap;
|
||||
outSpace = new(*heap, ev)
|
||||
morkAtomSpace(ev, morkUsage::kHeap, inAtomScope, this, heap, heap);
|
||||
|
||||
if ( outSpace ) // successful space creation?
|
||||
{
|
||||
// note adding to node map creates it's own strong ref...
|
||||
if ( mStore_AtomSpaces.AddAtomSpace(ev, outSpace) )
|
||||
outSpace->CutStrongRef(ev); // ...so we can drop our strong ref
|
||||
}
|
||||
}
|
||||
}
|
||||
return outSpace;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkStore::NonStoreTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkStore");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkStore::NilStoreFileError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mStore_File");
|
||||
}
|
||||
|
||||
|
||||
mork_bool
|
||||
morkStore::OpenStoreFile(morkEnv* ev, mork_bool inFrozen,
|
||||
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
|
||||
{
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkFile* file = morkFile::OpenOldFile(ev, mPort_Heap,
|
||||
inFilePath, inFrozen);
|
||||
if ( file )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
morkFile::SlotStrongFile(file, ev, &mStore_File);
|
||||
else
|
||||
file->CutStrongRef(ev);
|
||||
}
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkStore::CreateStoreFile(morkEnv* ev,
|
||||
const char* inFilePath, const mdbOpenPolicy* inOpenPolicy)
|
||||
{
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStore_File);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkFile* file = morkFile::CreateNewFile(ev, mPort_Heap,
|
||||
inFilePath);
|
||||
if ( file )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
morkFile::SlotStrongFile(file, ev, &mStore_File);
|
||||
else
|
||||
file->CutStrongRef(ev);
|
||||
}
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkAtom*
|
||||
morkStore::YarnToAtom(morkEnv* ev, const mdbYarn* inYarn)
|
||||
{
|
||||
morkAtom* outAtom = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkAtomSpace* groundSpace = this->LazyGetGroundAtomSpace(ev);
|
||||
if ( groundSpace )
|
||||
{
|
||||
morkMaxBookAtom* keyAtom =
|
||||
this->StageYarnAsBookAtom(ev, inYarn, groundSpace);
|
||||
|
||||
if ( keyAtom )
|
||||
{
|
||||
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
|
||||
outAtom = map->GetAtom(ev, keyAtom);
|
||||
if ( !outAtom )
|
||||
outAtom = groundSpace->MakeBookAtomCopy(ev, *keyAtom);
|
||||
}
|
||||
else if ( ev->Good() )
|
||||
{
|
||||
morkBuf buf(inYarn->mYarn_Buf, inYarn->mYarn_Fill);
|
||||
outAtom = mStore_Pool.NewAnonAtom(ev, buf, inYarn->mYarn_Form);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outAtom;
|
||||
}
|
||||
|
||||
// mork_bool
|
||||
// morkStore::CutBookAtom(morkEnv* ev, morkBookAtom* ioAtom)
|
||||
// {
|
||||
// }
|
||||
|
||||
void
|
||||
morkStore::TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName)
|
||||
{
|
||||
if ( inToken > morkAtomSpace_kMaxSevenBitAid )
|
||||
{
|
||||
morkBookAtom* atom = 0;
|
||||
morkAtomSpace* space = mStore_GroundColumnSpace;
|
||||
if ( space )
|
||||
atom = space->mAtomSpace_AtomAids.GetAid(ev, (mork_aid) inToken);
|
||||
|
||||
atom->GetYarn(outTokenName); // note this is safe even when atom==nil
|
||||
}
|
||||
else // token is an "immediate" single byte string representation?
|
||||
{
|
||||
mdbYarn* y = outTokenName;
|
||||
if ( y->mYarn_Buf && y->mYarn_Size ) // any space in yarn at all?
|
||||
{
|
||||
mork_u1* buf = (mork_u1*) y->mYarn_Buf; // for byte arithmetic
|
||||
buf[ 0 ] = (mork_u1) inToken; // write the single byte
|
||||
y->mYarn_Fill = 1;
|
||||
y->mYarn_More = 0;
|
||||
}
|
||||
else // just record we could not write the single byte
|
||||
{
|
||||
y->mYarn_More = 1;
|
||||
y->mYarn_Fill = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::StringToToken(morkEnv* ev, const char* inTokenName)
|
||||
{
|
||||
mork_token outToken = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
const mork_u1* s = (const mork_u1*) inTokenName;
|
||||
mork_bool nonAscii = ( *s > 0x7F );
|
||||
if ( nonAscii || ( *s && s[ 1 ] ) ) // more than one byte?
|
||||
{
|
||||
mork_cscode form = 0; // default charset
|
||||
morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev);
|
||||
if ( groundSpace )
|
||||
{
|
||||
morkMaxBookAtom* keyAtom =
|
||||
this->StageStringAsBookAtom(ev, inTokenName, form, groundSpace);
|
||||
if ( keyAtom )
|
||||
{
|
||||
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
|
||||
morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom);
|
||||
if ( bookAtom )
|
||||
outToken = bookAtom->mBookAtom_Id;
|
||||
else
|
||||
{
|
||||
bookAtom = groundSpace->MakeBookAtomCopy(ev, *keyAtom);
|
||||
if ( bookAtom )
|
||||
{
|
||||
outToken = bookAtom->mBookAtom_Id;
|
||||
bookAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // only a single byte in inTokenName string:
|
||||
outToken = *s;
|
||||
}
|
||||
|
||||
return outToken;
|
||||
}
|
||||
|
||||
mork_token
|
||||
morkStore::QueryToken(morkEnv* ev, const char* inTokenName)
|
||||
{
|
||||
mork_token outToken = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
const mork_u1* s = (const mork_u1*) inTokenName;
|
||||
mork_bool nonAscii = ( *s > 0x7F );
|
||||
if ( nonAscii || ( *s && s[ 1 ] ) ) // more than one byte?
|
||||
{
|
||||
mork_cscode form = 0; // default charset
|
||||
morkAtomSpace* groundSpace = this->LazyGetGroundColumnSpace(ev);
|
||||
if ( groundSpace )
|
||||
{
|
||||
morkMaxBookAtom* keyAtom =
|
||||
this->StageStringAsBookAtom(ev, inTokenName, form, groundSpace);
|
||||
if ( keyAtom )
|
||||
{
|
||||
morkAtomBodyMap* map = &groundSpace->mAtomSpace_AtomBodies;
|
||||
morkBookAtom* bookAtom = map->GetAtom(ev, keyAtom);
|
||||
if ( bookAtom )
|
||||
{
|
||||
outToken = bookAtom->mBookAtom_Id;
|
||||
bookAtom->MakeCellUseForever(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // only a single byte in inTokenName string:
|
||||
outToken = *s;
|
||||
}
|
||||
|
||||
return outToken;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkStore::HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount)
|
||||
{
|
||||
mork_bool outBool = morkBool_kFalse;
|
||||
|
||||
return outBool;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::GetTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount,
|
||||
mdb_bool* outMustBeUnique)
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
if ( rowSpace )
|
||||
{
|
||||
outTable = rowSpace->FindTableByKind(ev, inTableKind);
|
||||
if ( outTable )
|
||||
{
|
||||
if ( outTableCount )
|
||||
*outTableCount = outTable->GetRowCount();
|
||||
if ( outMustBeUnique )
|
||||
*outMustBeUnique = outTable->mTable_MustBeUnique;
|
||||
}
|
||||
}
|
||||
}
|
||||
return outTable;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::GetRow(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope);
|
||||
if ( rowSpace )
|
||||
{
|
||||
outRow = rowSpace->mRowSpace_Rows.GetOid(ev, inOid);
|
||||
}
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::GetTable(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope);
|
||||
if ( rowSpace )
|
||||
{
|
||||
outTable = rowSpace->FindTableByTid(ev, inOid->mOid_Id);
|
||||
}
|
||||
}
|
||||
return outTable;
|
||||
}
|
||||
|
||||
morkTable*
|
||||
morkStore::NewTable(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique)
|
||||
{
|
||||
morkTable* outTable = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
if ( rowSpace )
|
||||
outTable = rowSpace->NewTable(ev, inTableKind, inMustBeUnique);
|
||||
}
|
||||
return outTable;
|
||||
}
|
||||
|
||||
morkPortTableCursor*
|
||||
morkStore::GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind)
|
||||
{
|
||||
morkPortTableCursor* outCursor = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
nsIMdbHeap* heap = mPort_Heap;
|
||||
outCursor = new(*heap, ev)
|
||||
morkPortTableCursor(ev, morkUsage::kHeap, heap, this,
|
||||
inRowScope, inTableKind, heap);
|
||||
}
|
||||
return outCursor;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRowWithOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inOid->mOid_Scope);
|
||||
if ( rowSpace )
|
||||
outRow = rowSpace->NewRowWithOid(ev, inOid);
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkStore::NewRow(morkEnv* ev, mdb_scope inRowScope)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
morkRowSpace* rowSpace = this->LazyGetRowSpace(ev, inRowScope);
|
||||
if ( rowSpace )
|
||||
outRow = rowSpace->NewRow(ev);
|
||||
}
|
||||
return outRow;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
292
mozilla/db/mork/src/morkStore.h
Normal file
292
mozilla/db/mork/src/morkStore.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#define _MORKSTORE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#include "morkNodeMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kPort /*i*/ 0x7054 /* ascii 'pT' */
|
||||
|
||||
/*| morkPort:
|
||||
|*/
|
||||
class morkPort : public morkObject { // private mork port
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkHandle* mObject_Handle; // weak ref to handle for this object
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
morkEnv* mPort_Env; // non-refcounted env which created port
|
||||
morkFactory* mPort_Factory; // weak ref to suite factory
|
||||
nsIMdbHeap* mPort_Heap; // heap in which this port allocs objects
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // ClosePort() only if open
|
||||
virtual ~morkPort(); // assert that ClosePort() executed earlier
|
||||
|
||||
public: // morkPort construction & destruction
|
||||
morkPort(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioNodeHeap, // the heap (if any) for this node instance
|
||||
morkFactory* inFactory, // the factory for this
|
||||
nsIMdbHeap* ioPortHeap // the heap to hold all content in the port
|
||||
);
|
||||
void ClosePort(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkPort(const morkPort& other);
|
||||
morkPort& operator=(const morkPort& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsPort() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kPort; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // other port methods
|
||||
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakPort(morkPort* me,
|
||||
morkEnv* ev, morkPort** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongPort(morkPort* me,
|
||||
morkEnv* ev, morkPort** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
#define morkDerived_kStore /*i*/ 0x7354 /* ascii 'sT' */
|
||||
|
||||
/*| kGroundColumnSpace: we use the 'column space' as the default scope
|
||||
**| for grounding column name IDs, and this is also the default scope for
|
||||
**| all other explicitly tokenized strings.
|
||||
|*/
|
||||
#define morkStore_kGroundColumnSpace 'c' /* for mStore_GroundColumnSpace*/
|
||||
#define morkStore_kGroundAtomSpace 'a' /* for mStore_GroundAtomSpace*/
|
||||
#define morkStore_kStreamBufSize (8 * 1024) /* okay buffer size */
|
||||
|
||||
/*| morkStore:
|
||||
|*/
|
||||
class morkStore : public morkPort {
|
||||
|
||||
// public: // slots inherited from morkPort (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkEnv* mPort_Env; // non-refcounted env which created port
|
||||
// morkFactory* mPort_Factory; // weak ref to suite factory
|
||||
// nsIMdbHeap* mPort_Heap; // heap in which this port allocs objects
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
// mStore_OidAtomSpace might be unnecessary; I don't remember why I wanted it.
|
||||
morkAtomSpace* mStore_OidAtomSpace; // ground atom space for oids
|
||||
morkAtomSpace* mStore_GroundAtomSpace; // ground atom space for scopes
|
||||
morkAtomSpace* mStore_GroundColumnSpace; // ground column space for scopes
|
||||
|
||||
morkFile* mStore_File; // the file containing Mork text
|
||||
morkStream* mStore_InStream; // stream using file used by the builder
|
||||
morkBuilder* mStore_Builder; // to parse Mork text and build structures
|
||||
|
||||
morkStream* mStore_OutStream; // stream using file used by the writer
|
||||
|
||||
mork_column mStore_CharsetToken; // token for "charset"
|
||||
mork_column mStore_AtomScopeToken; // token for "atomScope"
|
||||
mork_column mStore_RowScopeToken; // token for "rowScope"
|
||||
mork_column mStore_TableScopeToken; // token for "tableScope"
|
||||
mork_column mStore_ColumnScopeToken; // token for "columnScope"
|
||||
mork_kind mStore_TableKindToken; // token for "tableKind"
|
||||
|
||||
morkRowSpaceMap mStore_RowSpaces; // maps mork_scope -> morkSpace
|
||||
morkAtomSpaceMap mStore_AtomSpaces; // maps mork_scope -> morkSpace
|
||||
|
||||
morkPool mStore_Pool;
|
||||
|
||||
// we alloc a max size book atom to reuse space for atom map key searches:
|
||||
morkMaxBookAtom mStore_BookAtom; // staging area for atom map searches
|
||||
|
||||
public: // building an atom inside mStore_BookAtom from a char* string
|
||||
|
||||
morkMaxBookAtom* StageYarnAsBookAtom(morkEnv* ev,
|
||||
const mdbYarn* inYarn, morkAtomSpace* ioSpace);
|
||||
|
||||
morkMaxBookAtom* StageStringAsBookAtom(morkEnv* ev,
|
||||
const char* inString, mork_cscode inForm, morkAtomSpace* ioSpace);
|
||||
// StageStringAsBookAtom() returns &mStore_BookAtom if inString is small
|
||||
// enough, such that strlen(inString) < morkBookAtom_kMaxBodySize. And
|
||||
// content inside mStore_BookAtom will be the valid atom format for
|
||||
// inString. This method is the standard way to stage a string as an
|
||||
// atom for searching or adding new atoms into an atom space hash table.
|
||||
|
||||
public: // lazy creation of members and nested row or atom spaces
|
||||
|
||||
morkAtomSpace* LazyGetOidAtomSpace(morkEnv* ev);
|
||||
morkAtomSpace* LazyGetGroundAtomSpace(morkEnv* ev);
|
||||
morkAtomSpace* LazyGetGroundColumnSpace(morkEnv* ev);
|
||||
|
||||
morkStream* LazyGetInStream(morkEnv* ev);
|
||||
morkBuilder* LazyGetBuilder(morkEnv* ev);
|
||||
|
||||
morkStream* LazyGetOutStream(morkEnv* ev);
|
||||
|
||||
morkRowSpace* LazyGetRowSpace(morkEnv* ev, mdb_scope inRowScope);
|
||||
morkAtomSpace* LazyGetAtomSpace(morkEnv* ev, mdb_scope inAtomScope);
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseStore() only if open
|
||||
virtual ~morkStore(); // assert that CloseStore() executed earlier
|
||||
|
||||
public: // morkStore construction & destruction
|
||||
morkStore(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioNodeHeap, // the heap (if any) for this node instance
|
||||
morkFactory* inFactory, // the factory for this
|
||||
nsIMdbHeap* ioPortHeap // the heap to hold all content in the port
|
||||
);
|
||||
void CloseStore(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkStore(const morkStore& other);
|
||||
morkStore& operator=(const morkStore& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsStore() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kStore; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonStoreTypeError(morkEnv* ev);
|
||||
static void NilStoreFileError(morkEnv* ev);
|
||||
|
||||
public: // store utilties
|
||||
|
||||
morkAtom* YarnToAtom(morkEnv* ev, const mdbYarn* inYarn);
|
||||
|
||||
public: // other store methods
|
||||
|
||||
void RenumberAllCollectableContent(morkEnv* ev);
|
||||
|
||||
nsIMdbStore* AcquireStoreHandle(morkEnv* ev); // mObject_Handle
|
||||
|
||||
morkPool* StorePool() { return &mStore_Pool; }
|
||||
|
||||
mork_bool OpenStoreFile(morkEnv* ev, // return value equals ev->Good()
|
||||
mork_bool inFrozen,
|
||||
const char* inFilePath,
|
||||
const mdbOpenPolicy* inOpenPolicy);
|
||||
|
||||
mork_bool CreateStoreFile(morkEnv* ev, // return value equals ev->Good()
|
||||
const char* inFilePath,
|
||||
const mdbOpenPolicy* inOpenPolicy);
|
||||
|
||||
// mork_bool CutBookAtom(morkEnv* ev, morkBookAtom* ioAtom);
|
||||
mork_token StringToToken(morkEnv* ev, const char* inTokenName);
|
||||
mork_token QueryToken(morkEnv* ev, const char* inTokenName);
|
||||
void TokenToString(morkEnv* ev, mdb_token inToken, mdbYarn* outTokenName);
|
||||
|
||||
mork_bool HasTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount);
|
||||
|
||||
morkTable* GetTableKind(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_count* outTableCount,
|
||||
mdb_bool* outMustBeUnique);
|
||||
|
||||
morkRow* GetRow(morkEnv* ev, const mdbOid* inOid);
|
||||
morkTable* GetTable(morkEnv* ev, const mdbOid* inOid);
|
||||
|
||||
morkTable* NewTable(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind, mdb_bool inMustBeUnique);
|
||||
|
||||
morkPortTableCursor* GetPortTableCursor(morkEnv* ev, mdb_scope inRowScope,
|
||||
mdb_kind inTableKind) ;
|
||||
|
||||
morkRow* NewRowWithOid(morkEnv* ev, const mdbOid* inOid);
|
||||
morkRow* NewRow(morkEnv* ev, mdb_scope inRowScope);
|
||||
|
||||
morkThumb* MakeCompressCommitThumb(morkEnv* ev, mork_bool inDoCollect);
|
||||
|
||||
public: // commit related methods
|
||||
|
||||
mork_bool MarkAllStoreContentDirty(morkEnv* ev);
|
||||
// MarkAllStoreContentDirty() visits every object in the store and marks
|
||||
// them dirty, including every table, row, cell, and atom. The return
|
||||
// equals ev->Good(), to show whether any error happened. This method is
|
||||
// intended for use in the beginning of a "compress commit" which writes
|
||||
// all store content, whether dirty or not. We dirty everything first so
|
||||
// that later iterations over content can mark things clean as they are
|
||||
// written, and organize the process of serialization so that objects are
|
||||
// written only at need (because of being dirty).
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakStore(morkStore* me,
|
||||
morkEnv* ev, morkStore** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongStore(morkStore* me,
|
||||
morkEnv* ev, morkStore** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKSTORE_ */
|
||||
859
mozilla/db/mork/src/morkStream.cpp
Normal file
859
mozilla/db/mork/src/morkStream.cpp
Normal file
@@ -0,0 +1,859 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTREAM_
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkStream::CloseMorkNode(morkEnv* ev) // CloseStream() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseStream(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkStream::~morkStream() // assert CloseStream() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mStream_ContentFile==0);
|
||||
MORK_ASSERT(mStream_Buf==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkStream::morkStream(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap,
|
||||
morkFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen)
|
||||
: morkFile(ev, inUsage, ioHeap, ioHeap)
|
||||
, mStream_At( 0 )
|
||||
, mStream_ReadEnd( 0 )
|
||||
, mStream_WriteEnd( 0 )
|
||||
|
||||
, mStream_ContentFile( 0 )
|
||||
|
||||
, mStream_Buf( 0 )
|
||||
, mStream_BufSize( 0 )
|
||||
, mStream_BufPos( 0 )
|
||||
, mStream_Dirty( morkBool_kFalse )
|
||||
, mStream_HitEof( morkBool_kFalse )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( inBufSize < morkStream_kMinBufSize )
|
||||
mStream_BufSize = inBufSize = morkStream_kMinBufSize;
|
||||
else if ( inBufSize > morkStream_kMaxBufSize )
|
||||
mStream_BufSize = inBufSize = morkStream_kMaxBufSize;
|
||||
|
||||
if ( ioContentFile && ioHeap )
|
||||
{
|
||||
if ( ioContentFile->FileFrozen() ) // forced to be readonly?
|
||||
inFrozen = morkBool_kTrue; // override the input value
|
||||
|
||||
morkFile::SlotStrongFile(ioContentFile, ev, &mStream_ContentFile);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mork_u1* buf = 0;
|
||||
ioHeap->Alloc(ev->AsMdbEnv(), inBufSize, (void**) &buf);
|
||||
if ( buf )
|
||||
{
|
||||
mStream_At = mStream_Buf = buf;
|
||||
|
||||
if ( !inFrozen )
|
||||
{
|
||||
// physical buffer end never moves:
|
||||
mStream_WriteEnd = buf + inBufSize;
|
||||
}
|
||||
else
|
||||
mStream_WriteEnd = 0; // no writing is allowed
|
||||
|
||||
if ( inFrozen )
|
||||
{
|
||||
// logical buffer end starts at Buf with no content:
|
||||
mStream_ReadEnd = buf;
|
||||
this->SetFileFrozen(inFrozen);
|
||||
}
|
||||
else
|
||||
mStream_ReadEnd = 0; // no reading is allowed
|
||||
|
||||
this->SetFileActive(morkBool_kTrue);
|
||||
this->SetFileIoOpen(morkBool_kTrue);
|
||||
}
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kStream;
|
||||
}
|
||||
}
|
||||
else ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkStream::CloseStream(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mStream_ContentFile);
|
||||
nsIMdbHeap* heap = mFile_SlotHeap;
|
||||
mork_u1* buf = mStream_Buf;
|
||||
mStream_Buf = 0;
|
||||
|
||||
if ( heap && buf )
|
||||
heap->Free(ev->AsMdbEnv(), buf);
|
||||
|
||||
this->CloseFile(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
#define morkStream_kSpacesPerIndent 1 /* one space per indent */
|
||||
#define morkStream_kMaxIndentDepth 70 /* max indent of 70 space bytes */
|
||||
static const char* morkStream_kSpaces // next line to ease length perception
|
||||
= " ";
|
||||
// 123456789_123456789_123456789_123456789_123456789_123456789_123456789_
|
||||
// morkStream_kSpaces above must contain (at least) 70 spaces (ASCII 0x20)
|
||||
|
||||
mork_size
|
||||
morkStream::PutIndent(morkEnv* ev, mork_count inDepth)
|
||||
// PutIndent() puts a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth)
|
||||
// PutByteThenIndent() puts the byte, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
if ( inDepth > morkStream_kMaxIndentDepth )
|
||||
inDepth = morkStream_kMaxIndentDepth;
|
||||
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutStringThenIndent(morkEnv* ev,
|
||||
const char* inString, mork_count inDepth)
|
||||
// PutStringThenIndent() puts the string, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
{
|
||||
mork_size outLength = 0;
|
||||
|
||||
if ( inDepth > morkStream_kMaxIndentDepth )
|
||||
inDepth = morkStream_kMaxIndentDepth;
|
||||
|
||||
if ( inString )
|
||||
{
|
||||
mork_size length = MORK_STRLEN(inString);
|
||||
if ( length && ev->Good() ) // any bytes to write?
|
||||
this->Write(ev, inString, length);
|
||||
}
|
||||
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outLength = inDepth;
|
||||
if ( inDepth )
|
||||
this->Write(ev, morkStream_kSpaces, inDepth);
|
||||
}
|
||||
}
|
||||
return outLength;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutString(morkEnv* ev, const char* inString)
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, outSize);
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutStringThenNewline(morkEnv* ev, const char* inString)
|
||||
// PutStringThenNewline() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, outSize);
|
||||
if ( ev->Good() )
|
||||
outSize += this->PutLineBreak(ev);
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString)
|
||||
// PutStringThenNewlineThenSpace() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 0;
|
||||
if ( inString )
|
||||
{
|
||||
outSize = MORK_STRLEN(inString);
|
||||
if ( outSize && ev->Good() ) // any bytes to write?
|
||||
{
|
||||
this->Write(ev, inString, outSize);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outSize += this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Putc(ev, ' ');
|
||||
++outSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutByteThenNewline(morkEnv* ev, int inByte)
|
||||
// PutByteThenNewline() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 1; // one for the following byte
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
outSize += this->PutLineBreak(ev);
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutByteThenNewlineThenSpace(morkEnv* ev, int inByte)
|
||||
// PutByteThenNewlineThenSpace() returns total number of bytes written.
|
||||
{
|
||||
mork_size outSize = 1; // one for the following byte
|
||||
this->Putc(ev, inByte);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
outSize += this->PutLineBreak(ev);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
this->Putc(ev, ' ');
|
||||
++outSize;
|
||||
}
|
||||
}
|
||||
return outSize;
|
||||
}
|
||||
|
||||
mork_size
|
||||
morkStream::PutLineBreak(morkEnv* ev)
|
||||
{
|
||||
#ifdef MORK_MAC
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
return 1;
|
||||
|
||||
#else
|
||||
# if defined(MORK_WIN) || defined(MORK_OS2)
|
||||
|
||||
this->Putc(ev, mork_kCR);
|
||||
this->Putc(ev, mork_kLF);
|
||||
return 2;
|
||||
|
||||
# else
|
||||
# ifdef MORK_UNIX
|
||||
|
||||
this->Putc(ev, mork_kLF);
|
||||
return 1;
|
||||
|
||||
# endif /* MORK_UNIX */
|
||||
# endif /* MORK_WIN */
|
||||
#endif /* MORK_MAC */
|
||||
}
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// public: // virtual morkFile methods
|
||||
|
||||
|
||||
/*public virtual*/ void
|
||||
morkStream::BecomeTrunk(morkEnv* ev)
|
||||
// If this file is a file version branch created by calling AcquireBud(),
|
||||
// BecomeTrunk() causes this file's content to replace the original
|
||||
// file's content, typically by assuming the original file's identity.
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
|
||||
/*public virtual*/ morkFile*
|
||||
morkStream::AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap)
|
||||
// AcquireBud() starts a new "branch" version of the file, empty of content,
|
||||
// so that a new version of the file can be written. This new file
|
||||
// can later be told to BecomeTrunk() the original file, so the branch
|
||||
// created by budding the file will replace the original file. Some
|
||||
// file subclasses might initially take the unsafe but expedient
|
||||
// approach of simply truncating this file down to zero length, and
|
||||
// then returning the same morkFile pointer as this, with an extra
|
||||
// reference count increment. Note that the caller of AcquireBud() is
|
||||
// expected to eventually call CutStrongRef() on the returned file
|
||||
// in order to release the strong reference. High quality versions
|
||||
// of morkFile subclasses will create entirely new files which later
|
||||
// are renamed to become the old file, so that better transactional
|
||||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
{
|
||||
morkFile* outFile = 0;
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenAndActiveFile() && file )
|
||||
{
|
||||
// figure out how this interacts with buffering and mStream_WriteEnd:
|
||||
ev->StubMethodOnlyError();
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outFile;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
morkStream::Length(morkEnv* ev) const // eof
|
||||
{
|
||||
mork_pos outPos = 0;
|
||||
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenAndActiveFile() && file )
|
||||
{
|
||||
mork_pos contentEof = file->Length(ev);
|
||||
|
||||
if ( mStream_WriteEnd ) // this stream supports writing?
|
||||
{
|
||||
// the local buffer might have buffered content past content eof
|
||||
if ( ev->Good() ) // no error happened during Length() above?
|
||||
{
|
||||
mork_u1* at = mStream_At;
|
||||
mork_u1* buf = mStream_Buf;
|
||||
if ( at >= buf ) // expected cursor order?
|
||||
{
|
||||
mork_pos localContent = mStream_BufPos + (at - buf);
|
||||
if ( localContent > contentEof ) // buffered past eof?
|
||||
contentEof = localContent; // return new logical eof
|
||||
|
||||
outPos = contentEof;
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
outPos = contentEof; // frozen files get length from content file
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
void morkStream::NewBadCursorSlotsError(morkEnv* ev) const
|
||||
{ ev->NewError("bad stream cursor slots"); }
|
||||
|
||||
void morkStream::NewNullStreamBufferError(morkEnv* ev) const
|
||||
{ ev->NewError("null stream buffer"); }
|
||||
|
||||
void morkStream::NewCantReadSinkError(morkEnv* ev) const
|
||||
{ ev->NewError("cant read stream sink"); }
|
||||
|
||||
void morkStream::NewCantWriteSourceError(morkEnv* ev) const
|
||||
{ ev->NewError("cant write stream source"); }
|
||||
|
||||
void morkStream::NewPosBeyondEofError(morkEnv* ev) const
|
||||
{ ev->NewError("stream pos beyond eof"); }
|
||||
|
||||
void morkStream::NewBadCursorOrderError(morkEnv* ev) const
|
||||
{ ev->NewError("bad stream cursor order"); }
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
morkStream::Tell(morkEnv* ev) const
|
||||
{
|
||||
mork_pos outPos = 0;
|
||||
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenAndActiveFile() && file )
|
||||
{
|
||||
mork_u1* buf = mStream_Buf;
|
||||
mork_u1* at = mStream_At;
|
||||
|
||||
mork_u1* readEnd = mStream_ReadEnd; // nonzero only if readonly
|
||||
mork_u1* writeEnd = mStream_WriteEnd; // nonzero only if writeonly
|
||||
|
||||
if ( writeEnd )
|
||||
{
|
||||
if ( buf && at >= buf && at <= writeEnd )
|
||||
{
|
||||
outPos = mStream_BufPos + (at - buf);
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
else if ( readEnd )
|
||||
{
|
||||
if ( buf && at >= buf && at <= readEnd )
|
||||
{
|
||||
outPos = mStream_BufPos + (at - buf);
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_size
|
||||
morkStream::Read(morkEnv* ev, void* outBuf, mork_size inSize)
|
||||
{
|
||||
// First we satisfy the request from buffered bytes, if any. Then
|
||||
// if additional bytes are needed, we satisfy these by direct reads
|
||||
// from the content file without any local buffering (but we still need
|
||||
// to adjust the buffer position to reflect the current i/o point).
|
||||
|
||||
mork_pos outActual = 0;
|
||||
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenAndActiveFile() && file )
|
||||
{
|
||||
mork_u1* end = mStream_ReadEnd; // byte after last buffered byte
|
||||
if ( end ) // file is open for read access?
|
||||
{
|
||||
if ( inSize ) // caller wants any output?
|
||||
{
|
||||
mork_u1* sink = (mork_u1*) outBuf; // where we plan to write bytes
|
||||
if ( sink ) // caller passed good buffer address?
|
||||
{
|
||||
mork_u1* at = mStream_At;
|
||||
mork_u1* buf = mStream_Buf;
|
||||
if ( at >= buf && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_num remaining = end - at; // bytes left in buffer
|
||||
|
||||
mork_num quantum = inSize; // number of bytes to copy
|
||||
if ( quantum > remaining ) // more than buffer content?
|
||||
quantum = remaining; // restrict to buffered bytes
|
||||
|
||||
if ( quantum ) // any bytes left in the buffer?
|
||||
{
|
||||
MORK_MEMCPY(sink, at, quantum); // from buffer bytes
|
||||
|
||||
at += quantum; // advance past read bytes
|
||||
mStream_At = at;
|
||||
outActual += quantum; // this much copied so far
|
||||
|
||||
sink += quantum; // in case we need to copy more
|
||||
inSize -= quantum; // filled this much of request
|
||||
mStream_HitEof = morkBool_kFalse;
|
||||
}
|
||||
|
||||
if ( inSize ) // we still need to read more content?
|
||||
{
|
||||
// We need to read more bytes directly from the
|
||||
// content file, without local buffering. We have
|
||||
// exhausted the local buffer, so we need to show
|
||||
// it is now empty, and adjust the current buf pos.
|
||||
|
||||
mork_num posDelta = (at - buf); // old buf content
|
||||
mStream_BufPos += posDelta; // past now empty buf
|
||||
|
||||
mStream_At = mStream_ReadEnd = buf; // empty buffer
|
||||
|
||||
file->Seek(ev, mStream_BufPos); // set file pos
|
||||
if ( ev->Good() ) // no seek error?
|
||||
{
|
||||
mork_num actual = file->Read(ev, sink, inSize);
|
||||
if ( ev->Good() ) // no read error?
|
||||
{
|
||||
if ( actual )
|
||||
{
|
||||
outActual += actual;
|
||||
mStream_BufPos += actual;
|
||||
mStream_HitEof = morkBool_kFalse;
|
||||
}
|
||||
else if ( !outActual )
|
||||
mStream_HitEof = morkBool_kTrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
else this->NewNullStreamBufferError(ev);
|
||||
}
|
||||
}
|
||||
else this->NewCantReadSinkError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
if ( ev->Bad() )
|
||||
outActual = 0;
|
||||
|
||||
return outActual;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_pos
|
||||
morkStream::Seek(morkEnv* ev, mork_pos inPos)
|
||||
{
|
||||
mork_pos outPos = 0;
|
||||
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
|
||||
{
|
||||
mork_u1* at = mStream_At; // current position in buffer
|
||||
mork_u1* buf = mStream_Buf; // beginning of buffer
|
||||
mork_u1* readEnd = mStream_ReadEnd; // nonzero only if readonly
|
||||
mork_u1* writeEnd = mStream_WriteEnd; // nonzero only if writeonly
|
||||
|
||||
if ( writeEnd ) // file is mutable/writeonly?
|
||||
{
|
||||
if ( mStream_Dirty ) // need to commit buffer changes?
|
||||
this->Flush(ev);
|
||||
|
||||
if ( ev->Good() ) // no errors during flush or earlier?
|
||||
{
|
||||
if ( at == buf ) // expected post flush cursor value?
|
||||
{
|
||||
if ( mStream_BufPos != inPos ) // need to change pos?
|
||||
{
|
||||
mork_pos eof = file->Length(ev);
|
||||
if ( ev->Good() ) // no errors getting length?
|
||||
{
|
||||
if ( inPos <= eof ) // acceptable new position?
|
||||
{
|
||||
mStream_BufPos = inPos; // new stream position
|
||||
outPos = inPos;
|
||||
}
|
||||
else this->NewPosBeyondEofError(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
}
|
||||
else if ( readEnd ) // file is frozen/readonly?
|
||||
{
|
||||
if ( at >= buf && at <= readEnd ) // expected cursor order?
|
||||
{
|
||||
mork_pos eof = file->Length(ev);
|
||||
if ( ev->Good() ) // no errors getting length?
|
||||
{
|
||||
if ( inPos <= eof ) // acceptable new position?
|
||||
{
|
||||
outPos = inPos;
|
||||
mStream_BufPos = inPos; // new stream position
|
||||
mStream_At = mStream_ReadEnd = buf; // empty buffer
|
||||
if ( inPos == eof ) // notice eof reached?
|
||||
mStream_HitEof = morkBool_kTrue;
|
||||
}
|
||||
else this->NewPosBeyondEofError(ev);
|
||||
}
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return outPos;
|
||||
}
|
||||
|
||||
/*public virtual*/ mork_size
|
||||
morkStream::Write(morkEnv* ev, const void* inBuf, mork_size inSize)
|
||||
{
|
||||
mork_num outActual = 0;
|
||||
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenActiveAndMutableFile() && file )
|
||||
{
|
||||
mork_u1* end = mStream_WriteEnd; // byte after last buffered byte
|
||||
if ( end ) // file is open for write access?
|
||||
{
|
||||
if ( inSize ) // caller provided any input?
|
||||
{
|
||||
const mork_u1* source = (const mork_u1*) inBuf; // from where
|
||||
if ( source ) // caller passed good buffer address?
|
||||
{
|
||||
mork_u1* at = mStream_At;
|
||||
mork_u1* buf = mStream_Buf;
|
||||
if ( at >= buf && at <= end ) // expected cursor order?
|
||||
{
|
||||
mork_num space = end - at; // space left in buffer
|
||||
|
||||
mork_num quantum = inSize; // number of bytes to write
|
||||
if ( quantum > space ) // more than buffer size?
|
||||
quantum = space; // restrict to avail space
|
||||
|
||||
if ( quantum ) // any space left in the buffer?
|
||||
{
|
||||
mStream_Dirty = morkBool_kTrue; // to ensure later flush
|
||||
MORK_MEMCPY(at, source, quantum); // into buffer
|
||||
|
||||
mStream_At += quantum; // advance past written bytes
|
||||
outActual += quantum; // this much written so far
|
||||
|
||||
source += quantum; // in case we need to write more
|
||||
inSize -= quantum; // filled this much of request
|
||||
}
|
||||
|
||||
if ( inSize ) // we still need to write more content?
|
||||
{
|
||||
// We need to write more bytes directly to the
|
||||
// content file, without local buffering. We have
|
||||
// exhausted the local buffer, so we need to flush
|
||||
// it and empty it, and adjust the current buf pos.
|
||||
// After flushing, if the rest of the write fits
|
||||
// inside the buffer, we will put bytes into the
|
||||
// buffer rather than write them to content file.
|
||||
|
||||
if ( mStream_Dirty )
|
||||
this->Flush(ev); // will update mStream_BufPos
|
||||
|
||||
at = mStream_At;
|
||||
if ( at < buf || at > end ) // bad cursor?
|
||||
this->NewBadCursorOrderError(ev);
|
||||
|
||||
if ( ev->Good() ) // no errors?
|
||||
{
|
||||
space = end - at; // space left in buffer
|
||||
if ( space > inSize ) // write to buffer?
|
||||
{
|
||||
mStream_Dirty = morkBool_kTrue; // ensure flush
|
||||
MORK_MEMCPY(at, source, inSize); // copy
|
||||
|
||||
mStream_At += inSize; // past written bytes
|
||||
outActual += inSize; // this much written
|
||||
}
|
||||
else // directly to content file instead
|
||||
{
|
||||
file->Seek(ev, mStream_BufPos); // set pos
|
||||
|
||||
if ( ev->Good() ) // no seek error?
|
||||
{
|
||||
mork_num actual =
|
||||
file->Write(ev, source, inSize);
|
||||
if ( ev->Good() ) // no write error?
|
||||
{
|
||||
outActual += actual;
|
||||
mStream_BufPos += actual;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
else this->NewNullStreamBufferError(ev);
|
||||
}
|
||||
}
|
||||
else this->NewCantWriteSourceError(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
if ( ev->Bad() )
|
||||
outActual = 0;
|
||||
|
||||
return outActual;
|
||||
}
|
||||
|
||||
/*public virtual*/ void
|
||||
morkStream::Flush(morkEnv* ev)
|
||||
{
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
|
||||
{
|
||||
if ( mStream_Dirty )
|
||||
this->spill_buf(ev);
|
||||
file->Flush(ev);
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
}
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
// protected: // protected non-poly morkStream methods (for char io)
|
||||
|
||||
int
|
||||
morkStream::fill_getc(morkEnv* ev)
|
||||
{
|
||||
int c = EOF;
|
||||
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenAndActiveFile() && file )
|
||||
{
|
||||
mork_u1* buf = mStream_Buf;
|
||||
mork_u1* end = mStream_ReadEnd; // beyond buf after earlier read
|
||||
if ( end > buf ) // any earlier read bytes buffered?
|
||||
{
|
||||
mStream_BufPos += ( end - buf ); // advance past old read
|
||||
}
|
||||
|
||||
if ( ev->Good() ) // no errors yet?
|
||||
{
|
||||
file->Seek(ev, mStream_BufPos); // set file pos
|
||||
if ( ev->Good() ) // no seek error?
|
||||
{
|
||||
mork_num actual = file->Read(ev, buf, mStream_BufSize);
|
||||
if ( ev->Good() ) // no read errors?
|
||||
{
|
||||
if ( actual > mStream_BufSize ) // more than asked for??
|
||||
actual = mStream_BufSize;
|
||||
|
||||
mStream_At = buf;
|
||||
mStream_ReadEnd = buf + actual;
|
||||
if ( actual ) // any bytes actually read?
|
||||
{
|
||||
c = *mStream_At++; // return first byte from buffer
|
||||
mStream_HitEof = morkBool_kFalse;
|
||||
}
|
||||
else
|
||||
mStream_HitEof = morkBool_kTrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
morkStream::spill_putc(morkEnv* ev, int c)
|
||||
{
|
||||
this->spill_buf(ev);
|
||||
if ( ev->Good() && mStream_At < mStream_WriteEnd )
|
||||
this->Putc(ev, c);
|
||||
}
|
||||
|
||||
void
|
||||
morkStream::spill_buf(morkEnv* ev) // spill/flush from buffer to file
|
||||
{
|
||||
morkFile* file = mStream_ContentFile;
|
||||
if ( this->IsOpenOrClosingNode() && this->FileActive() && file )
|
||||
{
|
||||
mork_u1* buf = mStream_Buf;
|
||||
if ( mStream_Dirty )
|
||||
{
|
||||
mork_u1* at = mStream_At;
|
||||
if ( at >= buf && at <= mStream_WriteEnd ) // order?
|
||||
{
|
||||
mork_num count = at - buf; // the number of bytes buffered
|
||||
if ( count ) // anything to write to the string?
|
||||
{
|
||||
if ( count > mStream_BufSize ) // no more than max?
|
||||
{
|
||||
count = mStream_BufSize;
|
||||
mStream_WriteEnd = buf + mStream_BufSize;
|
||||
this->NewBadCursorSlotsError(ev);
|
||||
}
|
||||
if ( ev->Good() )
|
||||
{
|
||||
file->Seek(ev, mStream_BufPos);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
file->Write(ev, buf, count);
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mStream_BufPos += count; // past bytes written
|
||||
mStream_At = buf; // reset buffer cursor
|
||||
mStream_Dirty = morkBool_kFalse;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else this->NewBadCursorOrderError(ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MORK_DEBUG
|
||||
ev->NewWarning("stream:spill:not:dirty");
|
||||
#endif /*MORK_DEBUG*/
|
||||
}
|
||||
}
|
||||
else this->NewFileDownError(ev);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
242
mozilla/db/mork/src/morkStream.h
Normal file
242
mozilla/db/mork/src/morkStream.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKSTREAM_
|
||||
#define _MORKSTREAM_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/*=============================================================================
|
||||
* morkStream: buffered file i/o
|
||||
*/
|
||||
|
||||
/*| morkStream exists to define an morkFile subclass that provides buffered
|
||||
**| i/o for an underlying content file. Naturally this arrangement only makes
|
||||
**| sense when the underlying content file is itself not efficiently buffered
|
||||
**| (especially for character by character i/o).
|
||||
**|
|
||||
**|| morkStream is intended for either reading use or writing use, but not
|
||||
**| both simultaneously or interleaved. Pick one when the stream is created
|
||||
**| and don't change your mind. This restriction is intended to avoid obscure
|
||||
**| and complex bugs that might arise from interleaved reads and writes -- so
|
||||
**| just don't do it. A stream is either a sink or a source, but not both.
|
||||
**|
|
||||
**|| (When the underlying content file is intended to support both reading and
|
||||
**| writing, a developer might use two instances of morkStream where one is for
|
||||
**| reading and the other is for writing. In this case, a developer must take
|
||||
**| care to keep the two streams in sync because each will maintain a separate
|
||||
**| buffer representing a cache consistency problem for the other. A simple
|
||||
**| approach is to invalidate the buffer of one when one uses the other, with
|
||||
**| the assumption that closely mixed reading and writing is not expected, so
|
||||
**| that little cost is associated with changing read/write streaming modes.)
|
||||
**|
|
||||
**|| Exactly one of mStream_ReadEnd or mStream_WriteEnd must be a null pointer,
|
||||
**| and this will cause the right thing to occur when inlines use them, because
|
||||
**| mStream_At < mStream_WriteEnd (for example) will always be false and the
|
||||
**| else branch of the statement calls a function that raises an appropriate
|
||||
**| error to complain about either reading a sink or writing a source.
|
||||
**|
|
||||
**|| morkStream is a direct clone of ab_Stream from Communicator 4.5's
|
||||
**| address book code, which in turn was based on the stream class in the
|
||||
**| public domain Mithril programming language.
|
||||
|*/
|
||||
|
||||
#define morkStream_kPrintBufSize /*i*/ 512 /* buffer size used by printf() */
|
||||
|
||||
#define morkStream_kMinBufSize /*i*/ 512 /* buffer no fewer bytes */
|
||||
#define morkStream_kMaxBufSize /*i*/ (32 * 1024) /* buffer no more bytes */
|
||||
|
||||
#define morkDerived_kStream /*i*/ 0x7A74 /* ascii 'zt' */
|
||||
|
||||
class morkStream /*d*/ : public morkFile { /* from Mithril's AgStream class */
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected morkStream members
|
||||
mork_u1* mStream_At; // pointer into mStream_Buf
|
||||
mork_u1* mStream_ReadEnd; // null or one byte past last readable byte
|
||||
mork_u1* mStream_WriteEnd; // null or mStream_Buf + mStream_BufSize
|
||||
|
||||
morkFile* mStream_ContentFile; // where content is read and written
|
||||
|
||||
mork_u1* mStream_Buf; // dynamically allocated memory to buffer io
|
||||
mork_size mStream_BufSize; // requested buf size (fixed by min and max)
|
||||
mork_pos mStream_BufPos; // logical position of byte at mStream_Buf
|
||||
mork_bool mStream_Dirty; // does the buffer need to be flushed?
|
||||
mork_bool mStream_HitEof; // has eof been reached? (only frozen streams)
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseStream() only if open
|
||||
virtual ~morkStream(); // assert that CloseStream() executed earlier
|
||||
|
||||
public: // morkStream construction & destruction
|
||||
morkStream(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkFile* ioContentFile, mork_size inBufSize, mork_bool inFrozen);
|
||||
void CloseStream(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkStream(const morkStream& other);
|
||||
morkStream& operator=(const morkStream& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsStream() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kStream; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
void NonStreamTypeError(morkEnv* ev);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // virtual morkFile methods
|
||||
|
||||
virtual void BecomeTrunk(morkEnv* ev);
|
||||
// If this file is a file version branch created by calling AcquireBud(),
|
||||
// BecomeTrunk() causes this file's content to replace the original
|
||||
// file's content, typically by assuming the original file's identity.
|
||||
|
||||
virtual morkFile* AcquireBud(morkEnv* ev, nsIMdbHeap* ioHeap);
|
||||
// AcquireBud() starts a new "branch" version of the file, empty of content,
|
||||
// so that a new version of the file can be written. This new file
|
||||
// can later be told to BecomeTrunk() the original file, so the branch
|
||||
// created by budding the file will replace the original file. Some
|
||||
// file subclasses might initially take the unsafe but expedient
|
||||
// approach of simply truncating this file down to zero length, and
|
||||
// then returning the same morkFile pointer as this, with an extra
|
||||
// reference count increment. Note that the caller of AcquireBud() is
|
||||
// expected to eventually call CutStrongRef() on the returned file
|
||||
// in order to release the strong reference. High quality versions
|
||||
// of morkFile subclasses will create entirely new files which later
|
||||
// are renamed to become the old file, so that better transactional
|
||||
// behavior is exhibited by the file, so crashes protect old files.
|
||||
// Note that AcquireBud() is an illegal operation on readonly files.
|
||||
|
||||
virtual mork_pos Length(morkEnv* ev) const; // eof
|
||||
virtual mork_pos Tell(morkEnv* ev) const;
|
||||
virtual mork_size Read(morkEnv* ev, void* outBuf, mork_size inSize);
|
||||
virtual mork_pos Seek(morkEnv* ev, mork_pos inPos);
|
||||
virtual mork_size Write(morkEnv* ev, const void* inBuf, mork_size inSize);
|
||||
virtual void Flush(morkEnv* ev);
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
protected: // protected non-poly morkStream methods (for char io)
|
||||
|
||||
int fill_getc(morkEnv* ev);
|
||||
void spill_putc(morkEnv* ev, int c);
|
||||
void spill_buf(morkEnv* ev); // spill/flush from buffer to file
|
||||
|
||||
// ````` ````` ````` ````` ````` ````` ````` `````
|
||||
public: // public non-poly morkStream methods
|
||||
|
||||
void NewBadCursorSlotsError(morkEnv* ev) const;
|
||||
void NewBadCursorOrderError(morkEnv* ev) const;
|
||||
void NewNullStreamBufferError(morkEnv* ev) const;
|
||||
void NewCantReadSinkError(morkEnv* ev) const;
|
||||
void NewCantWriteSourceError(morkEnv* ev) const;
|
||||
void NewPosBeyondEofError(morkEnv* ev) const;
|
||||
|
||||
morkFile* GetStreamContentFile() const { return mStream_ContentFile; }
|
||||
mork_size GetStreamBufferSize() const { return mStream_BufSize; }
|
||||
|
||||
mork_size PutIndent(morkEnv* ev, mork_count inDepth);
|
||||
// PutIndent() puts a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutByteThenIndent(morkEnv* ev, int inByte, mork_count inDepth);
|
||||
// PutByteThenIndent() puts the byte, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutStringThenIndent(morkEnv* ev,
|
||||
const char* inString, mork_count inDepth);
|
||||
// PutStringThenIndent() puts the string, then a linebreak, and then
|
||||
// "indents" by inDepth, and returns the line length after indentation.
|
||||
|
||||
mork_size PutString(morkEnv* ev, const char* inString);
|
||||
// PutString() returns the length of the string written.
|
||||
|
||||
mork_size PutStringThenNewline(morkEnv* ev, const char* inString);
|
||||
// PutStringThenNewline() returns total number of bytes written.
|
||||
|
||||
mork_size PutStringThenNewlineThenSpace(morkEnv* ev, const char* inString);
|
||||
// PutStringThenNewlineThenSpace() returns total number of bytes written.
|
||||
|
||||
mork_size PutByteThenNewline(morkEnv* ev, int inByte);
|
||||
// PutByteThenNewline() returns total number of bytes written.
|
||||
|
||||
mork_size PutByteThenNewlineThenSpace(morkEnv* ev, int inByte);
|
||||
// PutByteThenNewlineThenSpace() returns total number of bytes written.
|
||||
|
||||
// ````` ````` stdio type methods ````` `````
|
||||
void Printf(morkEnv* ev, const char* inFormat, ...);
|
||||
|
||||
mork_pos Ftell(morkEnv* ev) /*i*/ { return this->Tell(ev); }
|
||||
|
||||
void Fsetpos(morkEnv* ev, mork_pos inPos) /*i*/ { this->Seek(ev, inPos); }
|
||||
|
||||
void Rewind(morkEnv* ev) /*i*/ { this->Fsetpos(ev, 0); }
|
||||
|
||||
void Fflush(morkEnv* ev) /*i*/ { this->Flush(ev); }
|
||||
|
||||
mork_bool Feof() /*i*/ { return mStream_HitEof; }
|
||||
// Feof() is never true for writable stream output sinks
|
||||
|
||||
void Puts(morkEnv* ev, const char* inString) /*i*/
|
||||
{ this->PutString(ev, inString); }
|
||||
|
||||
void Ungetc(int c) /*i*/
|
||||
{ if ( mStream_At > mStream_Buf && c > 0 ) *--mStream_At = c; }
|
||||
|
||||
int Getc(morkEnv* ev) /*i*/
|
||||
{ return ( mStream_At < mStream_ReadEnd )? *mStream_At++ : fill_getc(ev); }
|
||||
|
||||
void Putc(morkEnv* ev, int c) /*i*/
|
||||
{
|
||||
mStream_Dirty = morkBool_kTrue;
|
||||
if ( mStream_At < mStream_WriteEnd )
|
||||
*mStream_At++ = c;
|
||||
else
|
||||
spill_putc(ev, c);
|
||||
}
|
||||
|
||||
mork_size PutLineBreak(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakStream(morkStream* me,
|
||||
morkEnv* ev, morkStream** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongStream(morkStream* me,
|
||||
morkEnv* ev, morkStream** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKSTREAM_ */
|
||||
318
mozilla/db/mork/src/morkTable.cpp
Normal file
318
mozilla/db/mork/src/morkTable.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#include "morkArray.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINTABLE_
|
||||
#include "orkinTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLEROWCURSOR_
|
||||
#include "morkTableRowCursor.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkTable::CloseMorkNode(morkEnv* ev) /*i*/ // CloseTable() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseTable(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkTable::~morkTable() /*i*/ // assert CloseTable() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
MORK_ASSERT(mTable_Store==0);
|
||||
MORK_ASSERT(mTable_RowSpace==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkTable::morkTable(morkEnv* ev, /*i*/
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
morkStore* ioStore, nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace,
|
||||
mork_tid inTid, mork_kind inKind, mork_bool inMustBeUnique)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mTable_Store( 0 )
|
||||
, mTable_RowSpace( 0 )
|
||||
, mTable_Id( inTid )
|
||||
, mTable_RowMap(ev, morkUsage::kMember, (nsIMdbHeap*) 0, ioSlotHeap,
|
||||
morkTable_kStartRowMapSlotCount)
|
||||
, mTable_RowArray(ev, morkUsage::kMember, (nsIMdbHeap*) 0,
|
||||
morkTable_kStartRowArraySize, ioSlotHeap)
|
||||
, mTable_Kind( inKind )
|
||||
, mTable_MustBeUnique( inMustBeUnique )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioStore && ioSlotHeap && ioRowSpace )
|
||||
{
|
||||
if ( inKind )
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &mTable_Store);
|
||||
morkRowSpace::SlotWeakRowSpace(ioRowSpace, ev, &mTable_RowSpace);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kTable;
|
||||
}
|
||||
else
|
||||
ioRowSpace->ZeroKindError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkTable::CloseTable(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mTable_RowMap.CloseMorkNode(ev);
|
||||
mTable_RowArray.CloseMorkNode(ev);
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mTable_Store);
|
||||
morkRowSpace::SlotStrongRowSpace((morkRowSpace*) 0,
|
||||
ev, &mTable_RowSpace);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkTable::NonTableTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkTable");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkTable::NonTableTypeWarning(morkEnv* ev)
|
||||
{
|
||||
ev->NewWarning("non morkTable");
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
morkTable::NilRowSpaceError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mTable_RowSpace");
|
||||
}
|
||||
|
||||
void
|
||||
morkTable::GetTableOid(morkEnv* ev, mdbOid* outOid)
|
||||
{
|
||||
morkRowSpace* space = mTable_RowSpace;
|
||||
if ( space )
|
||||
{
|
||||
outOid->mOid_Scope = space->mSpace_Scope;
|
||||
outOid->mOid_Id = mTable_Id;
|
||||
}
|
||||
else
|
||||
this->NilRowSpaceError(ev);
|
||||
}
|
||||
|
||||
nsIMdbTable*
|
||||
morkTable::AcquireTableHandle(morkEnv* ev)
|
||||
{
|
||||
nsIMdbTable* outTable = 0;
|
||||
orkinTable* t = (orkinTable*) mObject_Handle;
|
||||
if ( t ) // have an old handle?
|
||||
t->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
t = orkinTable::MakeTable(ev, this);
|
||||
mObject_Handle = t;
|
||||
}
|
||||
if ( t )
|
||||
outTable = t;
|
||||
return outTable;
|
||||
}
|
||||
|
||||
mork_pos
|
||||
morkTable::ArrayHasOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
mork_count count = mTable_RowArray.mArray_Fill;
|
||||
mork_pos pos = -1;
|
||||
while ( ++pos < count )
|
||||
{
|
||||
morkRow* row = (morkRow*) mTable_RowArray.At(pos);
|
||||
MORK_ASSERT(row);
|
||||
if ( row && row->EqualOid(inOid) )
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
mork_pos
|
||||
morkTable::MapHasOid(morkEnv* ev, const mdbOid* inOid)
|
||||
{
|
||||
morkRow* row = mTable_RowMap.GetOid(ev, inOid);
|
||||
if ( row )
|
||||
return 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkTable::AddRow(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
morkRow* row = mTable_RowMap.GetRow(ev, ioRow);
|
||||
if ( !row && ev->Good() )
|
||||
{
|
||||
mork_pos pos = mTable_RowArray.AppendSlot(ev, ioRow);
|
||||
if ( ev->Good() && pos > 0 )
|
||||
{
|
||||
ioRow->AddTableUse(ev);
|
||||
if ( mTable_RowMap.AddRow(ev, ioRow) )
|
||||
{
|
||||
// okay, anything else?
|
||||
}
|
||||
else
|
||||
mTable_RowArray.CutSlot(ev, pos);
|
||||
}
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
mork_bool
|
||||
morkTable::CutRow(morkEnv* ev, morkRow* ioRow)
|
||||
{
|
||||
morkRow* row = mTable_RowMap.GetRow(ev, ioRow);
|
||||
if ( row )
|
||||
{
|
||||
mork_count count = mTable_RowArray.mArray_Fill;
|
||||
morkRow** rowSlots = (morkRow**) mTable_RowArray.mArray_Slots;
|
||||
if ( rowSlots ) // array has vector as expected?
|
||||
{
|
||||
mork_pos pos = -1;
|
||||
morkRow** end = rowSlots + count;
|
||||
morkRow** slot = rowSlots - 1; // prepare for preincrement:
|
||||
while ( ++slot < end ) // another slot to check?
|
||||
{
|
||||
if ( *slot == row ) // found the slot containing row?
|
||||
{
|
||||
pos = slot - rowSlots; // record absolute position
|
||||
break; // end while loop
|
||||
}
|
||||
}
|
||||
if ( pos >= 0 ) // need to cut if from the array?
|
||||
mTable_RowArray.CutSlot(ev, pos);
|
||||
else
|
||||
ev->NewWarning("row not found in array");
|
||||
}
|
||||
else
|
||||
mTable_RowArray.NilSlotsAddressError(ev);
|
||||
|
||||
mTable_RowMap.CutRow(ev, ioRow);
|
||||
if ( ioRow->CutTableUse(ev) == 0 )
|
||||
ioRow->OnZeroTableUse(ev);
|
||||
}
|
||||
return ev->Good();
|
||||
}
|
||||
|
||||
morkTableRowCursor*
|
||||
morkTable::NewTableRowCursor(morkEnv* ev, mork_pos inRowPos)
|
||||
{
|
||||
morkTableRowCursor* outCursor = 0;
|
||||
if ( ev->Good() )
|
||||
{
|
||||
nsIMdbHeap* heap = mTable_Store->mPort_Heap;
|
||||
morkTableRowCursor* cursor = new(*heap, ev)
|
||||
morkTableRowCursor(ev, morkUsage::kHeap, heap, this, inRowPos);
|
||||
if ( cursor )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
outCursor = cursor;
|
||||
else
|
||||
cursor->CutStrongRef(ev);
|
||||
}
|
||||
}
|
||||
return outCursor;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
morkTableMap::~morkTableMap()
|
||||
{
|
||||
}
|
||||
|
||||
morkTableMap::morkTableMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap)
|
||||
: morkNodeMap(ev, inUsage, ioHeap, ioSlotHeap)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kTableMap;
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
207
mozilla/db/mork/src/morkTable.h
Normal file
207
mozilla/db/mork/src/morkTable.h
Normal file
@@ -0,0 +1,207 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#define _MORKTABLE_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKARRAY_
|
||||
#include "morkArray.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODEMAP_
|
||||
#include "morkNodeMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class nsIMdbTable;
|
||||
#define morkDerived_kTable /*i*/ 0x5462 /* ascii 'Tb' */
|
||||
|
||||
#define morkTable_kStartRowArraySize 11 /* modest starting size for array */
|
||||
|
||||
#define morkTable_kStartRowMapSlotCount 128
|
||||
|
||||
class morkTable : public morkObject {
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkHandle* mObject_Handle; // weak ref to handle for this object
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkStore* mTable_Store; // weak ref to port
|
||||
// mork_seed mTable_Seed; // use TableSeed() instead
|
||||
|
||||
// mTable_RowSpace->mSpace_Scope is row scope
|
||||
morkRowSpace* mTable_RowSpace; // weak ref to containing space
|
||||
|
||||
morkRowMap mTable_RowMap; // hash table of all members
|
||||
morkArray mTable_RowArray; // array of morkRow pointers
|
||||
|
||||
mork_tid mTable_Id;
|
||||
mork_kind mTable_Kind;
|
||||
|
||||
mork_bool mTable_MustBeUnique;
|
||||
mork_u1 mTable_Pad[ 3 ]; // padding to u4 alignment
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseTable() if open
|
||||
virtual ~morkTable(); // assert that close executed earlier
|
||||
|
||||
public: // morkTable construction & destruction
|
||||
morkTable(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioNodeHeap, morkStore* ioStore,
|
||||
nsIMdbHeap* ioSlotHeap, morkRowSpace* ioRowSpace,
|
||||
mork_tid inTableId,
|
||||
mork_kind inKind, mork_bool inMustBeUnique);
|
||||
void CloseTable(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkTable(const morkTable& other);
|
||||
morkTable& operator=(const morkTable& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsTable() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kTable; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonTableTypeError(morkEnv* ev);
|
||||
static void NonTableTypeWarning(morkEnv* ev);
|
||||
static void NilRowSpaceError(morkEnv* ev);
|
||||
|
||||
public: // other table methods
|
||||
|
||||
// void DirtyAllTableContent(morkEnv* ev);
|
||||
|
||||
mork_seed TableSeed() const { return mTable_RowArray.mArray_Seed; }
|
||||
|
||||
nsIMdbTable* AcquireTableHandle(morkEnv* ev); // mObject_Handle
|
||||
|
||||
mork_count GetRowCount() const { return mTable_RowArray.mArray_Fill; }
|
||||
|
||||
void GetTableOid(morkEnv* ev, mdbOid* outOid);
|
||||
mork_pos ArrayHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_pos MapHasOid(morkEnv* ev, const mdbOid* inOid);
|
||||
mork_bool AddRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||
mork_bool CutRow(morkEnv* ev, morkRow* ioRow); // returns ev->Good()
|
||||
|
||||
morkTableRowCursor* NewTableRowCursor(morkEnv* ev, mork_pos inRowPos);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakTable(morkTable* me,
|
||||
morkEnv* ev, morkTable** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongTableS(morkTable* me,
|
||||
morkEnv* ev, morkTable** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkDerived_kTableMap /*i*/ 0x744D /* ascii 'tM' */
|
||||
|
||||
/*| morkTableMap: maps mork_token -> morkTable
|
||||
|*/
|
||||
class morkTableMap : public morkNodeMap { // for mapping tokens to tables
|
||||
|
||||
public:
|
||||
|
||||
virtual ~morkTableMap();
|
||||
morkTableMap(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap);
|
||||
|
||||
public: // other map methods
|
||||
|
||||
mork_bool AddTable(morkEnv* ev, morkTable* ioTable)
|
||||
{ return this->AddNode(ev, ioTable->mTable_Id, ioTable); }
|
||||
// the AddTable() boolean return equals ev->Good().
|
||||
|
||||
mork_bool CutTable(morkEnv* ev, mork_tid inTid)
|
||||
{ return this->CutNode(ev, inTid); }
|
||||
// The CutTable() boolean return indicates whether removal happened.
|
||||
|
||||
morkTable* GetTable(morkEnv* ev, mork_tid inTid)
|
||||
{ return (morkTable*) this->GetNode(ev, inTid); }
|
||||
// Note the returned table does NOT have an increase in refcount for this.
|
||||
|
||||
mork_num CutAllTables(morkEnv* ev)
|
||||
{ return this->CutAllNodes(ev); }
|
||||
// CutAllTables() releases all the referenced table values.
|
||||
};
|
||||
|
||||
class morkTableMapIter: public morkMapIter{ // typesafe wrapper class
|
||||
|
||||
public:
|
||||
morkTableMapIter(morkEnv* ev, morkTableMap* ioMap)
|
||||
: morkMapIter(ev, ioMap) { }
|
||||
|
||||
morkTableMapIter( ) : morkMapIter() { }
|
||||
void InitTableMapIter(morkEnv* ev, morkTableMap* ioMap)
|
||||
{ this->InitMapIter(ev, ioMap); }
|
||||
|
||||
mork_change*
|
||||
FirstTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
||||
{ return this->First(ev, outTid, outTable); }
|
||||
|
||||
mork_change*
|
||||
NextTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
||||
{ return this->Next(ev, outTid, outTable); }
|
||||
|
||||
mork_change*
|
||||
HereTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
||||
{ return this->Here(ev, outTid, outTable); }
|
||||
|
||||
mork_change*
|
||||
CutHereTable(morkEnv* ev, mork_tid* outTid, morkTable** outTable)
|
||||
{ return this->CutHere(ev, outTid, outTable); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKTABLE_ */
|
||||
208
mozilla/db/mork/src/morkTableRowCursor.cpp
Normal file
208
mozilla/db/mork/src/morkTableRowCursor.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLEROWCURSOR_
|
||||
#include "morkTableRowCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINTABLEROWCURSOR_
|
||||
#include "orkinTableRowCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkTableRowCursor::CloseMorkNode(morkEnv* ev) // CloseTableRowCursor() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseTableRowCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkTableRowCursor::~morkTableRowCursor() // CloseTableRowCursor() executed earlier
|
||||
{
|
||||
MORK_ASSERT(this->IsShutNode());
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkTableRowCursor::morkTableRowCursor(morkEnv* ev,
|
||||
const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkTable* ioTable, mork_pos inRowPos)
|
||||
: morkCursor(ev, inUsage, ioHeap)
|
||||
, mTableRowCursor_Table( 0 )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
if ( ioTable )
|
||||
{
|
||||
mCursor_Pos = inRowPos;
|
||||
mCursor_Seed = ioTable->TableSeed();
|
||||
morkTable::SlotWeakTable(ioTable, ev, &mTableRowCursor_Table);
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kTableRowCursor;
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkTableRowCursor::CloseTableRowCursor(morkEnv* ev)
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mCursor_Pos = -1;
|
||||
mCursor_Seed = 0;
|
||||
morkTable::SlotWeakTable((morkTable*) 0, ev, &mTableRowCursor_Table);
|
||||
this->CloseCursor(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkTableRowCursor::NonTableRowCursorTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkTableRowCursor");
|
||||
}
|
||||
|
||||
orkinTableRowCursor*
|
||||
morkTableRowCursor::AcquireTableRowCursorHandle(morkEnv* ev)
|
||||
{
|
||||
orkinTableRowCursor* outCursor = 0;
|
||||
orkinTableRowCursor* c = (orkinTableRowCursor*) mObject_Handle;
|
||||
if ( c ) // have an old handle?
|
||||
c->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
c = orkinTableRowCursor::MakeTableRowCursor(ev, this);
|
||||
mObject_Handle = c;
|
||||
}
|
||||
if ( c )
|
||||
outCursor = c;
|
||||
return outCursor;
|
||||
}
|
||||
|
||||
mdb_pos
|
||||
morkTableRowCursor::NextRowOid(morkEnv* ev, mdbOid* outOid)
|
||||
{
|
||||
mdb_pos outPos = -1;
|
||||
(void) this->NextRow(ev, outOid, &outPos);
|
||||
return outPos;
|
||||
}
|
||||
|
||||
morkRow*
|
||||
morkTableRowCursor::NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos)
|
||||
{
|
||||
morkRow* outRow = 0;
|
||||
mork_pos pos = -1;
|
||||
|
||||
morkTable* table = mTableRowCursor_Table;
|
||||
if ( table )
|
||||
{
|
||||
if ( table->IsOpenNode() )
|
||||
{
|
||||
morkArray* array = &table->mTable_RowArray;
|
||||
pos = mCursor_Pos;
|
||||
if ( pos < 0 )
|
||||
pos = 0;
|
||||
else
|
||||
++pos;
|
||||
|
||||
if ( pos < array->mArray_Fill )
|
||||
{
|
||||
mCursor_Pos = pos; // update for next time
|
||||
morkRow* row = (morkRow*) array->At(pos);
|
||||
if ( row )
|
||||
{
|
||||
if ( row->IsRow() )
|
||||
{
|
||||
outRow = row;
|
||||
*outOid = row->mRow_Oid;
|
||||
}
|
||||
else
|
||||
row->NonRowTypeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
else
|
||||
{
|
||||
outOid->mOid_Scope = 0;
|
||||
outOid->mOid_Id = morkId_kMinusOne;
|
||||
}
|
||||
}
|
||||
else
|
||||
table->NonOpenNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
*outPos = pos;
|
||||
return outRow;
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
103
mozilla/db/mork/src/morkTableRowCursor.h
Normal file
103
mozilla/db/mork/src/morkTableRowCursor.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKTABLEROWCURSOR_
|
||||
#define _MORKTABLEROWCURSOR_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCURSOR_
|
||||
#include "morkCursor.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
class orkinTableRowCursor;
|
||||
#define morkDerived_kTableRowCursor /*i*/ 0x7243 /* ascii 'rC' */
|
||||
|
||||
class morkTableRowCursor : public morkCursor { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkFactory* mObject_Factory; // weak ref to suite factory
|
||||
|
||||
// mork_seed mCursor_Seed;
|
||||
// mork_pos mCursor_Pos;
|
||||
// mork_bool mCursor_DoFailOnSeedOutOfSync;
|
||||
// mork_u1 mCursor_Pad[ 3 ]; // explicitly pad to u4 alignment
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
morkTable* mTableRowCursor_Table; // weak ref to table
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseTableRowCursor()
|
||||
virtual ~morkTableRowCursor(); // assert that close executed earlier
|
||||
|
||||
public: // morkTableRowCursor construction & destruction
|
||||
morkTableRowCursor(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkTable* ioTable, mork_pos inRowPos);
|
||||
void CloseTableRowCursor(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkTableRowCursor(const morkTableRowCursor& other);
|
||||
morkTableRowCursor& operator=(const morkTableRowCursor& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsTableRowCursor() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kTableRowCursor; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonTableRowCursorTypeError(morkEnv* ev);
|
||||
|
||||
public: // other table row cursor methods
|
||||
|
||||
orkinTableRowCursor* AcquireTableRowCursorHandle(morkEnv* ev);
|
||||
|
||||
mdb_pos NextRowOid(morkEnv* ev, mdbOid* outOid);
|
||||
morkRow* NextRow(morkEnv* ev, mdbOid* outOid, mdb_pos* outPos);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakTableRowCursor(morkTableRowCursor* me,
|
||||
morkEnv* ev, morkTableRowCursor** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongTableRowCursor(morkTableRowCursor* me,
|
||||
morkEnv* ev, morkTableRowCursor** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKTABLEROWCURSOR_ */
|
||||
406
mozilla/db/mork/src/morkThumb.cpp
Normal file
406
mozilla/db/mork/src/morkThumb.cpp
Normal file
@@ -0,0 +1,406 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTHUMB_
|
||||
#include "morkThumb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINTHUMB_
|
||||
#include "orkinThumb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKFILE_
|
||||
#include "morkFile.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKWRITER_
|
||||
#include "morkWriter.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkThumb::CloseMorkNode(morkEnv* ev) // CloseThumb() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseThumb(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkThumb::~morkThumb() // assert CloseThumb() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mThumb_Magic==0);
|
||||
MORK_ASSERT(mThumb_Store==0);
|
||||
MORK_ASSERT(mThumb_File==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkThumb::morkThumb(morkEnv* ev,
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap,
|
||||
nsIMdbHeap* ioSlotHeap, mork_magic inMagic)
|
||||
: morkObject(ev, inUsage, ioHeap, (morkHandle*) 0)
|
||||
, mThumb_Magic( 0 )
|
||||
, mThumb_Total( 0 )
|
||||
, mThumb_Current( 0 )
|
||||
|
||||
, mThumb_Done( morkBool_kFalse )
|
||||
, mThumb_Broken( morkBool_kFalse )
|
||||
, mThumb_Seed( 0 )
|
||||
|
||||
, mThumb_Store( 0 )
|
||||
, mThumb_File( 0 )
|
||||
, mThumb_Writer( 0 )
|
||||
, mThumb_SourcePort( 0 )
|
||||
|
||||
, mThumb_DoCollect( morkBool_kFalse )
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
mThumb_Magic = inMagic;
|
||||
mNode_Derived = morkDerived_kThumb;
|
||||
}
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkThumb::CloseThumb(morkEnv* ev) // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
{
|
||||
mThumb_Magic = 0;
|
||||
morkWriter::SlotStrongWriter((morkWriter*) 0, ev, &mThumb_Writer);
|
||||
morkFile::SlotStrongFile((morkFile*) 0, ev, &mThumb_File);
|
||||
morkStore::SlotWeakStore((morkStore*) 0, ev, &mThumb_Store);
|
||||
morkPort::SlotStrongPort((morkPort*) 0, ev, &mThumb_SourcePort);
|
||||
this->MarkShut();
|
||||
}
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void morkThumb::NonThumbTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkThumb");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::UnsupportedThumbMagicError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("unsupported mThumb_Magic");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbStoreError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_Store");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbFileError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_File");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbWriterError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_Writer");
|
||||
}
|
||||
|
||||
/*static*/ void morkThumb::NilThumbSourcePortError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("nil mThumb_SourcePort");
|
||||
}
|
||||
|
||||
nsIMdbThumb*
|
||||
morkThumb::AcquireThumbHandle(morkEnv* ev)
|
||||
{
|
||||
nsIMdbThumb* outThumb = 0;
|
||||
orkinThumb* t = (orkinThumb*) mObject_Handle;
|
||||
if ( t ) // have an old handle?
|
||||
t->AddStrongRef(ev->AsMdbEnv());
|
||||
else // need new handle?
|
||||
{
|
||||
t = orkinThumb::MakeThumb(ev, this);
|
||||
mObject_Handle = t;
|
||||
}
|
||||
if ( t )
|
||||
outThumb = t;
|
||||
return outThumb;
|
||||
}
|
||||
|
||||
/*static*/ morkThumb*
|
||||
morkThumb::Make_OpenFileStore(morkEnv* ev, nsIMdbHeap* ioHeap,
|
||||
morkStore* ioStore)
|
||||
{
|
||||
morkThumb* outThumb = 0;
|
||||
if ( ioHeap && ioStore )
|
||||
{
|
||||
outThumb = new(*ioHeap, ev)
|
||||
morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap,
|
||||
morkThumb_kMagic_OpenFileStore);
|
||||
|
||||
if ( outThumb )
|
||||
{
|
||||
morkStore::SlotWeakStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
}
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return outThumb;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ morkThumb*
|
||||
morkThumb::Make_CompressCommit(morkEnv* ev,
|
||||
nsIMdbHeap* ioHeap, morkStore* ioStore, mork_bool inDoCollect)
|
||||
{
|
||||
morkThumb* outThumb = 0;
|
||||
if ( ioHeap && ioStore )
|
||||
{
|
||||
morkFile* file = ioStore->mStore_File;
|
||||
if ( file )
|
||||
{
|
||||
outThumb = new(*ioHeap, ev)
|
||||
morkThumb(ev, morkUsage::kHeap, ioHeap, ioHeap,
|
||||
morkThumb_kMagic_CompressCommit);
|
||||
|
||||
if ( outThumb )
|
||||
{
|
||||
morkWriter* writer = new(*ioHeap, ev)
|
||||
morkWriter(ev, morkUsage::kHeap, ioHeap, ioStore, file, ioHeap);
|
||||
if ( writer )
|
||||
{
|
||||
writer->mWriter_NeedDirtyAll = morkBool_kTrue;
|
||||
outThumb->mThumb_DoCollect = inDoCollect;
|
||||
morkStore::SlotWeakStore(ioStore, ev, &outThumb->mThumb_Store);
|
||||
morkFile::SlotStrongFile(file, ev, &outThumb->mThumb_File);
|
||||
morkWriter::SlotStrongWriter(writer, ev, &outThumb->mThumb_Writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ioStore->NilStoreFileError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
return outThumb;
|
||||
}
|
||||
|
||||
// { ===== begin non-poly methods imitating nsIMdbThumb =====
|
||||
void morkThumb::GetProgress(morkEnv* ev, mdb_count* outTotal,
|
||||
mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken)
|
||||
{
|
||||
if ( outTotal )
|
||||
*outTotal = mThumb_Total;
|
||||
if ( outCurrent )
|
||||
*outCurrent = mThumb_Current;
|
||||
if ( outDone )
|
||||
*outDone = mThumb_Done;
|
||||
if ( outBroken )
|
||||
*outBroken = mThumb_Broken;
|
||||
}
|
||||
|
||||
void morkThumb::DoMore(morkEnv* ev, mdb_count* outTotal,
|
||||
mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken)
|
||||
{
|
||||
if ( !mThumb_Done && !mThumb_Broken )
|
||||
{
|
||||
switch ( mThumb_Magic )
|
||||
{
|
||||
case morkThumb_kMagic_OpenFilePort: // 1 /* factory method */
|
||||
this->DoMore_OpenFilePort(ev); break;
|
||||
|
||||
case morkThumb_kMagic_OpenFileStore: // 2 /* factory method */
|
||||
this->DoMore_OpenFileStore(ev); break;
|
||||
|
||||
case morkThumb_kMagic_ExportToFormat: // 3 /* port method */
|
||||
this->DoMore_ExportToFormat(ev); break;
|
||||
|
||||
case morkThumb_kMagic_ImportContent: // 4 /* store method */
|
||||
this->DoMore_ImportContent(ev); break;
|
||||
|
||||
case morkThumb_kMagic_LargeCommit: // 5 /* store method */
|
||||
this->DoMore_LargeCommit(ev); break;
|
||||
|
||||
case morkThumb_kMagic_SessionCommit: // 6 /* store method */
|
||||
this->DoMore_SessionCommit(ev); break;
|
||||
|
||||
case morkThumb_kMagic_CompressCommit: // 7 /* store method */
|
||||
this->DoMore_CompressCommit(ev); break;
|
||||
|
||||
case morkThumb_kMagic_SearchManyColumns: // 8 /* table method */
|
||||
this->DoMore_SearchManyColumns(ev); break;
|
||||
|
||||
case morkThumb_kMagic_NewSortColumn: // 9 /* table metho) */
|
||||
this->DoMore_NewSortColumn(ev); break;
|
||||
|
||||
case morkThumb_kMagic_NewSortColumnWithCompare: // 10 /* table method */
|
||||
this->DoMore_NewSortColumnWithCompare(ev); break;
|
||||
|
||||
case morkThumb_kMagic_CloneSortColumn: // 11 /* table method */
|
||||
this->DoMore_CloneSortColumn(ev); break;
|
||||
|
||||
case morkThumb_kMagic_AddIndex: // 12 /* table method */
|
||||
this->DoMore_AddIndex(ev); break;
|
||||
|
||||
case morkThumb_kMagic_CutIndex: // 13 /* table method */
|
||||
this->DoMore_CutIndex(ev); break;
|
||||
|
||||
default:
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( outTotal )
|
||||
*outTotal = mThumb_Total;
|
||||
if ( outCurrent )
|
||||
*outCurrent = mThumb_Current;
|
||||
if ( outDone )
|
||||
*outDone = mThumb_Done;
|
||||
if ( outBroken )
|
||||
*outBroken = mThumb_Broken;
|
||||
}
|
||||
|
||||
void morkThumb::CancelAndBreakThumb(morkEnv* ev)
|
||||
{
|
||||
mThumb_Broken = morkBool_kTrue;
|
||||
}
|
||||
|
||||
// } ===== end non-poly methods imitating nsIMdbThumb =====
|
||||
|
||||
morkStore*
|
||||
morkThumb::ThumbToOpenStore(morkEnv* ev)
|
||||
// for orkinFactory::ThumbToOpenStore() after OpenFileStore()
|
||||
{
|
||||
return mThumb_Store;
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_OpenFilePort(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_OpenFileStore(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_ExportToFormat(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_ImportContent(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_LargeCommit(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_SessionCommit(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_CompressCommit(morkEnv* ev)
|
||||
{
|
||||
morkWriter* writer = mThumb_Writer;
|
||||
if ( writer )
|
||||
{
|
||||
writer->WriteMore(ev);
|
||||
mThumb_Total = writer->mWriter_TotalCount;
|
||||
mThumb_Current = writer->mWriter_DoneCount;
|
||||
mThumb_Done = ( ev->Bad() || writer->IsWritingDone() );
|
||||
mThumb_Broken = ev->Bad();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->NilThumbWriterError(ev);
|
||||
mThumb_Broken = morkBool_kTrue;
|
||||
mThumb_Done = morkBool_kTrue;
|
||||
}
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_SearchManyColumns(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_NewSortColumn(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_NewSortColumnWithCompare(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_CloneSortColumn(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_AddIndex(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
void morkThumb::DoMore_CutIndex(morkEnv* ev)
|
||||
{
|
||||
this->UnsupportedThumbMagicError(ev);
|
||||
}
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
176
mozilla/db/mork/src/morkThumb.h
Normal file
176
mozilla/db/mork/src/morkThumb.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKTHUMB_
|
||||
#define _MORKTHUMB_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKOBJECT_
|
||||
#include "morkObject.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
#define morkThumb_kMagic_OpenFilePort 1 /* factory method */
|
||||
#define morkThumb_kMagic_OpenFileStore 2 /* factory method */
|
||||
#define morkThumb_kMagic_ExportToFormat 3 /* port method */
|
||||
#define morkThumb_kMagic_ImportContent 4 /* store method */
|
||||
#define morkThumb_kMagic_LargeCommit 5 /* store method */
|
||||
#define morkThumb_kMagic_SessionCommit 6 /* store method */
|
||||
#define morkThumb_kMagic_CompressCommit 7 /* store method */
|
||||
#define morkThumb_kMagic_SearchManyColumns 8 /* table method */
|
||||
#define morkThumb_kMagic_NewSortColumn 9 /* table metho) */
|
||||
#define morkThumb_kMagic_NewSortColumnWithCompare 10 /* table method */
|
||||
#define morkThumb_kMagic_CloneSortColumn 11 /* table method */
|
||||
#define morkThumb_kMagic_AddIndex 12 /* table method */
|
||||
#define morkThumb_kMagic_CutIndex 13 /* table method */
|
||||
|
||||
#define morkDerived_kThumb /*i*/ 0x5468 /* ascii 'Th' */
|
||||
|
||||
/*| morkThumb:
|
||||
|*/
|
||||
class morkThumb : public morkObject {
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
// morkHandle* mObject_Handle; // weak ref to handle for this object
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
// might as well include all the return values here:
|
||||
|
||||
mork_magic mThumb_Magic; // magic sig different in each thumb type
|
||||
mork_count mThumb_Total;
|
||||
mork_count mThumb_Current;
|
||||
|
||||
mork_bool mThumb_Done;
|
||||
mork_bool mThumb_Broken;
|
||||
mork_u2 mThumb_Seed; // optional seed for u4 alignment padding
|
||||
|
||||
morkStore* mThumb_Store; // weak ref to created store
|
||||
morkFile* mThumb_File; // strong ref to file (store, import, export)
|
||||
morkWriter* mThumb_Writer; // strong ref to writer (for commit)
|
||||
morkPort* mThumb_SourcePort; // strong ref to port for import
|
||||
|
||||
mork_bool mThumb_DoCollect; // influence whether a collect happens
|
||||
mork_bool mThumb_Pad[ 3 ]; // padding for u4 alignment
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseThumb() only if open
|
||||
virtual ~morkThumb(); // assert that CloseThumb() executed earlier
|
||||
|
||||
public: // morkThumb construction & destruction
|
||||
morkThumb(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, nsIMdbHeap* ioSlotHeap, mork_magic inMagic);
|
||||
void CloseThumb(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkThumb(const morkThumb& other);
|
||||
morkThumb& operator=(const morkThumb& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsThumb() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kThumb; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonThumbTypeError(morkEnv* ev);
|
||||
static void UnsupportedThumbMagicError(morkEnv* ev);
|
||||
|
||||
static void NilThumbStoreError(morkEnv* ev);
|
||||
static void NilThumbFileError(morkEnv* ev);
|
||||
static void NilThumbWriterError(morkEnv* ev);
|
||||
static void NilThumbSourcePortError(morkEnv* ev);
|
||||
|
||||
public: // 'do more' methods
|
||||
|
||||
void DoMore_OpenFilePort(morkEnv* ev);
|
||||
void DoMore_OpenFileStore(morkEnv* ev);
|
||||
void DoMore_ExportToFormat(morkEnv* ev);
|
||||
void DoMore_ImportContent(morkEnv* ev);
|
||||
void DoMore_LargeCommit(morkEnv* ev);
|
||||
void DoMore_SessionCommit(morkEnv* ev);
|
||||
void DoMore_CompressCommit(morkEnv* ev);
|
||||
void DoMore_SearchManyColumns(morkEnv* ev);
|
||||
void DoMore_NewSortColumn(morkEnv* ev);
|
||||
void DoMore_NewSortColumnWithCompare(morkEnv* ev);
|
||||
void DoMore_CloneSortColumn(morkEnv* ev);
|
||||
void DoMore_AddIndex(morkEnv* ev);
|
||||
void DoMore_CutIndex(morkEnv* ev);
|
||||
|
||||
public: // other thumb methods
|
||||
|
||||
nsIMdbThumb* AcquireThumbHandle(morkEnv* ev); // mObject_Handle
|
||||
|
||||
morkStore* ThumbToOpenStore(morkEnv* ev);
|
||||
// for orkinFactory::ThumbToOpenStore() after OpenFileStore()
|
||||
|
||||
public: // assorted thumb constructors
|
||||
|
||||
static morkThumb* Make_OpenFileStore(morkEnv* ev,
|
||||
nsIMdbHeap* ioHeap,morkStore* ioStore);
|
||||
|
||||
static morkThumb* Make_CompressCommit(morkEnv* ev,
|
||||
nsIMdbHeap* ioHeap,morkStore* ioStore, mork_bool inDoCollect);
|
||||
|
||||
// { ===== begin non-poly methods imitating nsIMdbThumb =====
|
||||
void GetProgress(morkEnv* ev, mdb_count* outTotal,
|
||||
mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken);
|
||||
|
||||
void DoMore(morkEnv* ev, mdb_count* outTotal,
|
||||
mdb_count* outCurrent, mdb_bool* outDone, mdb_bool* outBroken);
|
||||
|
||||
void CancelAndBreakThumb(morkEnv* ev);
|
||||
// } ===== end non-poly methods imitating nsIMdbThumb =====
|
||||
|
||||
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakThumb(morkThumb* me,
|
||||
morkEnv* ev, morkThumb** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongThumb(morkThumb* me,
|
||||
morkEnv* ev, morkThumb** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKTHUMB_ */
|
||||
1293
mozilla/db/mork/src/morkWriter.cpp
Normal file
1293
mozilla/db/mork/src/morkWriter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
297
mozilla/db/mork/src/morkWriter.h
Normal file
297
mozilla/db/mork/src/morkWriter.h
Normal file
@@ -0,0 +1,297 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKWRITER_
|
||||
#define _MORKWRITER_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKMAP_
|
||||
#include "morkMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWMAP_
|
||||
#include "morkRowMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKTABLE_
|
||||
#include "morkTable.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMMAP_
|
||||
#include "morkAtomMap.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOMSPACE_
|
||||
#include "morkAtomSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTREAM_
|
||||
#include "morkStream.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
#define morkWriter_kStreamBufSize /*i*/ (16) /* buffer size for stream */
|
||||
|
||||
#define morkDerived_kWriter /*i*/ 0x5772 /* ascii 'Wr' */
|
||||
|
||||
#define morkWriter_kPhaseNothingDone 0 /* nothing has yet been done */
|
||||
#define morkWriter_kPhaseDirtyAllDone 1 /* DirtyAll() is done */
|
||||
#define morkWriter_kPhasePutHeaderDone 2 /* PutHeader() is done */
|
||||
|
||||
#define morkWriter_kPhaseRenumberAllDone 3 /* RenumberAll() is done */
|
||||
|
||||
#define morkWriter_kPhaseStoreAtomSpaces 4 /*mWriter_StoreAtomSpacesIter*/
|
||||
#define morkWriter_kPhaseAtomSpaceAtomAids 5 /*mWriter_AtomSpaceAtomAidsIter*/
|
||||
|
||||
#define morkWriter_kPhaseStoreRowSpacesTables 6 /*mWriter_StoreRowSpacesIter*/
|
||||
#define morkWriter_kPhaseRowSpaceTables 7 /*mWriter_RowSpaceTablesIter*/
|
||||
#define morkWriter_kPhaseTableRowArray 8 /*mWriter_TableRowArrayPos */
|
||||
|
||||
#define morkWriter_kPhaseStoreRowSpacesRows 9 /*mWriter_StoreRowSpacesIter*/
|
||||
#define morkWriter_kPhaseRowSpaceRows 10 /*mWriter_RowSpaceRowsIter*/
|
||||
|
||||
#define morkWriter_kPhaseContentDone 11 /* all content written */
|
||||
#define morkWriter_kPhaseWritingDone 12 /* everthing has been done */
|
||||
|
||||
#define morkWriter_kCountNumberOfPhases 13 /* part of mWrite_TotalCount */
|
||||
|
||||
#define morkWriter_kMaxColumnNameSize 128 /* longest writable col name */
|
||||
|
||||
#define morkWriter_kMaxIndent 48 /* default value for mWriter_MaxIndent */
|
||||
|
||||
#define morkWriter_kTableMetaCellDepth 4 /* */
|
||||
#define morkWriter_kTableMetaCellValueDepth 6 /* */
|
||||
|
||||
#define morkWriter_kDictMetaCellDepth 4 /* */
|
||||
#define morkWriter_kDictMetaCellValueDepth 6 /* */
|
||||
|
||||
#define morkWriter_kDictAliasDepth 2 /* */
|
||||
#define morkWriter_kDictAliasValueDepth 4 /* */
|
||||
|
||||
#define morkWriter_kRowDepth 2 /* */
|
||||
#define morkWriter_kRowCellDepth 4 /* */
|
||||
#define morkWriter_kRowCellValueDepth 6 /* */
|
||||
|
||||
class morkWriter : public morkNode { // row iterator
|
||||
|
||||
// public: // slots inherited from morkObject (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
|
||||
morkStore* mWriter_Store; // weak ref to committing store
|
||||
morkFile* mWriter_File; // strong ref to store's file
|
||||
morkFile* mWriter_Bud; // strong ref to bud of mWriter_File
|
||||
morkStream* mWriter_Stream; // strong ref to stream on bud file
|
||||
nsIMdbHeap* mWriter_SlotHeap; // strong ref to slot heap
|
||||
|
||||
mork_count mWriter_TotalCount; // count of all things to be written
|
||||
mork_count mWriter_DoneCount; // count of things already written
|
||||
|
||||
mork_size mWriter_LineSize; // length of current line being written
|
||||
mork_size mWriter_MaxIndent; // line size forcing a line break
|
||||
|
||||
mork_cscode mWriter_TableCharset; // current charset metainfo
|
||||
mork_scope mWriter_TableAtomScope; // current atom scope
|
||||
mork_scope mWriter_TableRowScope; // current row scope
|
||||
mork_scope mWriter_TableTableScope; // current table scope
|
||||
mork_scope mWriter_TableColumnScope; // current column scope
|
||||
mork_kind mWriter_TableKind; // current table kind
|
||||
|
||||
mork_cscode mWriter_RowCharset; // current charset metainfo
|
||||
mork_scope mWriter_RowAtomScope; // current atom scope
|
||||
mork_scope mWriter_RowScope; // current row scope
|
||||
|
||||
mork_cscode mWriter_DictCharset; // current charset metainfo
|
||||
mork_scope mWriter_DictAtomScope; // current atom scope
|
||||
|
||||
mork_bool mWriter_NeedDirtyAll; // need to call DirtyAll()
|
||||
mork_u1 mWriter_Phase; // status of writing process
|
||||
mork_bool mWriter_DidStartDict; // true when a dict has been started
|
||||
mork_bool mWriter_DidEndDict; // true when a dict has been ended
|
||||
|
||||
mork_pos mWriter_TableRowArrayPos; // index into mTable_RowArray
|
||||
|
||||
char mWriter_SafeNameBuf[ (morkWriter_kMaxColumnNameSize * 2) + 4 ];
|
||||
// Note: extra four bytes in ColNameBuf means we can always append to yarn
|
||||
|
||||
char mWriter_ColNameBuf[ morkWriter_kMaxColumnNameSize + 4 ];
|
||||
// Note: extra four bytes in ColNameBuf means we can always append to yarn
|
||||
|
||||
mdbYarn mWriter_ColYarn; // a yarn to describe space in ColNameBuf:
|
||||
// mYarn_Buf == mWriter_ColNameBuf, mYarn_Size == morkWriter_kMaxColumnNameSize
|
||||
|
||||
mdbYarn mWriter_SafeYarn; // a yarn to describe space in ColNameBuf:
|
||||
// mYarn_Buf == mWriter_SafeNameBuf, mYarn_Size == (kMaxColumnNameSize * 2)
|
||||
|
||||
morkAtomSpaceMapIter mWriter_StoreAtomSpacesIter; // for mStore_AtomSpaces
|
||||
morkAtomAidMapIter mWriter_AtomSpaceAtomAidsIter; // for AtomSpace_AtomAids
|
||||
|
||||
morkRowSpaceMapIter mWriter_StoreRowSpacesIter; // for mStore_RowSpaces
|
||||
morkTableMapIter mWriter_RowSpaceTablesIter; // for mRowSpace_Tables
|
||||
morkRowMapIter mWriter_RowSpaceRowsIter; // for mRowSpace_Rows
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseWriter()
|
||||
virtual ~morkWriter(); // assert that close executed earlier
|
||||
|
||||
public: // morkWriter construction & destruction
|
||||
morkWriter(morkEnv* ev, const morkUsage& inUsage,
|
||||
nsIMdbHeap* ioHeap, morkStore* ioStore, morkFile* ioFile,
|
||||
nsIMdbHeap* ioSlotHeap);
|
||||
void CloseWriter(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkWriter(const morkWriter& other);
|
||||
morkWriter& operator=(const morkWriter& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsWriter() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kWriter; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing & errors
|
||||
static void NonWriterTypeError(morkEnv* ev);
|
||||
static void NilWriterStoreError(morkEnv* ev);
|
||||
static void NilWriterBudError(morkEnv* ev);
|
||||
static void NilWriterStreamError(morkEnv* ev);
|
||||
static void UnsupportedPhaseError(morkEnv* ev);
|
||||
|
||||
public: // inlines
|
||||
mork_bool DidStartDict() const { return mWriter_DidStartDict; }
|
||||
mork_bool DidEndDict() const { return mWriter_DidEndDict; }
|
||||
|
||||
mork_bool NeedLineBreak() const
|
||||
{ return ( mWriter_LineSize > mWriter_MaxIndent ); }
|
||||
|
||||
void IndentAsNeeded(morkEnv* ev, mork_size inDepth)
|
||||
{
|
||||
if ( mWriter_LineSize > mWriter_MaxIndent )
|
||||
mWriter_LineSize = mWriter_Stream->PutIndent(ev, inDepth);
|
||||
}
|
||||
|
||||
public: // iterative/asynchronouse writing
|
||||
|
||||
mork_bool WriteMore(morkEnv* ev); // call until IsWritingDone() is true
|
||||
|
||||
mork_bool IsWritingDone() const // don't call WriteMore() any longer?
|
||||
{ return mWriter_Phase == morkWriter_kPhaseWritingDone; }
|
||||
|
||||
public: // marking all content dirty
|
||||
mork_bool DirtyAll(morkEnv* ev);
|
||||
// DirtyAll() visits every store sub-object and marks
|
||||
// them dirty, including every table, row, cell, and atom. The return
|
||||
// equals ev->Good(), to show whether any error happened. This method is
|
||||
// intended for use in the beginning of a "compress commit" which writes
|
||||
// all store content, whether dirty or not. We dirty everything first so
|
||||
// that later iterations over content can mark things clean as they are
|
||||
// written, and organize the process of serialization so that objects are
|
||||
// written only at need (because of being dirty). Note the method can
|
||||
// stop early when any error happens, since this will abort any commit.
|
||||
|
||||
public: // phase methods
|
||||
mork_bool OnNothingDone(morkEnv* ev);
|
||||
mork_bool OnDirtyAllDone(morkEnv* ev);
|
||||
mork_bool OnPutHeaderDone(morkEnv* ev);
|
||||
|
||||
mork_bool OnRenumberAllDone(morkEnv* ev);
|
||||
|
||||
mork_bool OnStoreAtomSpaces(morkEnv* ev);
|
||||
mork_bool OnAtomSpaceAtomAids(morkEnv* ev);
|
||||
|
||||
mork_bool OnStoreRowSpacesTables(morkEnv* ev);
|
||||
mork_bool OnRowSpaceTables(morkEnv* ev);
|
||||
mork_bool OnTableRowArray(morkEnv* ev);
|
||||
|
||||
mork_bool OnStoreRowSpacesRows(morkEnv* ev);
|
||||
mork_bool OnRowSpaceRows(morkEnv* ev);
|
||||
|
||||
mork_bool OnContentDone(morkEnv* ev);
|
||||
mork_bool OnWritingDone(morkEnv* ev);
|
||||
|
||||
public: // writing dict items first pass
|
||||
mork_bool PutTableDict(morkEnv* ev, morkTable* ioTable);
|
||||
mork_bool PutRowDict(morkEnv* ev, morkRow* ioRow);
|
||||
|
||||
public: // writing node content second pass
|
||||
mork_bool PutTable(morkEnv* ev, morkTable* ioTable);
|
||||
mork_bool PutRow(morkEnv* ev, morkRow* ioRow);
|
||||
mork_bool PutRowCells(morkEnv* ev, morkRow* ioRow);
|
||||
|
||||
public: // other writer methods
|
||||
|
||||
mork_size WriteYarn(morkEnv* ev, const mdbYarn* inYarn);
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire yarn's size, since only part goes on a last line).
|
||||
|
||||
mork_size WriteAtom(morkEnv* ev, const morkAtom* inAtom);
|
||||
// return number of atom bytes written on the current line (which
|
||||
// implies that escaped line breaks will make the size value smaller
|
||||
// than the entire atom's size, since only part goes on a last line).
|
||||
|
||||
void WriteAllStoreTables(morkEnv* ev);
|
||||
void WriteAtomSpaceAsDict(morkEnv* ev, morkAtomSpace* ioSpace);
|
||||
|
||||
void WriteTokenToTokenMetaCell(morkEnv* ev, mork_token inCol,
|
||||
mork_token inValue);
|
||||
void WriteStringToTokenDictCell(morkEnv* ev, const char* inCol,
|
||||
mork_token inValue);
|
||||
// Note inCol should begin with '(' and end with '=', with col in between.
|
||||
|
||||
void StartDict(morkEnv* ev);
|
||||
void EndDict(morkEnv* ev);
|
||||
|
||||
void StartTable(morkEnv* ev, morkTable* ioTable);
|
||||
void EndTable(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakWriter(morkWriter* me,
|
||||
morkEnv* ev, morkWriter** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongWriter(morkWriter* me,
|
||||
morkEnv* ev, morkWriter** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKTABLEROWCURSOR_ */
|
||||
93
mozilla/db/mork/src/morkYarn.cpp
Normal file
93
mozilla/db/mork/src/morkYarn.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKYARN_
|
||||
#include "morkYarn.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
// ````` ````` ````` ````` `````
|
||||
// { ===== begin morkNode interface =====
|
||||
|
||||
/*public virtual*/ void
|
||||
morkYarn::CloseMorkNode(morkEnv* ev) /*i*/ // CloseYarn() only if open
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
this->MarkClosing();
|
||||
this->CloseYarn(ev);
|
||||
this->MarkShut();
|
||||
}
|
||||
}
|
||||
|
||||
/*public virtual*/
|
||||
morkYarn::~morkYarn() /*i*/ // assert CloseYarn() executed earlier
|
||||
{
|
||||
MORK_ASSERT(mYarn_Body.mYarn_Buf==0);
|
||||
}
|
||||
|
||||
/*public non-poly*/
|
||||
morkYarn::morkYarn(morkEnv* ev, /*i*/
|
||||
const morkUsage& inUsage, nsIMdbHeap* ioHeap)
|
||||
: morkNode(ev, inUsage, ioHeap)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
mNode_Derived = morkDerived_kYarn;
|
||||
}
|
||||
|
||||
/*public non-poly*/ void
|
||||
morkYarn::CloseYarn(morkEnv* ev) /*i*/ // called by CloseMorkNode();
|
||||
{
|
||||
if ( this )
|
||||
{
|
||||
if ( this->IsNode() )
|
||||
this->MarkShut();
|
||||
else
|
||||
this->NonNodeError(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
}
|
||||
|
||||
// } ===== end morkNode methods =====
|
||||
// ````` ````` ````` ````` `````
|
||||
|
||||
/*static*/ void
|
||||
morkYarn::NonYarnTypeError(morkEnv* ev)
|
||||
{
|
||||
ev->NewError("non morkYarn");
|
||||
}
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
88
mozilla/db/mork/src/morkYarn.h
Normal file
88
mozilla/db/mork/src/morkYarn.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MORKYARN_
|
||||
#define _MORKYARN_ 1
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
|
||||
#define morkDerived_kYarn /*i*/ 0x7952 /* ascii 'yR' */
|
||||
|
||||
/*| morkYarn: a reference counted nsIMdbYarn C struct. This is for use in those
|
||||
**| few cases where single instances of reference counted buffers are needed
|
||||
**| in Mork, and we expect few enough instances that overhead is not a factor
|
||||
**| in decided whether to use such a thing.
|
||||
|*/
|
||||
class morkYarn : public morkNode { // refcounted yarn
|
||||
|
||||
// public: // slots inherited from morkNode (meant to inform only)
|
||||
// nsIMdbHeap* mNode_Heap;
|
||||
|
||||
// mork_base mNode_Base; // must equal morkBase_kNode
|
||||
// mork_derived mNode_Derived; // depends on specific node subclass
|
||||
|
||||
// mork_access mNode_Access; // kOpen, kClosing, kShut, or kDead
|
||||
// mork_usage mNode_Usage; // kHeap, kStack, kMember, kGlobal, kNone
|
||||
// mork_able mNode_Mutable; // can this node be modified?
|
||||
// mork_load mNode_Load; // is this node clean or dirty?
|
||||
|
||||
// mork_uses mNode_Uses; // refcount for strong refs
|
||||
// mork_refs mNode_Refs; // refcount for strong refs + weak refs
|
||||
|
||||
public: // state is public because the entire Mork system is private
|
||||
mdbYarn mYarn_Body;
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
virtual void CloseMorkNode(morkEnv* ev); // CloseYarn() only if open
|
||||
virtual ~morkYarn(); // assert that CloseYarn() executed earlier
|
||||
|
||||
public: // morkYarn construction & destruction
|
||||
morkYarn(morkEnv* ev, const morkUsage& inUsage, nsIMdbHeap* ioHeap);
|
||||
void CloseYarn(morkEnv* ev); // called by CloseMorkNode();
|
||||
|
||||
private: // copying is not allowed
|
||||
morkYarn(const morkYarn& other);
|
||||
morkYarn& operator=(const morkYarn& other);
|
||||
|
||||
public: // dynamic type identification
|
||||
mork_bool IsYarn() const
|
||||
{ return IsNode() && mNode_Derived == morkDerived_kYarn; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
public: // typing
|
||||
static void NonYarnTypeError(morkEnv* ev);
|
||||
|
||||
public: // typesafe refcounting inlines calling inherited morkNode methods
|
||||
static void SlotWeakYarn(morkYarn* me,
|
||||
morkEnv* ev, morkYarn** ioSlot)
|
||||
{ morkNode::SlotWeakNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
|
||||
static void SlotStrongYarn(morkYarn* me,
|
||||
morkEnv* ev, morkYarn** ioSlot)
|
||||
{ morkNode::SlotStrongNode((morkNode*) me, ev, (morkNode**) ioSlot); }
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _MORKYARN_ */
|
||||
673
mozilla/db/mork/src/orkinCell.cpp
Normal file
673
mozilla/db/mork/src/orkinCell.cpp
Normal file
@@ -0,0 +1,673 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELLOBJECT_
|
||||
#include "morkCellObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWOBJECT_
|
||||
#include "morkRowObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINCELL_
|
||||
#include "orkinCell.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKPOOL_
|
||||
#include "morkPool.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROW_
|
||||
#include "morkRow.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKATOM_
|
||||
#include "morkAtom.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSPACE_
|
||||
#include "morkSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKROWSPACE_
|
||||
#include "morkRowSpace.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKSTORE_
|
||||
#include "morkStore.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* public virtual*/
|
||||
orkinCell:: ~orkinCell() // morkHandle destructor does everything
|
||||
{
|
||||
}
|
||||
|
||||
/*protected non-poly construction*/
|
||||
orkinCell::orkinCell(morkEnv* ev, // morkUsage is morkUsage_kPool
|
||||
morkHandleFace* ioFace, // must not be nil, cookie for this handle
|
||||
morkCellObject* ioObject) // must not be nil, the object for this handle
|
||||
: morkHandle(ev, ioFace, ioObject, morkMagic_kCell)
|
||||
{
|
||||
// do not modify mNode_Derived; leave it equal to morkDerived_kHandle
|
||||
}
|
||||
|
||||
|
||||
/*static */ orkinCell*
|
||||
orkinCell::MakeCell(morkEnv* ev, morkCellObject* ioObject)
|
||||
{
|
||||
mork_bool isEnv = ev->IsEnv();
|
||||
MORK_ASSERT(isEnv);
|
||||
if ( isEnv )
|
||||
{
|
||||
morkHandleFace* face = ev->NewHandle(sizeof(orkinCell));
|
||||
if ( face )
|
||||
return new(face) orkinCell(ev, face, ioObject);
|
||||
else
|
||||
ev->OutOfMemoryError();
|
||||
}
|
||||
|
||||
return (orkinCell*) 0;
|
||||
}
|
||||
|
||||
// ResyncWithRow() moved to the morkCellObject class:
|
||||
// mork_bool
|
||||
// orkinCell::ResyncWithRow(morkEnv* ev)
|
||||
// {
|
||||
// morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
// morkRow* row = cellObj->mCellObject_Row;
|
||||
// mork_pos pos = 0;
|
||||
// morkCell* cell = row->GetCell(ev, cellObj->mCellObject_Col, &pos);
|
||||
// if ( cell )
|
||||
// {
|
||||
// cellObj->mCellObject_Pos = pos;
|
||||
// cellObj->mCellObject_Cell = cell;
|
||||
// cellObj->mCellObject_RowSeed = row->mRow_Seed;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// cellObj->mCellObject_Cell = 0;
|
||||
// cellObj->MissingRowColumnError(ev);
|
||||
// }
|
||||
// return ev->Good();
|
||||
// }
|
||||
|
||||
morkEnv*
|
||||
orkinCell::CanUseCell(nsIMdbEnv* mev, mork_bool inMutable,
|
||||
mdb_err* outErr, morkCell** outCell) const
|
||||
{
|
||||
morkEnv* outEnv = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = morkEnv::FromMdbEnv(mev);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*)
|
||||
this->GetGoodHandleObject(ev, inMutable, morkMagic_kCell);
|
||||
if ( cellObj )
|
||||
{
|
||||
if ( cellObj->IsCellObject() )
|
||||
{
|
||||
if ( cellObj->IsMutable() || !inMutable )
|
||||
{
|
||||
morkRowObject* rowObj = cellObj->mCellObject_RowObject;
|
||||
if ( rowObj )
|
||||
{
|
||||
morkRow* row = cellObj->mCellObject_Row;
|
||||
if ( row )
|
||||
{
|
||||
if ( rowObj->mRowObject_Row == row )
|
||||
{
|
||||
mork_u2 oldSeed = cellObj->mCellObject_RowSeed;
|
||||
if ( row->mRow_Seed == oldSeed || cellObj->ResyncWithRow(ev) )
|
||||
{
|
||||
cell = cellObj->mCellObject_Cell;
|
||||
if ( cell )
|
||||
{
|
||||
outEnv = ev;
|
||||
}
|
||||
else
|
||||
cellObj->NilCellError(ev);
|
||||
}
|
||||
}
|
||||
else
|
||||
cellObj->WrongRowObjectRowError(ev);
|
||||
}
|
||||
else
|
||||
cellObj->NilRowError(ev);
|
||||
}
|
||||
else
|
||||
cellObj->NilRowObjectError(ev);
|
||||
}
|
||||
else
|
||||
cellObj->NonMutableNodeError(ev);
|
||||
}
|
||||
else
|
||||
cellObj->NonCellObjectTypeError(ev);
|
||||
}
|
||||
*outErr = ev->AsErr();
|
||||
}
|
||||
MORK_ASSERT(outEnv);
|
||||
*outCell = cell;
|
||||
|
||||
return outEnv;
|
||||
}
|
||||
|
||||
|
||||
// { ===== begin nsIMdbISupports methods =====
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::AddRef() // add strong ref with no
|
||||
{
|
||||
morkEnv* ev = mHandle_Env;
|
||||
if ( ev && ev->IsEnv() )
|
||||
return this->Handle_AddStrongRef(ev->AsMdbEnv());
|
||||
else
|
||||
return morkEnv_kNonEnvTypeError;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::Release() // cut strong ref
|
||||
{
|
||||
morkEnv* ev = mHandle_Env;
|
||||
if ( ev && ev->IsEnv() )
|
||||
return this->Handle_CutStrongRef(ev->AsMdbEnv());
|
||||
else
|
||||
return morkEnv_kNonEnvTypeError;
|
||||
}
|
||||
// } ===== end nsIMdbISupports methods =====
|
||||
|
||||
// { ===== begin nsIMdbObject methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
|
||||
{
|
||||
return this->Handle_IsFrozenMdbObject(mev, outIsReadonly);
|
||||
}
|
||||
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin factory methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
|
||||
{
|
||||
return this->Handle_GetMdbFactory(mev, acqFactory);
|
||||
}
|
||||
// } ----- end factory methods -----
|
||||
|
||||
// { ----- begin ref counting for well-behaved cyclic graphs -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetWeakRefCount(nsIMdbEnv* mev, // weak refs
|
||||
mdb_count* outCount)
|
||||
{
|
||||
return this->Handle_GetWeakRefCount(mev, outCount);
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetStrongRefCount(nsIMdbEnv* mev, // strong refs
|
||||
mdb_count* outCount)
|
||||
{
|
||||
return this->Handle_GetStrongRefCount(mev, outCount);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::AddWeakRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_AddWeakRef(mev);
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::AddStrongRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_AddStrongRef(mev);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::CutWeakRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_CutWeakRef(mev);
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::CutStrongRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_CutStrongRef(mev);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::CloseMdbObject(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_CloseMdbObject(mev);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
||||
{
|
||||
return this->Handle_IsOpenMdbObject(mev, outOpen);
|
||||
}
|
||||
// } ----- end ref counting -----
|
||||
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
// { ===== begin nsIMdbBlob methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::SetBlob(nsIMdbEnv* mev,
|
||||
nsIMdbBlob* ioBlob)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
} // reads inBlob slots
|
||||
// when inBlob is in the same suite, this might be fastest cell-to-cell
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::ClearBlob( // make empty (so content has zero length)
|
||||
nsIMdbEnv* mev)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
// clearing a yarn is like SetYarn() with empty yarn instance content
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetBlobFill(nsIMdbEnv* mev,
|
||||
mdb_fill* outFill)
|
||||
// Same value that would be put into mYarn_Fill, if one called GetYarn()
|
||||
// with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
} // size of blob
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::SetYarn(nsIMdbEnv* mev,
|
||||
const mdbYarn* inYarn)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
morkRow* row = cellObj->mCellObject_Row;
|
||||
if ( row )
|
||||
{
|
||||
morkStore* store = row->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
cell->SetYarn(ev, inYarn, store);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
} // reads from yarn slots
|
||||
// make this text object contain content from the yarn's buffer
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetYarn(nsIMdbEnv* mev,
|
||||
mdbYarn* outYarn)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkAtom* atom = cell->GetAtom();
|
||||
atom->GetYarn(outYarn);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
} // writes some yarn slots
|
||||
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::AliasYarn(nsIMdbEnv* mev,
|
||||
mdbYarn* outYarn)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkAtom* atom = cell->GetAtom();
|
||||
atom->AliasYarn(outYarn);
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
} // writes ALL yarn slots
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// } ===== end nsIMdbBlob methods =====
|
||||
|
||||
// { ===== begin nsIMdbCell methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::SetColumn(nsIMdbEnv* mev, mdb_column inColumn)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetColumn(nsIMdbEnv* mev, mdb_column* outColumn)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_column col = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
col = cellObj->mCellObject_Col;
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outColumn )
|
||||
*outColumn = col;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetCellInfo( // all cell metainfo except actual content
|
||||
nsIMdbEnv* mev,
|
||||
mdb_column* outColumn, // the column in the containing row
|
||||
mdb_fill* outBlobFill, // the size of text content in bytes
|
||||
mdbOid* outChildOid, // oid of possible row or table child
|
||||
mdb_bool* outIsRowChild) // nonzero if child, and a row child
|
||||
// Checking all cell metainfo is a good way to avoid forcing a large cell
|
||||
// in to memory when you don't actually want to use the content.
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetRow(nsIMdbEnv* mev, // parent row for this cell
|
||||
nsIMdbRow** acqRow)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
morkRowObject* rowObj = cellObj->mCellObject_RowObject;
|
||||
outRow = rowObj->AcquireRowHandle(ev);
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
return outErr;
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetPort(nsIMdbEnv* mev, // port containing cell
|
||||
nsIMdbPort** acqPort)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbPort* outPort = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
morkRow* row = cellObj->mCellObject_Row;
|
||||
if ( row )
|
||||
{
|
||||
morkStore* store = row->GetRowSpaceStore(ev);
|
||||
if ( store )
|
||||
outPort = store->AcquireStoreHandle(ev);
|
||||
}
|
||||
else
|
||||
ev->NilPointerError();
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( acqPort )
|
||||
*acqPort = outPort;
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin children methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::HasAnyChild( // does cell have a child instead of text?
|
||||
nsIMdbEnv* mev,
|
||||
mdbOid* outOid, // out id of row or table (or unbound if no child)
|
||||
mdb_bool* outIsRow) // nonzero if child is a row (rather than a table)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_bool isRow = morkBool_kFalse;
|
||||
outOid->mOid_Scope = 0;
|
||||
outOid->mOid_Id = morkId_kMinusOne;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
morkAtom* atom = cellObj->GetCellAtom(ev);
|
||||
if ( atom )
|
||||
{
|
||||
isRow = atom->IsRowOid();
|
||||
if ( isRow || atom->IsTableOid() )
|
||||
*outOid = ((morkOidAtom*) atom)->mOidAtom_Oid;
|
||||
}
|
||||
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
if ( outIsRow )
|
||||
*outIsRow = isRow;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetAnyChild( // access table of specific attribute
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow** acqRow, // child row (or null)
|
||||
nsIMdbTable** acqTable) // child table (or null)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbRow* outRow = 0;
|
||||
nsIMdbTable* outTable = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
MORK_ASSERT(acqTable);
|
||||
if ( acqTable )
|
||||
*acqTable = outTable;
|
||||
MORK_ASSERT(acqRow);
|
||||
if ( acqRow )
|
||||
*acqRow = outRow;
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::SetChildRow( // access table of specific attribute
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow* ioRow)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
} // inRow must be bound inside this same db port
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetChildRow( // access row of specific attribute
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbRow** acqRow) // acquire child row (or nil if no child)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::SetChildTable( // access table of specific attribute
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbTable* inTable) // table must be bound inside this same db port
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinCell::GetChildTable( // access table of specific attribute
|
||||
nsIMdbEnv* mev, // context
|
||||
nsIMdbTable** acqTable) // acquire child tabdle (or nil if no chil)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkCell* cell = 0;
|
||||
morkEnv* ev = this->CanUseCell(mev, /*inMutable*/ morkBool_kTrue,
|
||||
&outErr, &cell);
|
||||
if ( ev )
|
||||
{
|
||||
morkCellObject* cellObj = (morkCellObject*) mHandle_Object;
|
||||
ev->StubMethodOnlyError();
|
||||
outErr = ev->AsErr();
|
||||
}
|
||||
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end children methods -----
|
||||
|
||||
// } ===== end nsIMdbCell methods =====
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
253
mozilla/db/mork/src/orkinCell.h
Normal file
253
mozilla/db/mork/src/orkinCell.h
Normal file
@@ -0,0 +1,253 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ORKINCELL_
|
||||
#define _ORKINCELL_ 1
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKCELL_
|
||||
#include "morkCell.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkMagic_kCell 0x43656C6C /* ascii 'Cell' */
|
||||
|
||||
class orkinCell : public morkHandle, public nsIMdbCell { // nsIMdbBlob
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
// virtual void CloseMorkNode(morkEnv* ev); // morkHandle is fine
|
||||
virtual ~orkinCell(); // morkHandle destructor does everything
|
||||
|
||||
protected: // construction is protected (use the static Make() method)
|
||||
orkinCell(morkEnv* ev, // note morkUsage is always morkUsage_kPool
|
||||
morkHandleFace* ioFace, // must not be nil, cookie for this handle
|
||||
morkCellObject* ioObject); // must not be nil, the object for this handle
|
||||
|
||||
// void CloseHandle(morkEnv* ev); // don't need to specialize closing
|
||||
|
||||
private: // copying is not allowed
|
||||
orkinCell(const morkHandle& other);
|
||||
orkinCell& operator=(const morkHandle& other);
|
||||
|
||||
// public: // dynamic type identification
|
||||
// mork_bool IsHandle() const //
|
||||
// { return IsNode() && mNode_Derived == morkDerived_kHandle; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
protected: // morkHandle memory management operators
|
||||
void* operator new(size_t inSize, morkPool& ioPool, morkEnv* ev)
|
||||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
// do NOT call delete on morkHandle instances. They are collected.
|
||||
|
||||
public: // construction:
|
||||
|
||||
static orkinCell* MakeCell(morkEnv* ev, morkCellObject* ioObject);
|
||||
|
||||
public: // utilities:
|
||||
|
||||
// ResyncWithRow() moved to the morkCellObject class:
|
||||
// mork_bool ResyncWithRow(morkEnv* ev); // return ev->Good()
|
||||
|
||||
morkEnv* CanUseCell(nsIMdbEnv* ev, mork_bool inMutable,
|
||||
mdb_err* outErr, morkCell** outCell) const;
|
||||
|
||||
public: // type identification
|
||||
mork_bool IsOrkinCell() const
|
||||
{ return mHandle_Magic == morkMagic_kCell; }
|
||||
|
||||
mork_bool IsOrkinCellHandle() const
|
||||
{ return this->IsHandle() && this->IsOrkinCell(); }
|
||||
|
||||
// { ===== begin nsIMdbISupports methods =====
|
||||
virtual mdb_err AddRef(); // add strong ref with no
|
||||
virtual mdb_err Release(); // cut strong ref
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
// { ===== begin nsIMdbObject methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
virtual mdb_err IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly);
|
||||
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin factory methods -----
|
||||
virtual mdb_err GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory);
|
||||
// } ----- end factory methods -----
|
||||
|
||||
// { ----- begin ref counting for well-behaved cyclic graphs -----
|
||||
virtual mdb_err GetWeakRefCount(nsIMdbEnv* ev, // weak refs
|
||||
mdb_count* outCount);
|
||||
virtual mdb_err GetStrongRefCount(nsIMdbEnv* ev, // strong refs
|
||||
mdb_count* outCount);
|
||||
|
||||
virtual mdb_err AddWeakRef(nsIMdbEnv* ev);
|
||||
virtual mdb_err AddStrongRef(nsIMdbEnv* ev);
|
||||
|
||||
virtual mdb_err CutWeakRef(nsIMdbEnv* ev);
|
||||
virtual mdb_err CutStrongRef(nsIMdbEnv* ev);
|
||||
|
||||
virtual mdb_err CloseMdbObject(nsIMdbEnv* ev); // called at strong refs zero
|
||||
virtual mdb_err IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen);
|
||||
// } ----- end ref counting -----
|
||||
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
// { ===== begin nsIMdbBlob methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
virtual mdb_err SetBlob(nsIMdbEnv* ev,
|
||||
nsIMdbBlob* ioBlob); // reads inBlob slots
|
||||
// when inBlob is in the same suite, this might be fastest cell-to-cell
|
||||
|
||||
virtual mdb_err ClearBlob( // make empty (so content has zero length)
|
||||
nsIMdbEnv* ev);
|
||||
// clearing a yarn is like SetYarn() with empty yarn instance content
|
||||
|
||||
virtual mdb_err GetBlobFill(nsIMdbEnv* ev,
|
||||
mdb_fill* outFill); // size of blob
|
||||
// Same value that would be put into mYarn_Fill, if one called GetYarn()
|
||||
// with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
|
||||
|
||||
virtual mdb_err SetYarn(nsIMdbEnv* ev,
|
||||
const mdbYarn* inYarn); // reads from yarn slots
|
||||
// make this text object contain content from the yarn's buffer
|
||||
|
||||
virtual mdb_err GetYarn(nsIMdbEnv* ev,
|
||||
mdbYarn* outYarn); // writes some yarn slots
|
||||
// copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
|
||||
|
||||
virtual mdb_err AliasYarn(nsIMdbEnv* ev,
|
||||
mdbYarn* outYarn); // writes ALL yarn slots
|
||||
// AliasYarn() reveals sensitive internal text buffer state to the caller
|
||||
// by setting mYarn_Buf to point into the guts of this text implementation.
|
||||
//
|
||||
// The caller must take great care to avoid writing on this space, and to
|
||||
// avoid calling any method that would cause the state of this text object
|
||||
// to change (say by directly or indirectly setting the text to hold more
|
||||
// content that might grow the size of the buffer and free the old buffer).
|
||||
// In particular, callers should scrupulously avoid making calls into the
|
||||
// mdb interface to write any content while using the buffer pointer found
|
||||
// in the returned yarn instance. Best safe usage involves copying content
|
||||
// into some other kind of external content representation beyond mdb.
|
||||
//
|
||||
// (The original design of this method a week earlier included the concept
|
||||
// of very fast and efficient cooperative locking via a pointer to some lock
|
||||
// member slot. But let's ignore that complexity in the current design.)
|
||||
//
|
||||
// AliasYarn() is specifically intended as the first step in transferring
|
||||
// content from nsIMdbBlob to a nsString representation, without forcing extra
|
||||
// allocations and/or memory copies. (A standard nsIMdbBlob_AsString() utility
|
||||
// will use AliasYarn() as the first step in setting a nsString instance.)
|
||||
//
|
||||
// This is an alternative to the GetYarn() method, which has copy semantics
|
||||
// only; AliasYarn() relaxes a robust safety principle only for performance
|
||||
// reasons, to accomodate the need for callers to transform text content to
|
||||
// some other canonical representation that would necessitate an additional
|
||||
// copy and transformation when such is incompatible with the mdbYarn format.
|
||||
//
|
||||
// The implementation of AliasYarn() should have extremely little overhead
|
||||
// besides the virtual dispatch to the method implementation, and the code
|
||||
// necessary to populate all the mdbYarn member slots with internal buffer
|
||||
// address and metainformation that describes the buffer content. Note that
|
||||
// mYarn_Grow must always be set to nil to indicate no resizing is allowed.
|
||||
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// } ===== end nsIMdbBlob methods =====
|
||||
|
||||
// { ===== begin nsIMdbCell methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
virtual mdb_err SetColumn(nsIMdbEnv* ev, mdb_column inColumn);
|
||||
virtual mdb_err GetColumn(nsIMdbEnv* ev, mdb_column* outColumn);
|
||||
|
||||
virtual mdb_err GetCellInfo( // all cell metainfo except actual content
|
||||
nsIMdbEnv* ev,
|
||||
mdb_column* outColumn, // the column in the containing row
|
||||
mdb_fill* outBlobFill, // the size of text content in bytes
|
||||
mdbOid* outChildOid, // oid of possible row or table child
|
||||
mdb_bool* outIsRowChild); // nonzero if child, and a row child
|
||||
|
||||
// Checking all cell metainfo is a good way to avoid forcing a large cell
|
||||
// in to memory when you don't actually want to use the content.
|
||||
|
||||
virtual mdb_err GetRow(nsIMdbEnv* ev, // parent row for this cell
|
||||
nsIMdbRow** acqRow);
|
||||
virtual mdb_err GetPort(nsIMdbEnv* ev, // port containing cell
|
||||
nsIMdbPort** acqPort);
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin children methods -----
|
||||
virtual mdb_err HasAnyChild( // does cell have a child instead of text?
|
||||
nsIMdbEnv* ev,
|
||||
mdbOid* outOid, // out id of row or table (or unbound if no child)
|
||||
mdb_bool* outIsRow); // nonzero if child is a row (rather than a table)
|
||||
|
||||
virtual mdb_err GetAnyChild( // access table of specific attribute
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow** acqRow, // child row (or null)
|
||||
nsIMdbTable** acqTable); // child table (or null)
|
||||
|
||||
|
||||
virtual mdb_err SetChildRow( // access table of specific attribute
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow* ioRow); // inRow must be bound inside this same db port
|
||||
|
||||
virtual mdb_err GetChildRow( // access row of specific attribute
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbRow** acqRow); // acquire child row (or nil if no child)
|
||||
|
||||
|
||||
virtual mdb_err SetChildTable( // access table of specific attribute
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbTable* inTable); // table must be bound inside this same db port
|
||||
|
||||
virtual mdb_err GetChildTable( // access table of specific attribute
|
||||
nsIMdbEnv* ev, // context
|
||||
nsIMdbTable** acqTable); // acquire child table (or nil if no child)
|
||||
// } ----- end children methods -----
|
||||
|
||||
// } ===== end nsIMdbCell methods =====
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _ORKINCELL_ */
|
||||
405
mozilla/db/mork/src/orkinEnv.cpp
Normal file
405
mozilla/db/mork/src/orkinEnv.cpp
Normal file
@@ -0,0 +1,405 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKENV_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ORKINENV_
|
||||
#include "orkinEnv.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
/* public virtual*/
|
||||
orkinEnv:: ~orkinEnv() // morkHandle destructor does everything
|
||||
{
|
||||
}
|
||||
|
||||
/*protected non-poly construction*/
|
||||
orkinEnv::orkinEnv(morkEnv* ev, // morkUsage is morkUsage_kPool
|
||||
morkHandleFace* ioFace, // must not be nil, cookie for this handle
|
||||
morkEnv* ioObject) // must not be nil, the object for this handle
|
||||
: morkHandle(ev, ioFace, ioObject, morkMagic_kEnv)
|
||||
{
|
||||
// do not modify mNode_Derived; leave it equal to morkDerived_kHandle
|
||||
}
|
||||
|
||||
|
||||
/*static */ orkinEnv*
|
||||
orkinEnv::MakeEnv(morkEnv* ev, morkEnv* ioObject)
|
||||
{
|
||||
mork_bool isEnv = ev->IsEnv();
|
||||
MORK_ASSERT(isEnv);
|
||||
if ( isEnv )
|
||||
{
|
||||
morkHandleFace* face = ev->NewHandle(sizeof(orkinEnv));
|
||||
if ( face )
|
||||
return new(face) orkinEnv(ev, face, ioObject);
|
||||
else
|
||||
ev->OutOfMemoryError();
|
||||
}
|
||||
|
||||
return (orkinEnv*) 0;
|
||||
}
|
||||
|
||||
morkEnv*
|
||||
orkinEnv::CanUseEnv(mork_bool inMutable, mdb_err* outErr) const
|
||||
{
|
||||
morkEnv* outEnv = 0;
|
||||
mdb_err err = morkEnv_kBadEnvError;
|
||||
if ( this->IsHandle() )
|
||||
{
|
||||
if ( this->IsOpenNode() )
|
||||
{
|
||||
morkEnv* ev = (morkEnv*) this->mHandle_Object;
|
||||
if ( ev && ev->IsEnv() )
|
||||
{
|
||||
outEnv = ev;
|
||||
err = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = morkEnv_kNonEnvTypeError;
|
||||
MORK_ASSERT(outEnv);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = morkEnv_kNonOpenNodeError;
|
||||
MORK_ASSERT(outEnv);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = morkEnv_kNonHandleTypeError;
|
||||
MORK_ASSERT(outEnv);
|
||||
}
|
||||
*outErr = err;
|
||||
return outEnv;
|
||||
}
|
||||
|
||||
|
||||
// { ===== begin nsIMdbISupports methods =====
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::AddRef() // add strong ref with no
|
||||
{
|
||||
morkEnv* ev = mHandle_Env;
|
||||
if ( ev && ev->IsEnv() )
|
||||
return this->Handle_AddStrongRef(ev->AsMdbEnv());
|
||||
else
|
||||
return morkEnv_kNonEnvTypeError;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::Release() // cut strong ref
|
||||
{
|
||||
morkEnv* ev = mHandle_Env;
|
||||
if ( ev && ev->IsEnv() )
|
||||
return this->Handle_CutStrongRef(ev->AsMdbEnv());
|
||||
else
|
||||
return morkEnv_kNonEnvTypeError;
|
||||
}
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
// { ===== begin nsIMdbObject methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::IsFrozenMdbObject(nsIMdbEnv* mev, mdb_bool* outIsReadonly)
|
||||
{
|
||||
return this->Handle_IsFrozenMdbObject(mev, outIsReadonly);
|
||||
}
|
||||
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin factory methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetMdbFactory(nsIMdbEnv* mev, nsIMdbFactory** acqFactory)
|
||||
{
|
||||
return this->Handle_GetMdbFactory(mev, acqFactory);
|
||||
}
|
||||
// } ----- end factory methods -----
|
||||
|
||||
// { ----- begin ref counting for well-behaved cyclic graphs -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetWeakRefCount(nsIMdbEnv* mev, // weak refs
|
||||
mdb_count* outCount)
|
||||
{
|
||||
return this->Handle_GetWeakRefCount(mev, outCount);
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetStrongRefCount(nsIMdbEnv* mev, // strong refs
|
||||
mdb_count* outCount)
|
||||
{
|
||||
return this->Handle_GetStrongRefCount(mev, outCount);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::AddWeakRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_AddWeakRef(mev);
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::AddStrongRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_AddStrongRef(mev);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::CutWeakRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_CutWeakRef(mev);
|
||||
}
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::CutStrongRef(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_CutStrongRef(mev);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::CloseMdbObject(nsIMdbEnv* mev)
|
||||
{
|
||||
return this->Handle_CloseMdbObject(mev);
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::IsOpenMdbObject(nsIMdbEnv* mev, mdb_bool* outOpen)
|
||||
{
|
||||
return this->Handle_IsOpenMdbObject(mev, outOpen);
|
||||
}
|
||||
// } ----- end ref counting -----
|
||||
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
// { ===== begin nsIMdbEnv methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetErrorCount(mdb_count* outCount,
|
||||
mdb_bool* outShouldAbort)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_count count = 1;
|
||||
mork_bool shouldAbort = morkBool_kFalse;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
count = (mdb_count) ev->mEnv_ErrorCount;
|
||||
shouldAbort = ev->mEnv_ShouldAbort;
|
||||
}
|
||||
if ( outCount )
|
||||
*outCount = count;
|
||||
if ( outShouldAbort )
|
||||
*outShouldAbort = shouldAbort;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetWarningCount(mdb_count* outCount,
|
||||
mdb_bool* outShouldAbort)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mdb_count count = 1;
|
||||
mork_bool shouldAbort = morkBool_kFalse;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
count = (mdb_count) ev->mEnv_WarningCount;
|
||||
shouldAbort = ev->mEnv_ShouldAbort;
|
||||
}
|
||||
if ( outCount )
|
||||
*outCount = count;
|
||||
if ( outShouldAbort )
|
||||
*outShouldAbort = shouldAbort;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetDoTrace(mdb_bool* outDoTrace)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mork_bool doTrace = morkBool_kFalse;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
doTrace = ev->mEnv_DoTrace;
|
||||
}
|
||||
if ( outDoTrace )
|
||||
*outDoTrace = doTrace;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::SetDoTrace(mdb_bool inDoTrace)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kTrue, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->mEnv_DoTrace = inDoTrace;
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetAutoClear(mdb_bool* outAutoClear)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
mork_bool autoClear = morkBool_kFalse;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
autoClear = ev->DoAutoClear();
|
||||
}
|
||||
if ( outAutoClear )
|
||||
*outAutoClear = autoClear;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::SetAutoClear(mdb_bool inAutoClear)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kTrue, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
if ( inAutoClear )
|
||||
ev->EnableAutoClear();
|
||||
else
|
||||
ev->DisableAutoClear();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetErrorHook(nsIMdbErrorHook** acqErrorHook)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbErrorHook* outErrorHook = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
outErrorHook = ev->mEnv_ErrorHook;
|
||||
}
|
||||
if ( acqErrorHook )
|
||||
*acqErrorHook = outErrorHook;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::SetErrorHook(
|
||||
nsIMdbErrorHook* ioErrorHook) // becomes referenced
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kTrue, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->mEnv_ErrorHook = ioErrorHook;
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::GetHeap(nsIMdbHeap** acqHeap)
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
nsIMdbHeap* outHeap = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kFalse, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
nsIMdbHeap* heap = ev->mEnv_Heap;
|
||||
if ( heap && heap->AddStrongRef(this) == 0 )
|
||||
outHeap = heap;
|
||||
}
|
||||
if ( acqHeap )
|
||||
*acqHeap = outHeap;
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::SetHeap(
|
||||
nsIMdbHeap* ioHeap) // becomes referenced
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kTrue, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
nsIMdbHeap_SlotStrongHeap(ioHeap, ev, &ev->mEnv_Heap);
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::ClearErrors() // clear errors beore re-entering db API
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kTrue, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->mEnv_ErrorCount = 0;
|
||||
ev->mEnv_ErrorCode = 0;
|
||||
ev->mEnv_ShouldAbort = morkBool_kFalse;
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::ClearWarnings() // clear warning
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kTrue, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->mEnv_WarningCount = 0;
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
|
||||
/*virtual*/ mdb_err
|
||||
orkinEnv::ClearErrorsAndWarnings() // clear both errors & warnings
|
||||
{
|
||||
mdb_err outErr = 0;
|
||||
morkEnv* ev = this->CanUseEnv(/*inMutable*/ morkBool_kTrue, &outErr);
|
||||
if ( ev )
|
||||
{
|
||||
ev->ClearMorkErrorsAndWarnings();
|
||||
}
|
||||
return outErr;
|
||||
}
|
||||
// } ===== end nsIMdbEnv methods =====
|
||||
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
164
mozilla/db/mork/src/orkinEnv.h
Normal file
164
mozilla/db/mork/src/orkinEnv.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ORKINENV_
|
||||
#define _ORKINENV_ 1
|
||||
|
||||
#ifndef _MDB_
|
||||
#include "mdb.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORK_
|
||||
#include "mork.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKNODE_
|
||||
#include "morkNode.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKHANDLE_
|
||||
#include "morkHandle.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MORKEnv_
|
||||
#include "morkEnv.h"
|
||||
#endif
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#define morkMagic_kEnv 0x456E7669 /* ascii 'Envi' */
|
||||
|
||||
/*| orkinEnv:
|
||||
|*/
|
||||
class orkinEnv : public morkHandle, public nsIMdbEnv { // nsIMdbObject
|
||||
|
||||
// { ===== begin morkNode interface =====
|
||||
public: // morkNode virtual methods
|
||||
// virtual void CloseMorkNode(morkEnv* ev); // morkHandle is fine
|
||||
virtual ~orkinEnv(); // morkHandle destructor does everything
|
||||
|
||||
protected: // construction is protected (use the static Make() method)
|
||||
orkinEnv(morkEnv* ev, // note morkUsage is always morkUsage_kPool
|
||||
morkHandleFace* ioFace, // must not be nil, cookie for this handle
|
||||
morkEnv* ioObject); // must not be nil, the object for this handle
|
||||
|
||||
// void CloseHandle(morkEnv* ev); // don't need to specialize closing
|
||||
|
||||
private: // copying is not allowed
|
||||
orkinEnv(const morkHandle& other);
|
||||
orkinEnv& operator=(const morkHandle& other);
|
||||
|
||||
// public: // dynamic type identification
|
||||
// mork_bool IsHandle() const //
|
||||
// { return IsNode() && mNode_Derived == morkDerived_kHandle; }
|
||||
// } ===== end morkNode methods =====
|
||||
|
||||
protected: // morkHandle memory management operators
|
||||
void* operator new(size_t inSize, morkPool& ioPool, morkEnv* ev)
|
||||
{ return ioPool.NewHandle(ev, inSize); }
|
||||
|
||||
void* operator new(size_t inSize, morkHandleFace* ioFace)
|
||||
{ return ioFace; }
|
||||
|
||||
void operator delete(void* ioAddress)
|
||||
{ morkNode::OnDeleteAssert(ioAddress); }
|
||||
// do NOT call delete on morkHandle instances. They are collected.
|
||||
|
||||
public: // construction:
|
||||
|
||||
static orkinEnv* MakeEnv(morkEnv* ev, morkEnv* ioObject);
|
||||
|
||||
public: // utilities:
|
||||
|
||||
morkEnv* CanUseEnv(mork_bool inMutable, mdb_err* outErr) const;
|
||||
|
||||
public: // type identification
|
||||
mork_bool IsOrkinEnv() const
|
||||
{ return mHandle_Magic == morkMagic_kEnv; }
|
||||
|
||||
mork_bool IsOrkinEnvHandle() const
|
||||
{ return this->IsHandle() && this->IsOrkinEnv(); }
|
||||
|
||||
public:
|
||||
|
||||
// { ===== begin nsIMdbISupports methods =====
|
||||
virtual mdb_err AddRef(); // add strong ref with no
|
||||
virtual mdb_err Release(); // cut strong ref
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
// { ===== begin nsIMdbObject methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
virtual mdb_err IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly);
|
||||
// same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
// { ----- begin factory methods -----
|
||||
virtual mdb_err GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory);
|
||||
// } ----- end factory methods -----
|
||||
|
||||
// { ----- begin ref counting for well-behaved cyclic graphs -----
|
||||
virtual mdb_err GetWeakRefCount(nsIMdbEnv* ev, // weak refs
|
||||
mdb_count* outCount);
|
||||
virtual mdb_err GetStrongRefCount(nsIMdbEnv* ev, // strong refs
|
||||
mdb_count* outCount);
|
||||
|
||||
virtual mdb_err AddWeakRef(nsIMdbEnv* ev);
|
||||
virtual mdb_err AddStrongRef(nsIMdbEnv* ev);
|
||||
|
||||
virtual mdb_err CutWeakRef(nsIMdbEnv* ev);
|
||||
virtual mdb_err CutStrongRef(nsIMdbEnv* ev);
|
||||
|
||||
virtual mdb_err CloseMdbObject(nsIMdbEnv* ev); // called at strong refs zero
|
||||
virtual mdb_err IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen);
|
||||
// } ----- end ref counting -----
|
||||
|
||||
// } ===== end nsIMdbObject methods =====
|
||||
|
||||
// { ===== begin nsIMdbEnv methods =====
|
||||
|
||||
// { ----- begin attribute methods -----
|
||||
virtual mdb_err GetErrorCount(mdb_count* outCount,
|
||||
mdb_bool* outShouldAbort);
|
||||
virtual mdb_err GetWarningCount(mdb_count* outCount,
|
||||
mdb_bool* outShouldAbort);
|
||||
|
||||
virtual mdb_err GetDoTrace(mdb_bool* outDoTrace);
|
||||
virtual mdb_err SetDoTrace(mdb_bool inDoTrace);
|
||||
|
||||
virtual mdb_err GetAutoClear(mdb_bool* outAutoClear);
|
||||
virtual mdb_err SetAutoClear(mdb_bool inAutoClear);
|
||||
|
||||
virtual mdb_err GetErrorHook(nsIMdbErrorHook** acqErrorHook);
|
||||
virtual mdb_err SetErrorHook(
|
||||
nsIMdbErrorHook* ioErrorHook); // becomes referenced
|
||||
|
||||
virtual mdb_err GetHeap(nsIMdbHeap** acqHeap);
|
||||
virtual mdb_err SetHeap(
|
||||
nsIMdbHeap* ioHeap); // becomes referenced
|
||||
// } ----- end attribute methods -----
|
||||
|
||||
virtual mdb_err ClearErrors(); // clear errors beore re-entering db API
|
||||
virtual mdb_err ClearWarnings(); // clear warnings
|
||||
virtual mdb_err ClearErrorsAndWarnings(); // clear both errors & warnings
|
||||
// } ===== end nsIMdbEnv methods =====
|
||||
};
|
||||
|
||||
//3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
|
||||
|
||||
#endif /* _ORKINENV_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user