Compare commits

..

24 Commits

Author SHA1 Message Date
law%netscape.com
dd7437a096 Add libplc21.lib to get PL_ functions
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21544 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:29:32 +00:00
mcmullen%netscape.com
a6041e3d9e Bringing nsCOMPtr.cpp from trunk.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21538 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:06:14 +00:00
mcmullen%netscape.com
467456baed Added nsRegistry::GetFactory()
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21537 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:05:28 +00:00
law%netscape.com
07adb3fa4c Pull changes on tip to branch
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21526 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 01:11:27 +00:00
law%netscape.com
9f7a44c3e2 Deal with nsIEnumerator.h changes
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21525 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 01:10:10 +00:00
mcmullen%netscape.com
99153e23c5 Brought change over from trunk.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21505 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 00:02:18 +00:00
mcmullen%netscape.com
509501efbf Brought some more of the changes over from the trunk (needed the changes in xcDll.h/cpp).
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21501 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 23:24:03 +00:00
law%netscape.com
249c9a91cc Adding registry to DIRS
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21491 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 22:29:33 +00:00
law%netscape.com
6100d0195f Pulling tip changes onto branch
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21490 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 22:27:12 +00:00
mcmullen%netscape.com
2b0897f6b5 Bringing nsCOMPtr.cpp from trunk.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21361 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-20 00:00:07 +00:00
law%netscape.com
9b7b41f2e2 Win32 build changes
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21360 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-19 23:54:05 +00:00
law%netscape.com
acaf468169 Win32 build changes
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@21358 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-19 23:44:01 +00:00
mcmullen%netscape.com
37c847e5d4 Rework previous changes, so that libreg (standalone) still builds on Windows. Also, add standalone target to the Macintosh project.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20885 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 05:16:27 +00:00
mcmullen%netscape.com
4397f139f4 First Checked In.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20870 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 03:26:51 +00:00
(no author)
07af9a116d This commit was manufactured by cvs2svn to create branch
'LIBREG990212_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20863 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 03:12:04 +00:00
mcmullen%netscape.com
601c209b84 Reverting these to the original form, prior to reworking to support the STANDALONE_REGISTRY version.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20842 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 01:32:45 +00:00
mcmullen%netscape.com
70f44c60cd Fix use of stat() for windows.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20828 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-16 22:52:10 +00:00
mcmullen%netscape.com
8d0d948e0a Added libreg, etc to make nsRegistry work.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20652 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 03:52:29 +00:00
mcmullen%netscape.com
bdc8aa3c5c Added nsRegistry::GetFactory()
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20651 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 03:51:43 +00:00
mcmullen%netscape.com
ffccab09a0 Made it work.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20650 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 03:50:42 +00:00
mcmullen%netscape.com
fc3851269e Hard-coded some command-line arguments for Macintosh.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20649 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 03:50:16 +00:00
mcmullen%netscape.com
66a57a8d4a Remove the illegal semicolon after extern "C" {}
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20648 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 03:49:41 +00:00
mcmullen%netscape.com
faddf412e6 LIBREG990212_BRANCH checkin to check that my port of libreg to NSPR is still working on win and unix.
git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20646 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 03:45:23 +00:00
(no author)
d95ce0280d This commit was manufactured by cvs2svn to create branch
'LIBREG990212_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/LIBREG990212_BRANCH@20631 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-13 00:58:55 +00:00
211 changed files with 57922 additions and 816 deletions

View File

@@ -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

View File

@@ -0,0 +1,28 @@
#!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 = include src
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,6 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
VerReg.h
NSReg.h

View 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
MODULE = libreg
EXPORTS = VerReg.h NSReg.h
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,249 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
/* NSReg.h
*/
#ifndef _NSREG_H_
#define _NSREG_H_
#include "xp_core.h"
typedef void (*nr_RegPackCallbackFunc) (void *userData, int32 bytes, int32 totalBytes);
typedef int32 REGERR;
typedef int32 RKEY;
typedef uint32 REGENUM;
typedef void * HREG;
typedef struct _reginfo
{
uint16 size; /* must be initialized to sizeof(REGINFO) */
uint16 entryType;
uint32 entryLength;
} REGINFO;
#define REGERR_OK (0)
#define REGERR_FAIL (1)
#define REGERR_NOMORE (2)
#define REGERR_NOFIND (3)
#define REGERR_BADREAD (4)
#define REGERR_BADLOCN (5)
#define REGERR_PARAM (6)
#define REGERR_BADMAGIC (7)
#define REGERR_BADCHECK (8)
#define REGERR_NOFILE (9)
#define REGERR_MEMORY (10)
#define REGERR_BUFTOOSMALL (11)
#define REGERR_NAMETOOLONG (12)
#define REGERR_REGVERSION (13)
#define REGERR_DELETED (14)
#define REGERR_BADTYPE (15)
#define REGERR_NOPATH (16)
#define REGERR_BADNAME (17)
#define REGERR_READONLY (18)
#define REGERR_BADUTF8 (19)
/* Total path length */
#define MAXREGPATHLEN (2048)
/* Name on the path (including null terminator) */
#define MAXREGNAMELEN (512)
/* Value of an entry */
#define MAXREGVALUELEN (0x7FFF)
/* Standard keys */
#define ROOTKEY_USERS (0x01)
#define ROOTKEY_COMMON (0x02)
#define ROOTKEY_CURRENT_USER (0x03)
#define ROOTKEY_PRIVATE (0x04)
/* enumeration styles */
#define REGENUM_NORMAL (0x00)
#define REGENUM_CHILDREN REGENUM_NORMAL
#define REGENUM_DESCEND (0x01)
#define REGENUM_DEPTH_FIRST (0x02)
/* entry data types */
#define REGTYPE_ENTRY (0x0010)
#define REGTYPE_ENTRY_STRING_UTF (REGTYPE_ENTRY + 1)
#define REGTYPE_ENTRY_INT32_ARRAY (REGTYPE_ENTRY + 2)
#define REGTYPE_ENTRY_BYTES (REGTYPE_ENTRY + 3)
#define REGTYPE_ENTRY_FILE (REGTYPE_ENTRY + 4)
#define REG_DELETE_LIST_KEY "Netscape/Communicator/SoftwareUpdate/Delete List"
#define REG_REPLACE_LIST_KEY "Netscape/Communicator/SoftwareUpdate/Replace List"
#define REG_UNINSTALL_DIR "Netscape/Communicator/SoftwareUpdate/Uninstall/"
#define UNINSTALL_NAV_STR "_"
#define UNIX_GLOBAL_FLAG "MOZILLA_SHARED_REGISTRY"
/* Platform-dependent declspec for library interface */
#if defined(XP_PC)
#if defined(WIN32)
#if defined (STANDALONE_REGISTRY)
#define VR_INTERFACE(type) __declspec(dllexport) type __cdecl
#else
#define VR_INTERFACE(type) __declspec(dllexport) type __stdcall
#endif
#elif defined(XP_OS2)
#define VR_INTERFACE(type) type _Optlink
#else
#define VR_INTERFACE(type) type _far _pascal _export
#endif
#elif defined XP_MAC
#define VR_INTERFACE(__x) __declspec(export) __x
#else
#define VR_INTERFACE(type) type
#endif
XP_BEGIN_PROTOS
/* ---------------------------------------------------------------------
* Registry API -- General
* ---------------------------------------------------------------------
*/
VR_INTERFACE(REGERR) NR_RegOpen(
char *filename, /* reg. file to open (NULL == standard registry) */
HREG *hReg /* OUT: handle to opened registry */
);
VR_INTERFACE(REGERR) NR_RegClose(
HREG hReg /* handle of open registry to close */
);
VR_INTERFACE(REGERR) NR_RegPack(
HREG hReg, /* handle of open registry to pack */
void *userData,
nr_RegPackCallbackFunc fn
);
VR_INTERFACE(REGERR) NR_RegGetUsername(
char **name /* on return, an alloc'ed copy of the current user name */
);
VR_INTERFACE(REGERR) NR_RegSetUsername(
const char *name /* name of current user */
);
/* ---------------------------------------------------------------------
* Registry API -- Key Management functions
* ---------------------------------------------------------------------
*/
VR_INTERFACE(REGERR) NR_RegAddKey(
HREG hReg, /* handle of open registry */
RKEY key, /* root key */
char *path, /* relative path of subkey to add */
RKEY *newKey /* if not null returns newly created key */
);
VR_INTERFACE(REGERR) NR_RegDeleteKey(
HREG hReg, /* handle of open registry */
RKEY key, /* root key */
char *path /* relative path of subkey to delete */
);
VR_INTERFACE(REGERR) NR_RegGetKey(
HREG hReg, /* handle of open registry */
RKEY key, /* root key */
char *path, /* relative path of subkey to find */
RKEY *result /* returns RKEY of specified sub-key */
);
VR_INTERFACE(REGERR) NR_RegEnumSubkeys(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
REGENUM *state, /* enum state, must be NULL to start */
char *buffer, /* buffer for entry names */
uint32 bufsize, /* size of buffer */
uint32 style /* 0: children only; REGENUM_DESCEND: sub-tree */
);
/* ---------------------------------------------------------------------
* Registry API -- Entry Management functions
* ---------------------------------------------------------------------
*/
VR_INTERFACE(REGERR) NR_RegGetEntryInfo(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
char *name, /* entry name */
REGINFO *info /* returned entry info */
);
VR_INTERFACE(REGERR) NR_RegGetEntryString(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
char *name, /* entry name */
char *buffer, /* buffer to hold value (UTF String) */
uint32 bufsize /* length of buffer */
);
VR_INTERFACE(REGERR) NR_RegGetEntry(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
char *name, /* entry name */
void *buffer, /* buffer to hold value */
uint32 *size /* in:length of buffer */
); /* out: data length, >>includes<< null terminator*/
VR_INTERFACE(REGERR) NR_RegSetEntryString(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
char *name, /* entry name */
char *buffer /* UTF String value */
);
VR_INTERFACE(REGERR) NR_RegSetEntry(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
char *name, /* entry name */
uint16 type, /* type of value data */
void *buffer, /* data buffer */
uint32 size /* data length in bytes; incl. null term for strings */
);
VR_INTERFACE(REGERR) NR_RegDeleteEntry(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
char *name /* value name */
);
VR_INTERFACE(REGERR) NR_RegEnumEntries(
HREG hReg, /* handle of open registry */
RKEY key, /* containing key */
REGENUM *state, /* enum state, must be NULL to start */
char *buffer, /* buffer for entry names */
uint32 bufsize, /* size of buffer */
REGINFO *info /* optional; returns info about entry */
);
VR_INTERFACE(void) NR_ShutdownRegistry(void);
VR_INTERFACE(void) NR_StartupRegistry(void);
XP_END_PROTOS
#endif /* _NSREG_H_ */
/* EOF: NSReg.h */

View File

@@ -0,0 +1,82 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
/* VerReg.h
* XP Version Registry functions
*/
#ifndef _VERREG_H_
#define _VERREG_H_
#include "NSReg.h"
typedef struct _version
{
int32 major;
int32 minor;
int32 release;
int32 build;
int32 check;
} VERSION;
/* CreateRegistry flags */
#define CR_NEWREGISTRY 1
XP_BEGIN_PROTOS
/* ---------------------------------------------------------------------
* Version Registry Operations
* ---------------------------------------------------------------------
*/
/* global registry operations */
VR_INTERFACE(REGERR) VR_SetRegDirectory(const char *path);
VR_INTERFACE(REGERR) VR_CreateRegistry(char *installation, char *programPath, char *versionStr);
VR_INTERFACE(REGERR) VR_PackRegistry(void *userData, nr_RegPackCallbackFunc pdCallbackFunction);
VR_INTERFACE(REGERR) VR_Close(void);
/* component-level functions */
VR_INTERFACE(REGERR) VR_Install(char *component_path, char *filepath, char *version, int bDirectory);
VR_INTERFACE(REGERR) VR_Remove(char *component_path);
VR_INTERFACE(REGERR) VR_InRegistry(char *path);
VR_INTERFACE(REGERR) VR_ValidateComponent(char *path);
VR_INTERFACE(REGERR) VR_Enum(char *component_path, REGENUM *state, char *buffer, uint32 buflen);
/* dealing with parts of individual components */
VR_INTERFACE(REGERR) VR_GetVersion(char *component_path, VERSION *result);
VR_INTERFACE(REGERR) VR_GetPath(char *component_path, uint32 sizebuf, char *buf);
VR_INTERFACE(REGERR) VR_SetRefCount(char *component_path, int refcount);
VR_INTERFACE(REGERR) VR_GetRefCount(char *component_path, int *result);
VR_INTERFACE(REGERR) VR_GetDefaultDirectory(char *component_path, uint32 sizebuf, char *buf);
VR_INTERFACE(REGERR) VR_SetDefaultDirectory(char *component_path, char *directory);
/* uninstall functions */
VR_INTERFACE(REGERR) VR_UninstallCreateNode(char *regPackageName, char *userPackageName);
VR_INTERFACE(REGERR) VR_UninstallAddFileToList(char *regPackageName, char *vrName);
VR_INTERFACE(REGERR) VR_UninstallFileExistsInList(char *regPackageName, char *vrName);
VR_INTERFACE(REGERR) VR_UninstallEnumSharedFiles(char *component_path, REGENUM *state, char *buffer, uint32 buflen);
VR_INTERFACE(REGERR) VR_UninstallDeleteFileFromList(char *component_path, char *vrName);
VR_INTERFACE(REGERR) VR_UninstallDeleteSharedFilesKey(char *regPackageName);
VR_INTERFACE(REGERR) VR_UninstallDestroy(char *regPackageName);
VR_INTERFACE(REGERR) VR_EnumUninstall(REGENUM *state, char* userPackageName,
int32 len1, char*regPackageName, int32 len2, Bool bSharedList);
VR_INTERFACE(REGERR) VR_GetUninstallUserName(char *regPackageName, char *outbuf, uint32 buflen);
XP_END_PROTOS
#endif /* _VERREG_H_ */
/* EOF: VerReg.h */

View File

@@ -0,0 +1,34 @@
#!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.
IGNORE_MANIFEST=1
#
#//------------------------------------------------------------------------
#//
#// Makefile to install MODULES/LIBREG/INCLUDE header files into the distribution
#// directory.
#//
#//------------------------------------------------------------------------
MODULE=libreg
DEPTH=..\..\..
EXPORTS=VerReg.h NSReg.h
include <$(DEPTH)/config/rules.mak>

View File

@@ -0,0 +1,3 @@
#include "MacPrefix.h"
#define STANDALONE_REGISTRY 1

Binary file not shown.

View File

@@ -0,0 +1,26 @@
globalRegName
NR_ShutdownRegistry
NR_StartupRegistry
NR_RegEnumEntries
NR_RegEnumSubkeys
NR_RegDeleteEntry
NR_RegSetEntry
NR_RegSetEntryString
NR_RegGetEntry
NR_RegGetEntryString
NR_RegGetEntryInfo
NR_RegGetKey
NR_RegDeleteKey
NR_RegAddKey
NR_RegPack
NR_RegClose
NR_RegOpen
NR_RegSetUsername
NR_RegGetUsername
nr_PathFromMacAlias
nr_MacAliasFromPath
vr_findGlobalRegName
#__ptmf_null
#longjmp
#__terminate
#__initialize

View File

@@ -0,0 +1,48 @@
#!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.
#//------------------------------------------------------------------------
#//
#// Makefile to build the MODULES\LIBREG tree
#//
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
#//
#// Specify the depth of the current directory relative to the
#// root of NS
#//
#//------------------------------------------------------------------------
DEPTH=..\..
#//------------------------------------------------------------------------
#//
#// Specify any "command" targets. (ie. DIRS, INSTALL_FILES, ...)
#// (these must come before the common makefiles are included)
#//
#// DIRS - There are subdirectories to process
#//
#//------------------------------------------------------------------------
DIRS=include src standalone
#//------------------------------------------------------------------------
#//
#// Include the common makefile rules
#//
#//------------------------------------------------------------------------
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,82 @@
#!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 = libreg
LIBRARY_NAME = reg
REQUIRES = libreg pref js
CSRCS = reg.c VerReg.c vr_stubs.c
BIN_SRCS = VerReg.c reg.c vr_stubs.c
BIN_OBJS = $(addprefix $(OBJDIR)/R_,$(BIN_SRCS:.c=.o))
include $(topsrcdir)/config/rules.mk
# Override gtscc when building vreg on IRIX 5.3.
ifeq ($(OS_ARCH)$(OS_RELEASE),IRIX5)
CC = cc
endif
INCLUDES += -I$(topsrcdir)/include
GARBAGE += $(PROGRAM)
PROGRAM = $(OBJDIR)/vreg$(BIN_SUFFIX)
$(PROGRAM): $(BIN_OBJS)
@$(MAKE_OBJDIR)
ifeq ($(OS_ARCH), OS2)
$(LINK_EXE) -OUT:$@ $(BIN_OBJS) $(LDFLAGS) $(OS_LIBS)
else
$(CCF) -o $@ $(BIN_OBJS) $(LDFLAGS)
endif
$(OBJDIR)/R_VerReg.o: VerReg.c
@$(MAKE_OBJDIR)
ifeq ($(OS_ARCH), OS2)
$(CC) -Fo$@ -c $(CFLAGS) -DSTANDALONE_REGISTRY $<
else
$(CC) -o $@ -c $(CFLAGS) -DSTANDALONE_REGISTRY $<
endif
$(OBJDIR)/R_reg.o: reg.c
@$(MAKE_OBJDIR)
ifeq ($(OS_ARCH), OS2)
$(CC) -Fo$@ -c $(CFLAGS) -DSTANDALONE_REGISTRY $<
else
$(CC) -o $@ -c $(CFLAGS) -DSTANDALONE_REGISTRY $<
endif
$(OBJDIR)/R_vr_stubs.o: vr_stubs.c
@$(MAKE_OBJDIR)
ifeq ($(OS_ARCH), OS2)
$(CC) -Fo$@ -c $(CFLAGS) -DSTANDALONE_REGISTRY $<
else
$(CC) -o $@ -c $(CFLAGS) -DSTANDALONE_REGISTRY $<
endif
$(BIN_OBJS): $(BIN_SRCS)
install:: $(PROGRAM)
$(INSTALL) -m 444 $(PROGRAM) $(DIST)/bin

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
#!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.
IGNORE_MANIFEST=1
#//------------------------------------------------------------------------
#//
#// Makefile to build
#//
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
#//
#// Specify the depth of the current directory relative to the
#// root of NS
#//
#//------------------------------------------------------------------------
DEPTH= ..\..\..
!ifndef MAKE_OBJ_TYPE
MAKE_OBJ_TYPE=DLL
!endif
#//------------------------------------------------------------------------
#//
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
#//
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
#//
#// Define the files necessary to build the target (ie. OBJS)
#//
#//------------------------------------------------------------------------
OBJS= \
.\$(OBJDIR)\reg.obj \
.\$(OBJDIR)\VerReg.obj \
.\$(OBJDIR)\vr_stubs.obj \
$(NULL)
#//------------------------------------------------------------------------
#//
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
#// (these must be defined before the common makefiles are included)
#//
#//------------------------------------------------------------------------
LIBNAME=libreg$(MOZ_BITS)
DLL=$(OBJDIR)\$(LIBNAME).dll
LIBRARY= .\$(OBJDIR)\$(LIBNAME).lib
#//------------------------------------------------------------------------
#//
#// Define any local options for the make tools
#// (ie. LCFLAGS, LLFLAGS, LLIBS, LINCS)
#//
#//------------------------------------------------------------------------
LCFLAGS = $(LCFLAGS)
LLIBS = $(LLIBS) $(LIBNSPR) $(DIST)\lib\libplc21.lib
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
!endif
#//
#// Win16 places ALL public header files in $(PUBLIC)/win16
#//
!if "$(MOZ_BITS)" != "16"
LINCS= $(LINCS) -I$(PUBLIC)/libreg \
$(NULL)
!endif
#//------------------------------------------------------------------------
#//
#// Include the common makefile rules
#//
#//------------------------------------------------------------------------
include <$(DEPTH)/config/rules.mak>
export:: $(DLL)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
$(MAKE_INSTALL) $(DLL) $(DIST)\bin
clobber::
$(RM) $(DIST)\bin\$(DLL)
$(RM) $(DIST)\lib\$(LIBRARY)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
/* reg.h
* XP Registry functions (prototype)
*/
#ifndef _REG_H_
#define _REG_H_
#include "vr_stubs.h"
#ifndef STANDALONE_REGISTRY
#include "prmon.h"
#endif
/* --------------------------------------------------------------------
* Miscellaneous Definitions
* --------------------------------------------------------------------
*/
#define MAGIC_NUMBER 0x76644441L
#define MAJOR_VERSION 1 /* major version for incompatible changes */
#define MINOR_VERSION 2 /* minor ver for new (compatible) features */
#define PATHDEL '/'
#define EQU '='
#define QUOTE '"'
#define HDRRESERVE 128 /* number of bytes reserved for hdr */
#define INTSIZE 4
#define DOUBLESIZE 8
#define PACKBUFFERSIZE 2048
/* Node types */
#define REGTYPE_KEY (1)
#define REGTYPE_DELETED (0x0080)
/* Private standard keys */
#define ROOTKEY (0x20)
#define ROOTKEY_VERSIONS (0x21)
/* strings for standard keys */
#define ROOTKEY_STR "/"
#define ROOTKEY_VERSIONS_STR "Version Registry"
#define ROOTKEY_USERS_STR "Users"
#define ROOTKEY_COMMON_STR "Common"
#define ROOTKEY_PRIVATE_STR "Private Arenas"
#define OLD_VERSIONS_STR "ROOTKEY_VERSIONS"
#define OLD_USERS_STR "ROOTKEY_USERS"
#define OLD_COMMON_STR "ROOTKEY_COMMON"
/* needs to be kept in sync with PE. see ns/cmd/winfe/profile.h */
/* and ns/cmd/macfe/central/profile.cp */
#define ASW_MAGIC_PROFILE_NAME "User1"
/* macros */
#define COPYDESC(dest,src) memcpy((dest),(src),sizeof(REGDESC))
#define VALID_FILEHANDLE(fh) ((fh) != NULL)
#define INVALID_NAME_CHAR(p) ( ((unsigned char)(p) < 0x20) || ((p) == '=') )
#define TYPE_IS_ENTRY(type) ( (type) & REGTYPE_ENTRY )
#define TYPE_IS_KEY(type) ( !((type) & REGTYPE_ENTRY) )
#define VERIFY_HREG(h)\
( ((h) == NULL) ? REGERR_PARAM : \
( (((REGHANDLE*)(h))->magic == MAGIC_NUMBER) ? REGERR_OK : REGERR_BADMAGIC ) )
/* --------------------------------------------------------------------
* Types and Objects
* --------------------------------------------------------------------
*/
#undef REGOFF
typedef int32 REGOFF; /* offset into registry file */
typedef struct _desc
{
REGOFF location; /* this object's offset (for verification) */
REGOFF name; /* name string */
uint16 namelen; /* length of name string (including terminator) */
uint16 type; /* node type (key, or entry style) */
REGOFF left; /* next object at this level (0 if none) */
REGOFF down; /* KEY: first subkey VALUE: 0 */
REGOFF value; /* KEY: first entry object VALUE: value string */
uint32 valuelen; /* KEY: 0 VALUE: length of value data */
uint32 valuebuf; /* KEY: 0 VALUE: length available */
REGOFF parent; /* the node on the immediate level above */
} REGDESC;
/* offsets into structure on disk */
#define DESC_LOCATION 0
#define DESC_NAME 4
#define DESC_NAMELEN 8
#define DESC_TYPE 10
#define DESC_LEFT 12
#define DESC_DOWN 16
#define DESC_VALUE 20
#define DESC_VALUELEN 24
#define DESC_VALUEBUF 16 /* stored in place of "down" for entries */
#define DESC_PARENT 28
#define DESC_SIZE 32 /* size of desc on disk */
typedef struct _hdr
{
uint32 magic; /* must equal MAGIC_NUMBER */
uint16 verMajor; /* major version number */
uint16 verMinor; /* minor version number */
REGOFF avail; /* next available offset */
REGOFF root; /* root object */
} REGHDR;
/* offsets into structure on disk*/
#define HDR_MAGIC 0
#define HDR_VERMAJOR 4
#define HDR_VERMINOR 6
#define HDR_AVAIL 8
#define HDR_ROOT 12
typedef XP_File FILEHANDLE; /* platform-specific file reference */
typedef struct _stdnodes {
REGOFF versions;
REGOFF users;
REGOFF common;
REGOFF current_user;
REGOFF privarea;
} STDNODES;
typedef struct _regfile
{
FILEHANDLE fh;
REGHDR hdr;
int refCount;
int hdrDirty;
int inInit;
int readOnly;
char * filename;
STDNODES rkeys;
struct _regfile *next;
struct _regfile *prev;
#ifndef STANDALONE_REGISTRY
PRMonitor *monitor;
#endif
} REGFILE;
typedef struct _reghandle
{
uint32 magic; /* for validating reg handles */
REGFILE *pReg; /* the real registry file object */
} REGHANDLE;
#endif /* _REG_H_ */
/* EOF: reg.h */

View File

@@ -0,0 +1,554 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
/* this file contains stubs needed to build the registry routines
* into a stand-alone library for use with our installers
*/
#ifdef STANDALONE_REGISTRY
#include <stdio.h>
#include <string.h>
#else
#include "prtypes.h"
#include "plstr.h"
#endif /*STANDALONE_REGISTRY*/
#include "vr_stubs.h"
#ifdef XP_MAC
#include <Folders.h>
#include <Script.h>
#include <stdlib.h>
#include <Errors.h>
#include "MoreFiles.h"
#include "FullPath.h" /* For FSpLocationFromFullPath() */
#endif
extern char* globalRegName;
/* ------------------------------------------------------------------
* OS/2 STUBS
* ------------------------------------------------------------------
*/
#ifdef XP_OS2
#define INCL_DOS
#include <os2.h>
#ifdef STANDALONE_REGISTRY
extern XP_File vr_fileOpen (const char *name, const char * mode)
{
XP_File fh = NULL;
struct stat st;
if ( name != NULL ) {
if ( stat( name, &st ) == 0 )
fh = fopen( name, XP_FILE_UPDATE_BIN );
else
fh = fopen( name, XP_FILE_WRITE_BIN );
}
return fh;
}
#endif /*STANDALONE_REGISTRY*/
extern void vr_findGlobalRegName ()
{
char path[ CCHMAXPATH ];
int pathlen;
XP_File fh = NULL;
struct stat st;
#ifdef XP_OS2_HACK
/*DSR050197 - at this point, I need some front-end call to get the install directory of*/
/*communicator... for now I will let it default to the current directory...*/
#endif
XP_STRCPY(path, ".");
pathlen = strlen(path);
if ( pathlen > 0 ) {
XP_STRCPY( path+pathlen, "\\nsreg.dat" );
globalRegName = XP_STRDUP(path);
}
}
#endif /* XP_OS2 */
/* ------------------------------------------------------------------
* WINDOWS STUBS
* ------------------------------------------------------------------
*/
#ifdef XP_PC
#include "windows.h"
#define PATHLEN 260
#ifdef STANDALONE_REGISTRY
extern XP_File vr_fileOpen (const char *name, const char * mode)
{
XP_File fh = NULL;
struct stat st;
if ( name != NULL ) {
if ( stat( name, &st ) == 0 )
fh = fopen( name, XP_FILE_UPDATE_BIN );
else
fh = fopen( name, XP_FILE_WRITE_BIN );
}
return fh;
}
#endif /*STANDALONE_REGISTRY*/
extern void vr_findGlobalRegName ()
{
char path[ PATHLEN ];
int pathlen;
pathlen = GetWindowsDirectory(path, PATHLEN);
if ( pathlen > 0 ) {
XP_STRCPY( path+pathlen, "\\nsreg.dat" );
globalRegName = XP_STRDUP(path);
}
}
#if !defined(WIN32) && !defined(__BORLANDC__)
int FAR PASCAL _export WEP(int);
int FAR PASCAL LibMain(HANDLE hInst, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine)
{
if ( wHeapSize > 0 )
UnlockData(0);
return 1;
}
int FAR PASCAL _export WEP(int nParam)
{
return 1;
}
#endif /* not WIN32 */
#endif /* XP_PC */
/* ------------------------------------------------------------------
* MACINTOSH STUBS
* ------------------------------------------------------------------
*/
#ifdef XP_MAC
#include <Files.h>
#include "FullPath.h"
#ifdef STANDALONE_REGISTRY
extern XP_File vr_fileOpen(const char *name, const char * mode)
{
XP_File fh = NULL;
struct stat st;
OSErr anErr;
FSSpec newFSSpec;
#ifdef STANDALONE_REGISTRY
errno = 0; // reset errno (only if we're using stdio)
#endif
anErr = FSpLocationFromFullPath(strlen(name), name, &newFSSpec);
if (anErr == -43)
{
/* if file doesn't exist */
anErr = FSpCreate(&newFSSpec, 'MOSS', 'REGS', smSystemScript);
}
else
{
/* there is not much to do here. if we got noErr, the file exists. If we did not get
noErr or -43, we are pretty hosed.
*/
}
if ( name != NULL ) {
if ( stat( name, &st ) == 0 )
fh = fopen( name, XP_FILE_UPDATE_BIN ); /* If/when we switch to MSL C Lib (gromit uses this), we might have to take out the Macro per bug #62382 */
else
{
/* should never get here! */
fh = fopen( name, XP_FILE_WRITE_BIN );
}
}
#ifdef STANDALONE_REGISTRY
if (anErr != noErr)
errno = anErr;
#endif
return fh;
}
#endif /*STANDALONE_REGISTRY*/
extern void vr_findGlobalRegName()
{
FSSpec regSpec;
OSErr err;
short foundVRefNum;
long foundDirID;
int bCreate = 0;
err = FindFolder(kOnSystemDisk,'pref', false, &foundVRefNum, &foundDirID);
if (!err)
{
err = FSMakeFSSpec(foundVRefNum, foundDirID, "\pNetscape Registry", &regSpec);
if (err == -43) /* if file doesn't exist */
{
err = FSpCreate(&regSpec, 'MOSS', 'REGS', smSystemScript);
bCreate = 1;
}
if (err == noErr)
{
Handle thePath;
short pathLen;
err = FSpGetFullPath(&regSpec, &pathLen, &thePath);
if (err == noErr && thePath)
{
#ifdef STANDALONE_REGISTRY
globalRegName = XP_STRDUP(*(char**)thePath);
#else
/* Since we're now using NSPR, this HAS to be a unix path! */
const char* src;
char* dst;
globalRegName = (char*)XP_ALLOC(pathLen + 2);
src = *(char**)thePath;
dst = globalRegName;
*dst++ = '/';
while (pathLen--)
{
char c = *src++;
*dst++ = (c == ':') ? '/' : c;
}
*dst = '\0';
#endif
}
DisposeHandle(thePath);
}
}
}
/* Moves and renames a file or directory.
Returns 0 on success, -1 on failure (errno contains mac error code).
*/
extern int nr_RenameFile(char *from, char *to)
{
OSErr err = -1;
FSSpec fromSpec;
FSSpec toSpec;
FSSpec destDirSpec;
FSSpec beforeRenameSpec;
#ifdef STANDALONE_REGISTRY
errno = 0; // reset errno (only if we're using stdio)
#endif
if (from && to) {
err = FSpLocationFromFullPath(XP_STRLEN(from), from, &fromSpec);
if (err != noErr) goto exit;
err = FSpLocationFromFullPath(XP_STRLEN(to), to, &toSpec);
if (err != noErr && err != fnfErr) goto exit;
// make an FSSpec for the destination directory
err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, nil, &destDirSpec);
if (err != noErr) goto exit; // parent directory must exist
// move it to the directory specified
err = FSpCatMove(&fromSpec, &destDirSpec);
if (err != noErr) goto exit;
// make a new FSSpec for the file or directory in its new location
err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, fromSpec.name, &beforeRenameSpec);
if (err != noErr) goto exit;
// rename the file or directory
err = FSpRename(&beforeRenameSpec, toSpec.name);
}
exit:
#ifdef STANDALONE_REGISTRY
if (err != noErr)
errno = err;
#endif
return (err == noErr ? 0 : -1);
}
#if 0
/* Uncomment the following for older Mac build environments
* that don't support these functions
*/
char *strdup(const char *source)
{
char *newAllocation;
size_t stringLength;
stringLength = strlen(source) + 1;
newAllocation = (char *)XP_ALLOC(stringLength);
if (newAllocation == NULL)
return NULL;
BlockMoveData(source, newAllocation, stringLength);
return newAllocation;
}
int strcasecmp(const char *str1, const char *str2)
{
char currentChar1, currentChar2;
while (1) {
currentChar1 = *str1;
currentChar2 = *str2;
if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
currentChar1 += ('A' - 'a');
if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
currentChar2 += ('A' - 'a');
if (currentChar1 == '\0')
break;
if (currentChar1 != currentChar2)
return currentChar1 - currentChar2;
str1++;
str2++;
}
return currentChar1 - currentChar2;
}
int strncasecmp(const char *str1, const char *str2, int length)
{
char currentChar1, currentChar2;
while (length > 0) {
currentChar1 = *str1;
currentChar2 = *str2;
if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
currentChar1 += ('A' - 'a');
if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
currentChar2 += ('A' - 'a');
if (currentChar1 == '\0')
break;
if (currentChar1 != currentChar2)
return currentChar1 - currentChar2;
str1++;
str2++;
length--;
}
return currentChar1 - currentChar2;
}
#endif /* 0 */
#endif /* XP_MAC */
/* ------------------------------------------------------------------
* UNIX STUBS
* ------------------------------------------------------------------
*/
/*allow OS/2 and Macintosh to use this main to test...*/
#if (defined(STANDALONE_REGISTRY) && defined(XP_MAC)) || defined(XP_UNIX) || defined(XP_OS2)
#include <stdlib.h>
#ifdef XP_OS2
#include <io.h>
#define W_OK 0x02 /*evil hack from the docs...*/
#else
#include <unistd.h>
#endif
#include "NSReg.h"
#include "VerReg.h"
char *TheRegistry = "registry";
char *Flist;
/* WARNING: build hackery */
#if defined(STANDALONE_REGISTRY) && !defined(XP_MAC)
long BUILDNUM =
#include "../../../build/build_number"
;
#endif
REGERR vr_ParseVersion(char *verstr, VERSION *result);
int main(int argc, char *argv[]);
#ifdef XP_UNIX
#define DEF_REG "/.netscape/registry"
#ifdef STANDALONE_REGISTRY
extern XP_File vr_fileOpen (const char *name, const char * mode)
{
XP_File fh = NULL;
struct stat st;
if ( name != NULL ) {
if ( stat( name, &st ) == 0 )
fh = fopen( name, XP_FILE_UPDATE_BIN );
else
fh = fopen( name, XP_FILE_WRITE_BIN );
}
return fh;
}
#endif /*STANDALONE_REGISTRY*/
extern void vr_findGlobalRegName ()
{
#ifndef STANDALONE_REGISTRY
char *def = NULL;
char *home = getenv("HOME");
if (home != NULL) {
def = (char *) XP_ALLOC(XP_STRLEN(home) + XP_STRLEN(DEF_REG)+1);
if (def != NULL) {
XP_STRCPY(def, home);
XP_STRCAT(def, DEF_REG);
}
}
if (def != NULL) {
globalRegName = XP_STRDUP(def);
} else {
globalRegName = TheRegistry;
}
XP_FREEIF(def);
#else
globalRegName = TheRegistry;
#endif /*STANDALONE_REGISTRY*/
}
#endif /*XP_UNIX*/
#if defined(STANDALONE_REGISTRY) && (defined(XP_UNIX) || defined(XP_OS2) || defined(XP_MAC))
int main(int argc, char *argv[])
{
XP_File fh;
char *entry;
char *p;
char *v;
char buff[1024];
char name[MAXREGPATHLEN+1];
char path[MAXREGPATHLEN+1];
char ver[MAXREGPATHLEN+1];
if ( argc >= 3 )
{
TheRegistry = argv[1];
Flist = argv[2];
}
else
{
fprintf(stderr, "Usage: %s RegistryName FileList\n", argv[0]);
fprintf(stderr, " The FileList file contains lines with comma-separated fields:\n");
fprintf(stderr, " <regItemName>,<version>,<full filepath>\n");
exit (1);
}
/* tmp use of buff to get the registry directory, which must be
* the navigator home directory. Preserve the slash to match
* FE_GetDirectoryPath() called during navigator set-up
*/
strcpy(buff, TheRegistry);
p = strrchr( buff, '/' );
if ( p )
{
char pwd[1024];
*(p+1) = '\0';
getcwd(pwd, sizeof(pwd));
chdir(buff); getcwd(buff, sizeof(buff));
chdir(pwd);
}
else
{
getcwd(buff, sizeof(buff));
}
strcat(buff, "/");
NR_StartupRegistry();
VR_SetRegDirectory(buff);
#ifndef XP_MAC
if ( -1 == (access( TheRegistry, W_OK )) ) {
sprintf(ver,"4.50.0.%ld",BUILDNUM);
VR_CreateRegistry("Communicator", buff, ver);
}
#endif
if ( !(fh = fopen( Flist, "r" )) )
{
fprintf(stderr, "%s: Cannot open \"%s\"\n", argv[0], Flist);
exit (1);
}
while ( fgets ( buff, 1024, fh ) )
{
if ( *(entry = &buff[strlen(buff)-1]) == '\n' )
*entry = '\0';
entry = strchr(buff, ',');
strcpy(name, strtok(buff, ","));
strcpy(ver, strtok( NULL, ","));
strcpy(path, strtok( NULL, ","));
v = ver;
while (*v && *v == ' ')
v++;
p = path;
while (*p && *p == ' ')
p++;
VR_Install ( name, p, v, FALSE );
}
fclose( fh );
return 0;
}
#endif /* STANDALONE_REGISTRY && (XP_UNIX || XP_OS2 || XP_MAC) */
#endif /* XP_UNIX || XP_OS2 */

View File

@@ -0,0 +1,253 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
/* vr_stubs.h
*
* XP code stubs for stand-alone registry library
*
*/
#ifndef _VR_STUBS_H_
#define _VR_STUBS_H_
#ifdef STANDALONE_REGISTRY
#include <errno.h>
#include <string.h>
#ifdef XP_MAC
#include "macstdlibextras.h" /* For strcasecmp and strncasecmp */
#endif
#else
#include "prio.h"
#include "prmem.h"
#include "plstr.h"
#endif /* STANDALONE_REGISTRY*/
#ifdef XP_MAC
#include <stat.h>
#else
#if defined(BSDI) && !defined(BSDI_2)
#include <sys/types.h>
#endif
#include <sys/stat.h>
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#if defined(__cplusplus)
# define XP_CPLUSPLUS
# define XP_IS_CPLUSPLUS 1
#else
# define XP_IS_CPLUSPLUS 0
#endif
#if defined(XP_CPLUSPLUS)
# define XP_BEGIN_PROTOS extern "C" {
# define XP_END_PROTOS }
#else
# define XP_BEGIN_PROTOS
# define XP_END_PROTOS
#endif
#ifdef STANDALONE_REGISTRY
#define XP_FILE_READ "r"
#define XP_FILE_READ_BIN "rb"
#define XP_FILE_WRITE "w"
#define XP_FILE_WRITE_BIN "wb"
#define XP_FILE_UPDATE "r+"
#define XP_FILE_TRUNCATE "w+"
#ifdef SUNOS4
/* XXX SunOS4 hack -- make this universal by using r+b and w+b */
#define XP_FILE_UPDATE_BIN "r+"
#define XP_FILE_TRUNCATE_BIN "w+"
#else
#define XP_FILE_UPDATE_BIN "rb+"
#define XP_FILE_TRUNCATE_BIN "wb+"
#endif
#define XP_FileSeek(file,offset,whence) fseek((file), (offset), (whence))
#define XP_FileRead(dest,count,file) fread((dest), 1, (count), (file))
#define XP_FileWrite(src,count,file) fwrite((src), 1, (count), (file))
#define XP_FileTell(file) ftell(file)
#define XP_FileFlush(file) fflush(file)
#define XP_FileClose(file) fclose(file)
#define XP_ASSERT(x) ((void)0)
#define XP_STRCAT(a,b) strcat((a),(b))
#define XP_ATOI atoi
#define XP_STRCPY(a,b) strcpy((a),(b))
#define XP_STRLEN(x) strlen(x)
#define XP_SPRINTF sprintf
#define XP_FREE(x) free((x))
#define XP_ALLOC(x) malloc((x))
#define XP_FREEIF(x) if ((x)) free((x))
#define XP_STRCMP(x,y) strcmp((x),(y))
#define XP_STRNCMP(x,y,n) strncmp((x),(y),(n))
#define XP_STRDUP(s) strdup((s))
#define XP_MEMCPY(d, s, l) memcpy((d), (s), (l))
#define XP_MEMSET(d, c, l) memset((d), (c), (l))
#ifdef XP_PC
#define XP_STRCASECMP(x,y) stricmp((x),(y))
#define XP_STRNCASECMP(x,y,n) strnicmp((x),(y),(n))
#else
#define XP_STRCASECMP(x,y) strcasecmp((x),(y))
#define XP_STRNCASECMP(x,y,n) strncasecmp((x),(y),(n))
#endif /*XP_PC*/
typedef FILE * XP_File;
#else /* if not standalone, use NSPR */
#define XP_FILE_READ PR_RDONLY, 0700
#define XP_FILE_READ_BIN PR_RDONLY, 0700
#define XP_FILE_WRITE PR_WRONLY, 0700
#define XP_FILE_WRITE_BIN PR_WRONLY, 0700
#define XP_FILE_UPDATE PR_RDWR
#define XP_FILE_TRUNCATE (PR_WRONLY | PR_TRUNCATE), 0700
#define XP_FILE_UPDATE_BIN PR_RDWR, 0700
#define XP_FILE_TRUNCATE_BIN (PR_RDWR | PR_TRUNCATE), 0700
#ifdef SEEK_SET
#undef SEEK_SET
#undef SEEK_CUR
#undef SEEK_END
#define SEEK_SET PR_SEEK_SET
#define SEEK_CUR PR_SEEK_CUR
#define SEEK_END PR_SEEK_END
#endif
/*
** Note that PR_Seek returns the offset (if successful) and -1 otherwise. So
** to make this code work
** if (XP_FileSeek(fh, offset, SEEK_SET) != 0) { error handling }
** we return 1 if PR_Seek() returns a negative value, and 0 otherwise
*/
#define XP_FileSeek(file,offset,whence) (PR_Seek((file), (offset), (whence)) < 0)
#define XP_FileRead(dest,count,file) PR_Read((file), (dest), (count))
#define XP_FileWrite(src,count,file) PR_Write((file), (src), (count))
#define XP_FileTell(file) PR_Seek(file, 0, PR_SEEK_CUR)
#define XP_FileFlush(file) PR_Sync(file)
#define XP_FileClose(file) PR_Close(file)
#define XP_ASSERT(x) PR_ASSERT((x))
#define XP_STRCAT(a,b) PL_strcat((a),(b))
#define XP_ATOI PL_atoi
#define XP_STRCPY(a,b) PL_strcpy((a),(b))
#define XP_STRLEN(x) PL_strlen(x)
#define XP_SPRINTF sprintf
#define XP_FREE(x) PR_Free((x))
#define XP_ALLOC(x) PR_Malloc((x))
#define XP_FREEIF(x) PR_FREEIF(x)
#define XP_STRCMP(x,y) PL_strcmp((x),(y))
#define XP_STRNCMP(x,y,n) PL_strncmp((x),(y),(n))
#define XP_STRDUP(s) PL_strdup((s))
#define XP_MEMCPY(d, s, l) memcpy((d), (s), (l))
#define XP_MEMSET(d, c, l) memset((d), (c), (l))
#define XP_STRCASECMP(x,y) PL_strcasecmp((x),(y))
#define XP_STRNCASECMP(x,y,n) PL_strncasecmp((x),(y),(n))
typedef PRFileDesc* XP_File;
#endif /*STANDALONE_REGISTRY*/
#ifdef STANDALONE_REGISTRY /* included from prmon.h otherwise */
#include "prtypes.h"
#if 0
typedef long int32;
typedef unsigned long uint32;
typedef short int16;
typedef unsigned short uint16;
typedef unsigned char uint8;
#ifdef XP_MAC
#include <Types.h>
typedef char BOOL;
typedef char Bool;
typedef char XP_Bool;
#elif defined(XP_PC)
typedef int Bool;
typedef int XP_Bool;
#else
/* XP_UNIX: X11/Xlib.h "define"s Bool to be int. This is really lame
* (that's what typedef is for losers). So.. in lieu of a #undef Bool
* here (Xlib still needs ints for Bool-typed parameters) people have
* been #undef-ing Bool before including this file.
* Can we just #undef Bool here? <mailto:mcafee> (help from djw, converse)
*/
typedef char Bool;
typedef char XP_Bool;
#endif /* XP_MAC */
#endif /* 0 */
#endif /*STANDALONE_REGISTRY*/
#ifdef XP_PC
typedef struct _stat XP_StatStruct;
#define XP_Stat(file,data,type) _stat((file),(data))
#else
typedef struct stat XP_StatStruct;
#define XP_Stat(file,data,type) stat((file),(data))
#endif /*XP_PC*/
#ifdef XP_MAC
extern int nr_RenameFile(char *from, char *to);
#else
XP_BEGIN_PROTOS
#define nr_RenameFile(from, to) rename((from), (to))
XP_END_PROTOS
#endif
#ifdef STANDALONE_REGISTRY /* included from prmon.h otherwise */
XP_BEGIN_PROTOS
extern XP_File vr_fileOpen(const char *name, const char * mode);
extern void vr_findGlobalRegName();
#if !defined(XP_PC) && !(defined(__GLIBC__) && __GLIBC__ >= 2)
extern char * strdup(const char * s);
#endif
XP_END_PROTOS
#else
#define vr_fileOpen PR_Open
XP_BEGIN_PROTOS
extern void vr_findGlobalRegName();
XP_END_PROTOS
#endif /* STANDALONE_REGISTRY */
#endif /* _VR_STUBS_H_ */

View File

@@ -0,0 +1,115 @@
#!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.
IGNORE_MANIFEST=1
#//------------------------------------------------------------------------
#//
#// Makefile to build
#//
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
#//
#// Specify the depth of the current directory relative to the
#// root of NS
#//
#//------------------------------------------------------------------------
DEPTH= ..\..\..
!ifndef MAKE_OBJ_TYPE
MAKE_OBJ_TYPE=DLL
!endif
#//------------------------------------------------------------------------
#//
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
#//
#//------------------------------------------------------------------------
#//------------------------------------------------------------------------
#//
#// Define the files necessary to build the target (ie. OBJS)
#//
#//------------------------------------------------------------------------
OBJS= \
.\$(OBJDIR)\reg.obj \
.\$(OBJDIR)\VerReg.obj \
.\$(OBJDIR)\vr_stubs.obj \
$(NULL)
#//------------------------------------------------------------------------
#//
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
#// (these must be defined before the common makefiles are included)
#//
#//------------------------------------------------------------------------
LIBNAME=nsreg
DLL=$(OBJDIR)\$(LIBNAME).dll
#//------------------------------------------------------------------------
#//
#// Define any local options for the make tools
#// (ie. LCFLAGS, LLFLAGS, LLIBS, LINCS)
#//
#//------------------------------------------------------------------------
LCFLAGS = -DSTANDALONE_REGISTRY
LINCS= $(LINCS) -I$(PUBLIC)/libreg \
$(NULL)
#//------------------------------------------------------------------------
#//
#// Include the common makefile rules
#//
#//------------------------------------------------------------------------
include <$(DEPTH)/config/rules.mak>
reg.c::
$(RM) $(DEPTH)\modules\libreg\standalone\reg.h
$(RM) $(DEPTH)\modules\libreg\standalone\reg.c
$(RM) $(DEPTH)\modules\libreg\standalone\vr_stubs.h
$(RM) $(DEPTH)\modules\libreg\standalone\vr_stubs.c
$(RM) $(DEPTH)\modules\libreg\standalone\VerReg.c
copy $(DEPTH)\modules\libreg\src\reg.h $(DEPTH)\modules\libreg\standalone\reg.h
copy $(DEPTH)\modules\libreg\src\reg.c $(DEPTH)\modules\libreg\standalone\reg.c
copy $(DEPTH)\modules\libreg\src\vr_stubs.h $(DEPTH)\modules\libreg\standalone\vr_stubs.h
copy $(DEPTH)\modules\libreg\src\vr_stubs.c $(DEPTH)\modules\libreg\standalone\vr_stubs.c
copy $(DEPTH)\modules\libreg\src\VerReg.c $(DEPTH)\modules\libreg\standalone\VerReg.c
export:: $(DLL)
$(MAKE_INSTALL) $(DLL) $(DIST)\bin
$(RM) $(DEPTH)\modules\libreg\standalone\reg.h
$(RM) $(DEPTH)\modules\libreg\standalone\reg.c
$(RM) $(DEPTH)\modules\libreg\standalone\vr_stubs.h
$(RM) $(DEPTH)\modules\libreg\standalone\vr_stubs.c
$(RM) $(DEPTH)\modules\libreg\standalone\VerReg.c
clobber::
$(RM) $(DIST)\bin\$(DLL)
$(RM) $(DEPTH)\modules\libreg\standalone\reg.h
$(RM) $(DEPTH)\modules\libreg\standalone\reg.c
$(RM) $(DEPTH)\modules\libreg\standalone\vr_stubs.h
$(RM) $(DEPTH)\modules\libreg\standalone\vr_stubs.c
$(RM) $(DEPTH)\modules\libreg\standalone\VerReg.c

View File

@@ -0,0 +1,430 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
// Registry interpreter
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "VerReg.h"
#include "NSReg.h"
extern char *errstr(REGERR err);
extern int DumpTree(void);
int gVerbose = 1;
int gPretend = 0;
int error(char *func, int err)
{
if (err == REGERR_OK)
{
if (gVerbose)
printf("%s Ok\n", func);
}
else
{
printf("%s returns %s\n", func, errstr(err));
}
return err;
} // error
static char *GetNextWord(char *cmd, char *buf)
{
// copies until ',' or eos, then skips spaces
if (!cmd || !buf)
return 0;
while (*cmd && *cmd != ',')
*buf++ = *cmd++;
*buf = '\0';
if (*cmd == ',')
{
cmd++;
while(*cmd && *cmd == ' ')
cmd++;
}
return cmd;
} // GetNextWord
static int vr_ParseVersion(char *verstr, VERSION *result)
{
result->major = result->minor = result->release = result->build = 0;
result->major = atoi(verstr);
while (*verstr && *verstr != '.')
verstr++;
if (*verstr)
{
verstr++;
result->minor = atoi(verstr);
while (*verstr && *verstr != '.')
verstr++;
if (*verstr)
{
verstr++;
result->release = atoi(verstr);
while (*verstr && *verstr != '.')
verstr++;
if (*verstr)
{
verstr++;
result->build = atoi(verstr);
while (*verstr && *verstr != '.')
verstr++;
}
}
}
return REGERR_OK;
} // ParseVersion
void parse(char *cmd, char *name, VERSION *ver, char *path)
{
// expects 'cmd' points to: "<name>, <ver>, <path>"
char buf[256];
char *p;
cmd = GetNextWord(cmd, buf);
strcpy(name, buf);
p = cmd; // 'cmd' points to version
vr_ParseVersion(cmd, ver);
ver->check = gPretend ? 0xad : 0;
while (*p && *p != ',') // skip to next ','
p++;
if (*p == ',') // skip comma
p++;
while (*p && *p == ' ') // skip white space
p++;
strcpy(path, p);
} // parse
void vVerbose(char *cmd)
{
if (stricmp(cmd, "ON") == 0)
{
gVerbose = 1;
printf("Verbose mode is now ON.\n");
}
else
{
gVerbose = 0;
}
} // vVerbose
void vCreate(char *cmd)
{
// Syntax: Create [new,] 5.0b1
char buf[64];
int flag = 0;
cmd = GetNextWord(cmd, buf);
if (stricmp(buf, "NEW,") == 0)
{
flag = CR_NEWREGISTRY;
}
error("VR_CreateRegistry", VR_CreateRegistry(flag, cmd));
} // vCreate
void vDisplay(char *cmd)
{
DumpTree();
} // vDisplay
void vFind(char *cmd)
{
VERSION ver;
char path[MAXREGPATHLEN];
if (error("VR_GetVersion", VR_GetVersion(cmd, &ver)) == REGERR_OK)
{
if (error("VR_GetPath", VR_GetPath(cmd, sizeof(path), path)) == REGERR_OK)
{
printf("%s found: ver=%d.%d.%d.%d, check=0x%04x, path=%s\n",
cmd, ver.major, ver.minor, ver.release, ver.build, ver.check,
path);
return;
}
}
printf("%s not found.\n", cmd);
return;
} // vFind
void vHelp(char *cmd)
{
puts("Enter a command:");
puts("\tD)isplay - display the current contents of the Registry");
puts("\tI)nstall <name>, <version>, <path> - install a new component");
puts("\tU)pdate <name>, <version>, <path> - update a component");
puts("\tF)ind <name> - returns version and path");
puts("\tV)erify <name> - verify component exists and checks out");
puts("\tC)reate <name> - create a new instance of Navigator (e.g., \"4.0\")");
puts("\tR)emove <name> - deletes a component from the Registry");
puts("\tT)est - perform a simple test on the Registry");
puts("\tver(B)ose ON|off - turn verbose mode on or off");
puts("\tP)retend on|OFF - pretend that test files exist");
puts("\tS)ave - save the Registry to disk");
puts("\tpac(K) registry - squeeze out unused space from the Registry");
puts("\tQ)uit - end the program");
} // vHelp
void vInstall(char *cmd)
{
char name[MAXREGPATHLEN+1];
char path[MAXREGPATHLEN+1];
VERSION ver;
parse(cmd, name, &ver, path);
error("VR_Install", VR_Install(name, path, &ver));
} // vInstall
void vPack(char *cmd)
{
error("VR_PackRegistry", VR_PackRegistry(0));
} // vPack
void vPretend(char *cmd)
{
if (!cmd)
{
gPretend = !!gPretend;
}
else
{
if (stricmp(cmd, "ON") == 0)
gPretend = 1;
else
gPretend = 0;
}
if (gVerbose)
printf("Pretend mode is %s\n", gPretend ? "ON" : "OFF");
} // vPretend
void vRemove(char *cmd)
{
error("VR_Remove", VR_Remove(cmd));
} // vRemove
void vSave(char *cmd)
{
error("VR_Checkpoint", VR_Checkpoint());
} // vSave
void vTest(char *cmd)
{
VERSION ver;
ver.major = 4;
ver.minor = 0;
ver.release = 0;
ver.build = 237;
ver.check = gPretend ? 0xad : 0;
if (error("VR_Install", VR_Install("Navigator/NS.exe",
"c:\\Program Files\\Netscape\\Navigator\\Program\\NETSCAPE.EXE", &ver)))
return;
if (error("VR_Install", VR_Install("Navigator/Help",
"c:\\Program Files\\Netscape\\Navigator\\Program\\NETSCAPE.HLP", &ver)))
return;
if (error("VR_Install", VR_Install("Navigator/NSPR",
"c:\\Program Files\\Netscape\\Navigator\\Program\\NSPR32.DLL", &ver)))
return;
if (error("VR_Install", VR_Install("Navigator/Player",
"c:\\Program Files\\Netscape\\Navigator\\Program\\NSPLAYER.EXE", &ver)))
return;
if (error("VR_Install", VR_Install("Navigator/NSJava",
"c:\\Program Files\\Netscape\\Navigator\\Program\\NSJAVA32.DLL", &ver)))
return;
if (error("VR_Install", VR_Install("Web/Certificate.DB",
"c:\\Program Files\\Netscape\\Navigator\\Program\\CERT.DB", &ver)))
return;
if (error("VR_Install", VR_Install("Web/CertificateNI.DB",
"c:\\Program Files\\Netscape\\Navigator\\Program\\CERTNI.DB", &ver)))
return;
if (error("VR_Install", VR_Install("Web/Keys",
"c:\\Program Files\\Netscape\\Navigator\\Program\\KEY.DB", &ver)))
return;
if (error("VR_Install", VR_Install("MailNews/Postal",
"c:\\Program Files\\Netscape\\Navigator\\System\\POSTAL32.DLL", &ver)))
return;
if (error("VR_Install", VR_Install("MailNews/Folders/Inbox",
"c:\\Program Files\\Netscape\\Navigator\\Mail\\INBOX.SNM", &ver)))
return;
if (error("VR_Install", VR_Install("MailNews/Folders/Sent",
"c:\\Program Files\\Netscape\\Navigator\\Mail\\SENT.SNM", &ver)))
return;
if (error("VR_Install", VR_Install("MailNews/Folders/Trash",
"c:\\Program Files\\Netscape\\Navigator\\Mail\\TRASH.SNM", &ver)))
return;
if (error("VR_Install", VR_Install("Components/NUL",
"c:\\Program Files\\Netscape\\Navigator\\Program\\Plugins\\NPNUL32.DLL", &ver)))
return;
if (error("VR_Install", VR_Install("Components/PointCast",
"c:\\Program Files\\Netscape\\Navigator\\Program\\Plugins\\NPPCN32.DLL", &ver)))
return;
if (error("VR_Install", VR_Install("Components/AWT",
"c:\\Program Files\\Netscape\\Navigator\\Program\\Java\\bin\\AWT3220.DLL", &ver)))
return;
if (error("VR_Install", VR_Install("Components/MM",
"c:\\Program Files\\Netscape\\Navigator\\Program\\Java\\bin\\MM3220.DLL", &ver)))
return;
if (error("VR_Install", VR_Install("Java/Classes.Zip",
"c:\\Program Files\\Netscape\\Navigator\\Program\\Java\\classes\\MOZ2_0.ZIP", &ver)))
return;
if (error("VR_Install", VR_Install("Java/Classes Directory",
"c:\\Program Files\\Netscape\\Navigator\\Program\\Java\\classes\\MOZ2_0", &ver)))
return;
} // vTest
void vUpdate(char *cmd)
{
char name[MAXREGPATHLEN+1];
char path[MAXREGPATHLEN+1];
VERSION ver;
parse(cmd, name, &ver, path);
error("VR_Update", VR_Update(name, path, &ver));
} // vUpdate
void vVerify(char *cmd)
{
error("VR_CheckEntry", VR_CheckEntry(0, cmd));
} // vVerify
void interp(void)
{
char line[256];
char *p;
while(1)
{
putchar('>');
putchar(' ');
flushall();
gets(line);
// p points to next word after verb on command line
p = line;
while (*p && *p!=' ')
p++;
if (!*p)
p = 0;
else
{
while(*p && *p==' ')
p++;
}
switch(toupper(line[0]))
{
case 'B':
vVerbose(p);
break;
case 'C':
vCreate(p);
break;
case 'D':
vDisplay(p);
break;
case 'F':
vFind(p);
break;
case 'H':
default:
vHelp(line);
break;
case 'I':
vInstall(p);
break;
case 'K':
vPack(p);
break;
case 'P':
vPretend(p);
break;
case 'R':
vRemove(p);
break;
case 'S':
vSave(p);
break;
case 'T':
vTest(p);
break;
case 'U':
vUpdate(p);
break;
case 'V':
vVerify(p);
break;
case 'Q':
case 'X':
vSave(0);
return;
} // switch
} // while
assert(0);
return; // shouldn't get here
} // interp
// EOF: interp.c

View File

@@ -0,0 +1,438 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include "NSReg.h"
#include "VerReg.h"
extern void interp(void);
#define REGFILE "c:\\temp\\reg.dat"
char *gRegistry;
int main(int argc, char *argv[]);
char *errstr(REGERR err)
{
switch( err )
{
case REGERR_OK:
return "REGERR_OK";
case REGERR_FAIL:
return "REGERR_FAIL";
case REGERR_NOMORE:
return "REGERR_MORE";
case REGERR_NOFIND:
return "REGERR_NOFIND";
case REGERR_BADREAD:
return "REGERR_BADREAD";
case REGERR_BADLOCN:
return "REGERR_BADLOCN";
case REGERR_PARAM:
return "REGERR_PARAM";
case REGERR_BADMAGIC:
return "REGERR_BADMAGIC";
default:
return "<Unknown>";
}
} // errstr
int CreateEmptyRegistry(void)
{
#if 0
int fh;
remove(REGFILE); // ignore errors like file not found
fh = _open(REGFILE, _O_CREAT, _S_IREAD|_S_IWRITE);
if (fh < 0)
return -1;
close(fh);
return 0;
#endif
return VR_CreateRegistry(CR_NEWREGISTRY, "4.0");
} // CreateEmptyRegistry
int BuildTree(void)
{
REGERR err;
err = NR_RegAdd(0,"/Machine/Old");
if (err != REGERR_OK)
{
printf("NR_RegAdd() returned %s.\n", errstr(err));
return err;
}
err = NR_RegAdd(0,"/User");
if (err != REGERR_OK)
{
printf("NR_RegAdd() returned %s.\n", errstr(err));
return err;
}
err = NR_RegAdd(0,"/Machine/4.0/Name1=Val1");
if (err != REGERR_OK)
{
printf("NR_RegAdd() returned %s.\n", errstr(err));
return err;
}
err = NR_RegAdd(0,"/Machine/4.0/Name2=Val2");
if (err != REGERR_OK)
{
printf("NR_RegAdd() returned %s.\n", errstr(err));
return err;
}
err = NR_RegAdd(0,"/Machine/4.0/Name2=Val3");
if (err != REGERR_OK)
{
printf("NR_RegAdd() returned %s.\n", errstr(err));
return err;
}
err = NR_RegAdd(0,"/Machine/4.0/Name3=Val4");
if (err != REGERR_OK)
{
printf("NR_RegAdd() returned %s.\n", errstr(err));
return err;
}
return VR_Checkpoint();
} // BuildTree
int FindKeys(void)
{
RKEY key;
REGERR err;
char buf[80];
if (NR_RegGetKey(0, "", &key) == REGERR_OK)
{
printf("NR_RegGetKey returns ok for an empty path.\n");
return 1;
}
if (NR_RegGetKey(0, "/", &key) != REGERR_OK)
{
printf("NR_RegGetKey couldn't find root.\n");
return 1;
}
if (NR_RegGetKey(0, "/Machine/Old", &key) != REGERR_OK)
{
printf("NR_RegGetKey couldn't find Old\n");
return 1;
}
printf("NR_RegGetKey returns key for Old as: 0x%lx\n", (long) key);
if (NR_RegGetKey(0, "/Machine/4.0", &key) != REGERR_OK)
{
printf("NR_RegGetKey couldn't find 4.0\n");
return 1;
}
printf("NR_RegGetKey returns key for 4.0 as: 0x%lx\n", (long) key);
// ----------------------------------------
if ((err = NR_RegFindValue(0, "/Machine/4.0/Name3", 64, buf)) != REGERR_OK)
{
printf("NR_RegFindValue (no key) returns %s\n", errstr(err));
return 1;
}
printf("NR_RegFindValue (no key) of Name3 = %s\n", buf);
if (NR_RegFindValue(key, "Aliens", 64, buf) == REGERR_OK)
{
printf("NR_RegFindValue finds Aliens.\n");
return 1;
}
if ((err = NR_RegFindValue(key, "Name3", 64, buf)) != REGERR_OK)
{
printf("NR_RegFindValue (w/key) returns %s\n", errstr(err));
return 1;
}
printf("NR_RegFindValue (w/key) of Name3 = %s\n", buf);
return 0;
} // FindTree
int DumpTree(void)
{
char *path;
char *line = "------------------------------------------------------------";
path = malloc(2048);
if (!path)
return REGERR_FAIL;
strcpy(path, "/");
puts(line);
puts(path);
while (NR_RegNext( 0, 512, path ) == REGERR_OK)
{
puts(path);
}
puts(line);
return 0;
} // DumpTree
int ChangeKeys(void)
{
REGERR err;
err = NR_RegUpdate(0,"/Machine/4.0/name3", "Infospect Software, Inc.");
if (err)
{
printf("Couldn't update name3's value to ISI.\n");
return err;
}
err = NR_RegUpdate(0,"/Machine/4.0/name3=Infospect Software, Inc.", "\"Jonathan=Kid1\"");
if (err)
{
printf("Couldn't update name3's value to Jon.\n");
return err;
}
err = NR_RegRename(0,"/Machine/4.0/name3=\"Jonathan=Kid1\"", "First born");
if (err)
{
printf("Couldn't update name3's name to First born.\n");
return err;
}
err = NR_RegUpdate(0,"/Machine/4.0/name2=Val2", "Kelley Ann");
if (err)
{
printf("Couldn't update name2's value to Kelley.\n");
return err;
}
return VR_Checkpoint();
} // ChangeKeys
int DeleteKeys(void)
{
REGERR err;
err = NR_RegDelete(0, "/User");
if (err)
{
printf("NR_RegDelete returned %s.\n", errstr(err));
return err;
}
return VR_Checkpoint();
} // DeleteKeys
int StressTest(void)
{
REGERR err;
RKEY key;
printf("Starting stress...\n");
err = NR_RegGetKey(0, "/Machine/4.0", &key);
if (err)
{
printf("Error getting key for 4.0 = %s\n", errstr(err));
return err;
}
err = NR_RegAdd(key, "A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/"
"A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/"
"A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/" );
if (err)
{
printf("Adding humungous string returned %s\n", errstr(err));
return err;
}
// TODO: Add a value to one of the middle keys, get it back.
printf("Stress done.\n");
return 0;
} // StressTest
int Install(void)
{
int err;
VERSION ver;
ver.major = 4;
ver.minor = 2;
ver.release = 10;
ver.build = 937;
ver.check = 0;
err = VR_Install("Web/Navigator/netscape.exe",
"c:\\Netscape\\NETSCAPE.EXE", &ver);
if (err)
return err;
ver.release = 19;
ver.build = 722;
ver.check = 0;
err = VR_Install("Web/Navigator/nspr.dll",
"c:\\Netscape\\System\\Vtcprac.386", &ver);
if (err)
return err;
return VR_Checkpoint();
}
int GetInfo(void)
{
int err;
char buf[256];
VERSION ver;
err = VR_GetPath("Web/Navigator/nspr.dll", 256, buf);
if (err)
return err;
printf("GetPath(nspr.dll) returns %s\n", buf);
err = VR_GetVersion("Web/Navigator/netscape.exe", &ver);
if (err)
return err;
printf("GetVersion(netscape.exe) returns %d.%d.%d.%d and check=%d\n",
ver.major, ver.minor, ver.release, ver.build, ver.check);
return 0;
}
int main(int argc, char *argv[])
{
printf("Registry Test 10/01/96.\n");
if (argc > 1)
{
gRegistry = argv[1];
}
else
{
gRegistry = REGFILE;
}
VR_RegistryName(gRegistry);
#if 1
if (NR_RegOpen(gRegistry) != REGERR_OK)
VR_CreateRegistry(CR_NEWREGISTRY, "4.0");
interp();
#else
if (CreateEmptyRegistry())
goto abort;
if (Install())
goto done;
if (DumpTree())
goto done;
if (GetInfo())
goto done;
#if defined(TEST_NR)
if ((err = NR_RegOpen(REGFILE)) != REGERR_OK)
{
printf("NR_RegOpen(%s) returned %s...Test aborted.\n", REGFILE, errstr(err));
goto abort;
}
if (BuildTree())
goto done;
if (FindKeys())
goto done;
if (DumpTree())
goto done;
if (ChangeKeys())
goto done;
if (DeleteKeys())
goto done;
if (DumpTree())
goto done;
if (StressTest())
goto done;
if (DumpTree())
goto done;
done:
NR_RegClose();
#else
done:
#endif
abort:
puts("Press Enter to continue...");
getchar();
#endif
return 0;
}

File diff suppressed because it is too large Load Diff

30
mozilla/xpcom/Makefile.in Normal file
View 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 = public src
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/rules.mk

6027
mozilla/xpcom/base/IIDS.h Normal file

File diff suppressed because it is too large Load Diff

170
mozilla/xpcom/base/nsAgg.h Normal file
View 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsAgg_h___
#define nsAgg_h___
#include "nsISupports.h"
/**
* Outer objects can implement nsIOuter if they choose, allowing them to
* get notification if their inner objects (children) are effectively freed.
* This allows them to reset any state associated with the inner object and
* potentially unload it.
*/
class nsIOuter : public nsISupports {
public:
/**
* This method is called whenever an inner object's refcount is about to
* become zero and the inner object should be released by the outer. This
* allows the outer to clean up any state associated with the inner and
* potentially unload the inner object. This method should call
* inner->Release().
*/
NS_IMETHOD
ReleaseInner(nsISupports* inner) = 0;
};
#define NS_IOUTER_IID \
{ /* ea0bf9f0-3d67-11d2-8163-006008119d7a */ \
0xea0bf9f0, \
0x3d67, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
////////////////////////////////////////////////////////////////////////////////
// Put this in your class's declaration:
#define NS_DECL_AGGREGATED \
NS_DECL_ISUPPORTS \
\
protected: \
\
/* You must implement this operation instead of the nsISupports */ \
/* methods if you inherit from nsAggregated. */ \
NS_IMETHOD \
AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr); \
\
class Internal : public nsISupports { \
public: \
\
Internal() {} \
\
NS_IMETHOD QueryInterface(const nsIID& aIID, \
void** aInstancePtr); \
NS_IMETHOD_(nsrefcnt) AddRef(void); \
NS_IMETHOD_(nsrefcnt) Release(void); \
\
}; \
\
friend class Internal; \
\
nsISupports* fOuter; \
Internal fAggregated; \
\
nsISupports* GetInner(void) { return &fAggregated; } \
\
public: \
// Put this in your class's constructor:
#define NS_INIT_AGGREGATED(outer) \
PR_BEGIN_MACRO \
NS_INIT_REFCNT(); \
fOuter = outer; \
PR_END_MACRO
// Put this in your class's implementation file:
#define NS_IMPL_AGGREGATED(_class) \
NS_IMETHODIMP \
_class::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
{ \
/* try our own interfaces first before delegating to outer */ \
nsresult rslt = AggregatedQueryInterface(aIID, aInstancePtr); \
if (rslt != NS_OK && fOuter) \
return fOuter->QueryInterface(aIID, aInstancePtr); \
else \
return rslt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::AddRef(void) \
{ \
++mRefCnt; /* keep track of our refcount as well as outer's */ \
if (fOuter) \
return NS_ADDREF(fOuter); \
else \
return mRefCnt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Release(void) \
{ \
if (fOuter) { \
nsISupports* outer = fOuter; /* in case we release ourself */ \
nsIOuter* outerIntf; \
static NS_DEFINE_IID(kIOuterIID, NS_IOUTER_IID); \
if (mRefCnt == 1 && \
outer->QueryInterface(kIOuterIID, \
(void**)&outerIntf) == NS_OK) { \
outerIntf->ReleaseInner(GetInner()); \
outerIntf->Release(); \
} \
else \
--mRefCnt; /* keep track of our refcount as well as outer's */ \
return outer->Release(); \
} \
else { \
if (--mRefCnt == 0) { \
delete this; \
return 0; \
} \
return mRefCnt; \
} \
} \
\
NS_IMETHODIMP \
_class::Internal::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
return agg->AggregatedQueryInterface(aIID, aInstancePtr); \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Internal::AddRef(void) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
return ++agg->mRefCnt; \
} \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Internal::Release(void) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
if (--agg->mRefCnt == 0) { \
delete agg; \
return 0; \
} \
return agg->mRefCnt; \
} \
#endif /* nsAgg_h___ */

View File

@@ -0,0 +1,129 @@
/* -*- 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
////////////////////////////////////////////////////////////////////////////////
// Implementation of nsIAllocator using NSPR
////////////////////////////////////////////////////////////////////////////////
#include "nsAllocator.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIAllocatorIID, NS_IALLOCATOR_IID);
nsAllocator::nsAllocator(nsISupports* outer)
{
NS_INIT_AGGREGATED(outer);
}
nsAllocator::~nsAllocator(void)
{
}
NS_IMPL_AGGREGATED(nsAllocator);
NS_METHOD
nsAllocator::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIAllocatorIID) ||
aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_METHOD
nsAllocator::Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr)
{
if (outer && !aIID.Equals(kISupportsIID))
return NS_NOINTERFACE; // XXX right error?
nsAllocator* mm = new nsAllocator(outer);
if (mm == NULL)
return NS_ERROR_OUT_OF_MEMORY;
mm->AddRef();
if (aIID.Equals(kISupportsIID))
*aInstancePtr = mm->GetInner();
else
*aInstancePtr = mm;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
NS_METHOD_(void*)
nsAllocator::Alloc(PRUint32 size)
{
return PR_Malloc(size);
}
NS_METHOD_(void*)
nsAllocator::Realloc(void* ptr, PRUint32 size)
{
return PR_Realloc(ptr, size);
}
NS_METHOD
nsAllocator::Free(void* ptr)
{
PR_Free(ptr);
return NS_OK;
}
NS_METHOD
nsAllocator::HeapMinimize(void)
{
#ifdef XP_MAC
// This used to live in the memory allocators no Mac, but does no more
// Needs to be hooked up in the new world.
// CallCacheFlushers(0x7fffffff);
#endif
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
nsAllocatorFactory::nsAllocatorFactory(void)
{
}
nsAllocatorFactory::~nsAllocatorFactory(void)
{
}
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
NS_IMPL_ISUPPORTS(nsAllocatorFactory, kIFactoryIID);
NS_METHOD
nsAllocatorFactory::CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult)
{
return nsAllocator::Create(aOuter, aIID, aResult);
}
NS_METHOD
nsAllocatorFactory::LockFactory(PRBool aLock)
{
return NS_OK; // XXX what?
}
////////////////////////////////////////////////////////////////////////////////

View 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
////////////////////////////////////////////////////////////////////////////////
// Implementation of nsIAllocator using NSPR
////////////////////////////////////////////////////////////////////////////////
#ifndef nsAllocator_h__
#define nsAllocator_h__
#include "nsIAllocator.h"
#include "prmem.h"
#include "nsAgg.h"
class nsAllocator : public nsIAllocator {
public:
/**
* Allocates a block of memory of a particular size.
*
* @param size - the size of the block to allocate
* @result the block of memory
*/
NS_IMETHOD_(void*) Alloc(PRUint32 size);
/**
* Reallocates a block of memory to a new size.
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size);
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
*/
NS_IMETHOD Free(void* ptr);
/**
* Attempts to shrink the heap.
*/
NS_IMETHOD HeapMinimize(void);
////////////////////////////////////////////////////////////////////////////
nsAllocator(nsISupports* outer);
virtual ~nsAllocator(void);
NS_DECL_AGGREGATED
static NS_METHOD
Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr);
};
////////////////////////////////////////////////////////////////////////////////
#include "nsIFactory.h"
class nsAllocatorFactory : nsIFactory {
public:
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
nsAllocatorFactory(void);
~nsAllocatorFactory(void);
NS_DECL_ISUPPORTS
};
////////////////////////////////////////////////////////////////////////////////
#endif // nsAllocator_h__

View File

@@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#include "nsCOMPtr.h"
void
nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
{
if ( rawPtr )
NSCAP_ADDREF(rawPtr);
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
}
void
nsCOMPtr_base::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result )
{
nsresult status = NS_OK;
if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) )
rawPtr = 0;
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
if ( result )
*result = status;
}
void**
nsCOMPtr_base::begin_assignment()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
return NSCAP_REINTERPRET_CAST(void**, &mRawPtr);
}

View File

@@ -0,0 +1,668 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsCOMPtr_h___
#define nsCOMPtr_h___
// Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
#ifndef nsDebug_h___
#include "nsDebug.h"
// for |NS_PRECONDITION|
#endif
#ifndef nsISupports_h___
#include "nsISupports.h"
// for |nsresult|, |NS_ADDREF|, et al
#endif
/*
TO DO...
+ make alternative function for |getter_AddRefs| (or something)
+ make constructor for |nsQueryInterface| explicit (suddenly construct/assign from raw pointer becomes illegal)
+ Improve internal documentation
+ mention *&
+ alternatives for comparison
+ do_QueryInterface
*/
/* USER MANUAL
See also:
<http://www.meer.net/ScottCollins/doc/nsCOMPtr.html>, or
<http://www.mozilla.org/projects/xpcom/nsCOMPtr.html>
What is |nsCOMPtr|?
|nsCOMPtr| is a `smart-pointer'. It is a template class that acts, syntactically,
just like an ordinary pointer in C or C++, i.e., you can apply |*| or |->| to it to
`get to' what it points at. |nsCOMPtr| is smart in that, unlike a raw COM
interface pointer, |nsCOMPtr| manages |AddRef|, |Release|, and |QueryInterface|
_for_ you.
For instance, here is a typical snippet of code (at its most compact) where you assign
a COM interface pointer into a member variable:
NS_IF_RELEASE(mFoop); // If I have one already, I must release it before over-writing it.
if ( mFooP = aPtr ) // Now it's safe to assign it in, and, if it's not NULL
mFooP->AddRef(); // I must |AddRef| it, since I'll be holding on to it.
If our member variable |mFooP| were a |nsCOMPtr|, however, the snippet above
would look like this:
mFoop = aPtr; // Note: automatically |Release|s the old and |AddRef|s the new
|nsCOMPtr| helps you write code that is leak-proof, exception safe, and significantly
less verbose than you would with raw COM interface pointers. With |nsCOMPtr|, you
may never have to call |AddRef|, |Release|, or |QueryInterface| by hand.
You still have to understand COM. You still have to know which functions return
interface pointers that have already been |AddRef|ed and which don't. You still
have to ensure your program logic doesn't produce circularly referencing garbage.
|nsCOMPtr| is not a panacea. It is, however, helpful, easy to use, well-tested,
and polite. It doesn't require that a function author cooperate with you, nor does
your use force others to use it.
Where should I use |nsCOMPtr|?
...
Where _shouldn't_ I use |nsCOMPtr|?
In public interfaces... [[others]]
How does a |nsCOMPtr| differ from a raw pointer?
A |nsCOMPtr| differs, syntactically, from a raw COM interface pointer in three
ways:
+ It's declared differently, e.g.,
// instead of saying // you say
IFoo* fooP; nsCOMPtr<IFoo> fooP;
+ You can't call |AddRef| or |Release| through it,
fooP->AddRef(); // OK fooP->AddRef(); // Error: no permission
fooP->Release(); // OK fooP->Release(); // Error: no permission
+ You can't just apply an |&| to it to pass it to the typical `getter' function
AcquireFoo(&fooP); AcquireFoo( getter_AddRefs(fooP) );
GetFoo(&fooP); GetFoo( getter_doesnt_AddRef(fooP) );
How do I use |nsCOMPtr|?
Typically, you can use a |nsCOMPtr| exactly as you would a standard COM
interface pointer:
IFoo* fooP; nsCOMPtr<IFoo> fooP;
// ... // ...
fooP->SomeFunction(x, y, z); fooP->SomeFunction(x, y, z);
AnotherFunction(fooP); AnotherFunction(fooP);
if ( fooP ) if ( fooP )
// ... // ...
if ( fooP == barP ) if ( fooP == barP )
// ... // ...
There are some differences, though. In particular, you can't call |AddRef| or |Release|
through a |nsCOMPtr| directly, nor would you need to. |AddRef| is called for you
whenever you assign a COM interface pointer _into_ a |nsCOMPtr|. |Release| is
called on the old value, and also when the |nsCOMPtr| goes out of scope. Trying
to call |AddRef| or |Release| yourself will generate a compile-time error.
fooP->AddRef(); // fooP->AddRef(); // ERROR: no permission
fooP->Release(); // fooP->Release(); // ERROR: no permission
The final difference is that a bare |nsCOMPtr| (or rather a pointer to it) can't
be supplied as an argument to a function that `fills in' a COM interface pointer.
Rather it must be wrapped with a utility call that says whether the function calls
|AddRef| before returning, e.g.,
...->QueryInterface(riid, &fooP) ...->QueryInterface(riid, getter_AddRefs(fooP))
LookupFoo(&fooP); LookupFoo( getter_doesnt_AddRef(fooP) );
Don't worry. It's a compile-time error if you forget to wrap it.
Compare the raw-pointer way...
IFoo* foo = 0;
nsresult status = CreateIFoo(&foo);
if ( NS_SUCCEEDED(status) )
{
IBar* bar = 0;
if ( NS_SUCCEEDED(status = foo->QueryInterface(riid, &bar)) )
{
IFooBar* foobar = 0;
if ( NS_SUCCEEDED(status = CreateIFooBar(foo, bar, &foobar)) )
{
foobar->DoTheReallyHardThing();
foobar->Release();
}
bar->Release();
}
foo->Release();
}
To the smart-pointer way...
nsCOMPtr<IFoo> fooP;
nsresult status = CreateIFoo( getter_AddRefs(fooP) );
if ( NS_SUCCEEDED(status) )
if ( nsCOMPtr<IBar> barP( fooP ) )
{
nsCOMPtr<IFooBar> fooBarP;
if ( NS_SUCCEEDED(status = CreateIFooBar(fooP, barP, getter_AddRefs(fooBarP))) )
fooBarP->DoTheReallyHardThing();
}
Is there an easy way to convert my current code?
...
What do I have to beware of?
VC++ < 6.0 _can't_ handle the following situation
class nsIFoo; // forward declare some class
// ...
nsCOMPtr<nsIFoo> bar; // ERROR: incomplete type nsIFoo, etc.
Instead, you must make sure that you actually defined the underlying interface class, e.g.,
#include "nsIFoo.h" // fully defines |class nsIFoo|
// ...
nsCOMPtr<nsIFoo> bar; // no problem
Why is this? It's because VC++ tries to instantiate every member of the template
as soon as it sees the template declarations. Bad compiler. No cookie!
[[Thanks to mjudge, waterson, and pinkerton on this one.]]
Why does |getter_AddRefs| have such a funny name? I.e., why doesn't it follow our
naming conventions?
|getter_AddRefs| and |getter_doesnt_AddRef| use underscores for the same
reason our special macros do, quoting from our coding conventions "...to make them
stick out like a sore thumb". Note also that since |AddRef| is one word,
|getter_AddRefs| and |getter_doesnt_AddRef| couldn't have the right spacing if only inter-
caps were used.
*/
/*
WARNING:
This file defines several macros for internal use only. These macros begin with the
prefix |NSCAP_|. Do not use these macros in your own code. They are for internal use
only for cross-platform compatibility, and are subject to change without notice.
*/
/*
Set up some |#define|s to turn off a couple of troublesome C++ features.
Interestingly, none of the compilers barf on template stuff.
Ideally, we would want declarations like these in a configuration file
that everybody would get. Deciding exactly how to do that should
be part of the process of moving from experimental to production.
Update: ramiro is working on getting these into the configuration system.
*/
#if defined(__GNUG__) && (__GNUC_MINOR__ <= 90) && !defined(SOLARIS)
#define NSCAP_NO_MEMBER_USING_DECLARATIONS
#if (defined(LINUX) || defined(__bsdi__)) && (__GNUC_MINOR__ <= 7)
#define NSCAP_NEED_UNUSED_VIRTUAL_IMPLEMENTATIONS
#endif
#endif
#if defined(SOLARIS) && !defined(__GNUG__)
#define NSCAP_NO_BOOL
#define NSCAP_NO_EXPLICIT
#define NSCAP_NO_NEW_CASTS
#define NSCAP_NO_MEMBER_USING_DECLARATIONS
#endif
#if defined(_MSC_VER) && (_MSC_VER<1100)
#define NSCAP_NO_EXPLICIT
#define NSCAP_NO_BOOL
#endif
#if defined(IRIX)
#define NSCAP_NO_MEMBER_USING_DECLARATIONS
#define NSCAP_NO_EXPLICIT
#define NSCAP_NO_NEW_CASTS
#define NSCAP_NO_BOOL
#endif
#ifdef NSCAP_NO_EXPLICIT
#define explicit
#endif
#ifndef NSCAP_NO_NEW_CASTS
#define NSCAP_REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
#else
#define NSCAP_REINTERPRET_CAST(T,x) ((T)(x))
#endif
#ifndef NSCAP_NO_BOOL
typedef bool NSCAP_BOOL;
#else
typedef PRBool NSCAP_BOOL;
#endif
#ifdef NSCAP_FEATURE_DEBUG_MACROS
#define NSCAP_ADDREF(ptr) NS_ADDREF(ptr)
#define NSCAP_RELEASE(ptr) NS_RELEASE(ptr)
#else
#define NSCAP_ADDREF(ptr) (ptr)->AddRef()
#define NSCAP_RELEASE(ptr) (ptr)->Release()
#endif
/*
WARNING:
VC++4.2 is very picky. To compile under VC++4.2, the classes must be defined
in an order that satisfies:
nsDerivedSafe < nsCOMPtr
nsDontAddRef < nsCOMPtr
nsCOMPtr < nsGetterAddRefs
The other compilers probably won't complain, so please don't reorder these
classes, on pain of breaking 4.2 compatibility.
*/
template <class T>
class nsDerivedSafe : public T
/*
No client should ever see or have to type the name of this class. It is the
artifact that makes it a compile-time error to call |AddRef| and |Release|
on a |nsCOMPtr|.
See |nsCOMPtr::operator->|, |nsCOMPtr::operator*|, et al.
*/
{
private:
#ifndef NSCAP_NO_MEMBER_USING_DECLARATIONS
using T::AddRef;
using T::Release;
#else
nsrefcnt AddRef();
nsrefcnt Release();
#endif
void operator delete( void* ); // NOT TO BE IMPLEMENTED
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
nsDerivedSafe& operator=( const nsDerivedSafe& ); // NOT TO BE IMPLEMENTED
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
};
#if defined(NSCAP_NO_MEMBER_USING_DECLARATIONS) && defined(NSCAP_NEED_UNUSED_VIRTUAL_IMPLEMENTATIONS)
template <class T>
nsrefcnt
nsDerivedSafe<T>::AddRef()
{
return 0;
}
template <class T>
nsrefcnt
nsDerivedSafe<T>::Release()
{
return 0;
}
#endif
template <class T>
struct nsDontQueryInterface
/*
...
*/
{
explicit
nsDontQueryInterface( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
nsDontQueryInterface<T>
dont_QueryInterface( T* aRawPtr )
{
return nsDontQueryInterface<T>(aRawPtr);
}
struct nsQueryInterface
{
// explicit
nsQueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
: mRawPtr(aRawPtr),
mErrorPtr(error)
{
// nothing else to do here
}
nsISupports* mRawPtr;
nsresult* mErrorPtr;
};
inline
nsQueryInterface
do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
{
return nsQueryInterface(aRawPtr, error);
}
template <class T>
struct nsDontAddRef
/*
...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
|AddRef|ing it. You would rarely use this directly, but rather through the
machinery of |getter_AddRefs| in the argument list to functions that |AddRef|
their results before returning them to the caller.
See also |getter_AddRefs()| and |class nsGetterAddRefs|.
*/
{
explicit
nsDontAddRef( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
nsDontAddRef<T>
dont_AddRef( T* aRawPtr )
/*
...makes typing easier, because it deduces the template type, e.g.,
you write |dont_AddRef(fooP)| instead of |nsDontAddRef<IFoo>(fooP)|.
Like the class it is shorthand for, you would rarely use this directly,
but rather through |getter_AddRefs|.
*/
{
return nsDontAddRef<T>(aRawPtr);
}
class nsCOMPtr_base
{
public:
nsCOMPtr_base( nsISupports* rawPtr = 0 )
: mRawPtr(rawPtr)
{
// nothing else to do here
}
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
NS_EXPORT void assign_with_AddRef( nsISupports* );
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
NS_EXPORT void** begin_assignment();
protected:
nsISupports* mRawPtr;
};
template <class T>
class nsCOMPtr : private nsCOMPtr_base
/*
...
*/
{
public:
typedef T element_type;
nsCOMPtr()
// : nsCOMPtr_base(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, T::IID(), aSmartPtr.mErrorPtr);
}
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
// nothing else to do here
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
{
assign_with_QueryInterface(rhs.mRawPtr, T::IID(), rhs.mErrorPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontAddRef<T>& rhs )
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsCOMPtr& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsDerivedSafe<T>*
get() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
return NSCAP_REINTERPRET_CAST(nsDerivedSafe<T>*, mRawPtr);
}
nsDerivedSafe<T>*
operator->() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
return get();
}
nsDerivedSafe<T>&
operator*() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
return *get();
}
operator nsDerivedSafe<T>*() const
{
return get();
}
#if 0
private:
friend class nsGetterAddRefs<T>;
/*
In a perfect world, the following member function, |StartAssignment|, would be private.
It is and should be only accessed by the closely related class |nsGetterAddRefs<T>|.
Unfortunately, some compilers---most notably VC++5.0---fail to grok the
friend declaration above or in any alternate acceptable form. So, physically
it will be public (until our compilers get smarter); but it is not to be
considered part of the logical public interface.
*/
#endif
T**
StartAssignment()
{
return NSCAP_REINTERPRET_CAST(T**, begin_assignment());
}
};
template <class T>
class nsGetterAddRefs
/*
...
This class is designed to be used for anonymous temporary objects in the
argument list of calls that return COM interface pointers, e.g.,
nsCOMPtr<IFoo> fooP;
...->QueryInterface(iid, nsGetterAddRefs<IFoo>(fooP))
...->QueryInterface(iid, getter_AddRefs(fooP))
When initialized with a |nsCOMPtr|, as in the example above, it returns
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
case) can fill in. When this temporary object goes out of scope, just after
the call returns, its destructor assigned the resulting interface pointer, i.e.,
|QueryInterface|s result, into the |nsCOMPtr| it was initialized with.
See also |nsGetterDoesntAddRef|.
*/
{
public:
explicit
nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
: mTargetSmartPtr(aSmartPtr)
{
// nothing else to do
}
operator void**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment());
}
T*&
operator*()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return *(mTargetSmartPtr.StartAssignment());
}
operator T**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return mTargetSmartPtr.StartAssignment();
}
private:
nsCOMPtr<T>& mTargetSmartPtr;
};
template <class T>
inline
nsGetterAddRefs<T>
getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
/*
Used around a |nsCOMPtr| when
...makes the class |nsGetterAddRefs<T>| invisible.
*/
{
return nsGetterAddRefs<T>(aSmartPtr);
}
#endif // !defined(nsCOMPtr_h___)

218
mozilla/xpcom/base/nsCom.h Normal file
View File

@@ -0,0 +1,218 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsCom_h__
#define nsCom_h__
/*
* API Import/Export macros
*/
#ifdef _IMPL_NS_COM
#ifdef XP_PC
#define NS_COM _declspec(dllexport)
#else /* !XP_PC */
#define NS_COM
#endif /* !XP_PC */
#else /* !_IMPL_NS_COM */
#ifdef XP_PC
#define NS_COM _declspec(dllimport)
#else /* !XP_PC */
#define NS_COM
#endif /* !XP_PC */
#endif /* !_IMPL_NS_COM */
/*
* DLL Export macro
*/
#if defined(XP_PC)
#define NS_EXPORT _declspec(dllexport)
#define NS_EXPORT_(type) _declspec(dllexport) type __stdcall
#define NS_IMETHOD_(type) virtual type __stdcall
#define NS_IMETHOD virtual nsresult __stdcall
#define NS_IMETHODIMP_(type) type __stdcall
#define NS_IMETHODIMP nsresult __stdcall
#define NS_METHOD_(type) type __stdcall
#define NS_METHOD nsresult __stdcall
#elif defined(XP_MAC)
#define NS_EXPORT __declspec(export)
#define NS_EXPORT_(type) __declspec(export) type
#define NS_IMETHOD_(type) virtual type
#define NS_IMETHOD virtual nsresult
#define NS_IMETHODIMP_(type) type
#define NS_IMETHODIMP nsresult
#define NS_METHOD_(type) type
#define NS_METHOD nsresult
#else /* !XP_PC && !XP_MAC */
#define NS_EXPORT
#define NS_EXPORT_(type) type
#define NS_IMETHOD_(type) virtual type
#define NS_IMETHOD virtual nsresult
#define NS_IMETHODIMP_(type) type
#define NS_IMETHODIMP nsresult
#define NS_METHOD_(type) type
#define NS_METHOD nsresult
#endif /* !XP_PC */
/* use these functions to associate get/set methods with a
C++ member variable
*/
#define NS_METHOD_GETTER(_method, _type, _member) \
_method(_type* aResult) \
{\
if (!aResult) return NS_ERROR_NULL_POINTER; \
*aResult = _member; \
return NS_OK; \
}
#define NS_METHOD_SETTER(_method, _type, _member) \
_method(_type aResult) \
{ \
_member = aResult; \
return NS_OK; \
}
/*
* special for strings to get/set char* strings
* using PL_strdup and PR_FREEIF
*/
#define NS_METHOD_GETTER_STR(_method,_member) \
_method(char* *aString)\
{\
if (!aString) return NS_ERROR_NULL_POINTER; \
*aString = PL_strdup(_member); \
return NS_OK; \
}
#define NS_METHOD_SETTER_STR(_method, _member) \
_method(char *aString)\
{\
PR_FREEIF(_member);\
if (aString) _member = PL_strdup(aString); \
else _member = nsnull;\
return NS_OK; \
}
/* Getter/Setter macros.
Usage:
NS_IMPL_[CLASS_]GETTER[_<type>](method, [type,] member);
NS_IMPL_[CLASS_]SETTER[_<type>](method, [type,] member);
NS_IMPL_[CLASS_]GETSET[_<type>]([class, ]postfix, [type,] member);
where:
CLASS_ - implementation is inside a class definition
(otherwise the class name is needed)
Do NOT use in publicly exported header files, because
the implementation may be included many times over.
Instead, use the non-CLASS_ version.
_<type> - For more complex (STR, IFACE) data types
(otherwise the simple data type is needed)
method - name of the method, such as GetWidth or SetColor
type - simple data type if required
member - class member variable such as m_width or mColor
class - the class name, such as Window or MyObject
postfix - Method part after Get/Set such as "Width" for "GetWidth"
Example:
class Window {
public:
NS_IMPL_CLASS_GETSET(Width, int, m_width);
NS_IMPL_CLASS_GETTER_STR(GetColor, m_color);
NS_IMETHOD SetColor(char *color);
private:
int m_width; // read/write
char *m_color; // readonly
};
// defined outside of class
NS_IMPL_SETTER_STR(Window::GetColor, m_color);
Questions/Comments to alecf@netscape.com
*/
/*
* Getter/Setter implementation within a class definition
*/
/* simple data types */
#define NS_IMPL_CLASS_GETTER(_method, _type, _member) \
NS_IMETHOD NS_METHOD_GETTER(_method, _type, _member)
#define NS_IMPL_CLASS_SETTER(_method, _type, _member) \
NS_IMETHOD NS_METHOD_SETTER(_method, _type, _member)
#define NS_IMPL_CLASS_GETSET(_postfix, _type, _member) \
NS_IMPL_CLASS_GETTER(Get##_postfix, _type, _member) \
NS_IMPL_CLASS_SETTER(Set##_postfix, _type, _member)
/* strings */
#define NS_IMPL_CLASS_GETTER_STR(_method, _member) \
NS_IMETHOD NS_METHOD_GETTER_STR(_method, _member)
#define NS_IMPL_CLASS_SETTER_STR(_method, _member) \
NS_IMETHOD NS_METHOD_SETTER_STR(_method, _member)
#define NS_IMPL_CLASS_GETSET_STR(_postfix, _member) \
NS_IMPL_CLASS_GETTER_STR(Get##_postfix, _member) \
NS_IMPL_CLASS_SETTER_STR(Set##_postfix, _member)
/* Getter/Setter implementation outside of a class definition */
/* simple data types */
#define NS_IMPL_GETTER(_method, _type, _member) \
NS_IMETHODIMP NS_METHOD_GETTER(_method, _type, _member)
#define NS_IMPL_SETTER(_method, _type, _member) \
NS_IMETHODIMP NS_METHOD_SETTER(_method, _type, _member)
#define NS_IMPL_GETSET(_class, _postfix, _type, _member) \
NS_IMPL_GETTER(_class::Get##_postfix, _type, _member) \
NS_IMPL_SETTER(_class::Set##_postfix, _type, _member)
/* strings */
#define NS_IMPL_GETTER_STR(_method, _member) \
NS_IMETHODIMP NS_METHOD_GETTER_STR(_method, _member)
#define NS_IMPL_SETTER_STR(_method, _member) \
NS_IMETHODIMP NS_METHOD_SETTER_STR(_method, _member)
#define NS_IMPL_GETSET_STR(_class, _postfix, _member) \
NS_IMPL_GETTER_STR(_class::Get##_postfix, _member) \
NS_IMPL_SETTER_STR(_class::Set##_postfix, _member)
#endif

View File

@@ -0,0 +1,169 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#include "nsDebug.h"
#include "prlog.h"
#if defined(_WIN32)
#include <windows.h>
#elif defined(XP_MAC)
#define TEMP_MAC_HACK
//------------------------
#ifdef TEMP_MAC_HACK
#include <MacTypes.h>
#include <Processes.h>
// TEMPORARY UNTIL WE HAVE MACINTOSH ENVIRONMENT VARIABLES THAT CAN TURN ON
// LOGGING ON MACINTOSH
// At this moment, NSPR's logging is a no-op on Macintosh.
#include <stdarg.h>
#include <stdio.h>
#undef PR_LOG
#define PR_LOG(module,level,args) dprintf args
static void dprintf(const char *format, ...)
{
va_list ap;
Str255 buffer;
va_start(ap, format);
buffer[0] = vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
va_end(ap);
DebugStr(buffer);
}
#endif // TEMP_MAC_HACK
//------------------------
#endif
/**
* Implementation of the nsDebug methods. Note that this code is
* always compiled in, in case some other module that uses it is
* compiled with debugging even if this library is not.
*/
static PRLogModuleInfo* gDebugLog;
static void InitLog(void)
{
if (0 == gDebugLog) {
gDebugLog = PR_NewLogModule("nsDebug");
gDebugLog->level = PR_LOG_DEBUG;
}
}
NS_COM void nsDebug::Abort(const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Abort: at file %s, line %d", aFile, aLine));
PR_LogFlush();
#if defined(_WIN32)
long* __p = (long*) 0x7;
*__p = 0x7;
#elif defined(XP_MAC)
ExitToShell();
#elif defined(XP_UNIX)
::abort();
#endif
}
NS_COM void nsDebug::Break(const char* aFile, PRIntn aLine)
{
#ifndef TEMP_MAC_HACK
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Break: at file %s, line %d", aFile, aLine));
PR_LogFlush();
//XXX this works on win32 only for now. For all the other platforms call Abort
#if defined(_WIN32)
::DebugBreak();
#else
Abort(aFile, aLine);
#endif
#endif // TEMP_MAC_HACK
}
NS_COM void nsDebug::PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PreCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PostCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Assertion: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotYetImplemented: \"%s\" at file %s, line %d", aMessage,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotReached(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotReached: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Error(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Error: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Warning(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Warning: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
}

View File

@@ -0,0 +1,179 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsDebug_h___
#define nsDebug_h___
#include "nsCom.h"
#include "prtypes.h"
#ifdef DEBUG
#define NS_DEBUG
#endif
/**
* Namespace for debugging methods. Note that your code must use the
* macros defined later in this file so that the debug code can be
* conditionally compiled out.
*/
class nsDebug {
public:
// XXX add in log controls here
// XXX probably want printf type arguments
/**
* Abort the executing program. This works on all architectures.
*/
static NS_COM void Abort(const char* aFile, PRIntn aLine);
/**
* Break the executing program into the debugger.
*/
static NS_COM void Break(const char* aFile, PRIntn aLine);
/**
* Log a pre-condition message to the debug log
*/
static NS_COM void PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a post-condition message to the debug log
*/
static NS_COM void PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log an assertion message to the debug log
*/
static NS_COM void Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a not-yet-implemented message to the debug log
*/
static NS_COM void NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a not-reached message to the debug log
*/
static NS_COM void NotReached(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log an error message to the debug log. This call returns.
*/
static NS_COM void Error(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a warning message to the debug log.
*/
static NS_COM void Warning(const char* aMessage,
const char* aFile, PRIntn aLine);
};
#ifdef NS_DEBUG
/**
* Test a precondition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_PRECONDITION(expr,str) \
if (!(expr)) \
nsDebug::PreCondition(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_ASSERTION(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure. The expression will still be
* executed in release mode.
*/
#define NS_VERIFY(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test a post-condition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_POSTCONDITION(expr,str) \
if (!(expr)) \
nsDebug::PostCondition(str, #expr, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTYETIMPLEMENTED(str) \
nsDebug::NotYetImplemented(str, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTREACHED(str) \
nsDebug::NotReached(str, __FILE__, __LINE__)
/**
* Log an error message.
*/
#define NS_ERROR(str) \
nsDebug::Error(str, __FILE__, __LINE__)
/**
* Log a warning message.
*/
#define NS_WARNING(str) \
nsDebug::Warning(str, __FILE__, __LINE__)
/**
* Trigger an abort
*/
#define NS_ABORT() \
nsDebug::Abort(__FILE__, __LINE__)
/**
* Cause a break
*/
#define NS_BREAK() \
nsDebug::Break(__FILE__, __LINE__)
#else /* NS_DEBUG */
#define NS_PRECONDITION(expr,str) {}
#define NS_ASSERTION(expr,str) {}
#define NS_VERIFY(expr,str) expr
#define NS_POSTCONDITION(expr,str) {}
#define NS_NOTYETIMPLEMENTED(str) {}
#define NS_NOTREACHED(str) {}
#define NS_ERROR(str) {}
#define NS_WARNING(str) {}
#define NS_ABORT() {}
#define NS_BREAK() {}
#endif /* ! NS_DEBUG */
#endif /* nsDebug_h___ */

View File

@@ -0,0 +1,186 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsError_h
#define nsError_h
#ifndef prtypes_h___
#include "prtypes.h"
#endif
/**
* Generic result data type
*/
typedef PRUint32 nsresult;
/*
* To add error code to your module, you need to do the following:
*
* 1) Add a module offset code. Add yours to the bottom of the list
* right below this comment, adding 1.
*
* 2) In your module, define a header file which uses one of the
* NE_ERROR_GENERATExxxxxx macros. Some examples below:
*
* #define NS_ERROR_MYMODULE_MYERROR1 NS_ERROR_GENERATE(NS_ERROR_SEVERITY_ERROR,NS_ERROR_MODULE_MYMODULE,1)
* #define NS_ERROR_MYMODULE_MYERROR2 NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_MYMODULE,2)
* #define NS_ERROR_MYMODULE_MYERROR3 NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_MYMODULE,3)
*
*/
/**
* @name Standard Module Offset Code. Each Module should identify a unique number
* and then all errors associated with that module become offsets from the
* base associated with that module id. There are 16 bits of code bits for
* each module.
*/
#define NS_ERROR_MODULE_XPCOM 1
#define NS_ERROR_MODULE_BASE 2
#define NS_ERROR_MODULE_GFX 3
#define NS_ERROR_MODULE_WIDGET 4
#define NS_ERROR_MODULE_CALENDAR 5
#define NS_ERROR_MODULE_NETWORK 6
#define NS_ERROR_MODULE_PLUGINS 7
#define NS_ERROR_MODULE_LAYOUT 8
#define NS_ERROR_MODULE_HTMLPARSER 9
#define NS_ERROR_MODULE_RDF 10
#define NS_ERROR_MODULE_UCONV 11
#define NS_ERROR_MODULE_REG 12
#define NS_ERROR_MODULE_FILES 13
#define NS_ERROR_MODULE_MAILNEWS 16
/**
* @name Standard Error Handling Macros
*/
#define NS_FAILED(_nsresult) ((_nsresult) & 0x80000000)
#define NS_SUCCEEDED(_nsresult) (!((_nsresult) & 0x80000000))
/**
* @name Severity Code. This flag identifies the level of warning
*/
#define NS_ERROR_SEVERITY_SUCCESS 0
#define NS_ERROR_SEVERITY_ERROR 1
/**
* @name Mozilla Code. This flag separates consumers of mozilla code
* from the native platform
*/
#define NS_ERROR_MODULE_BASE_OFFSET 0x45
/**
* @name Standard Error Generating Macros
*/
#define NS_ERROR_GENERATE(sev,module,code) \
((nsresult) (((PRUint32)(sev)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
#define NS_ERROR_GENERATE_SUCCESS(module,code) \
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_SUCCESS)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
#define NS_ERROR_GENERATE_FAILURE(module,code) \
((nsresult) (((PRUint32)(NS_ERROR_SEVERITY_ERROR)<<31) | ((PRUint32)(module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | ((PRUint32)(code))) )
/**
* @name Standard Macros for retrieving error bits
*/
#if PR_BYTES_PER_INT == 4
#define NS_IS_ERROR(err) (((nsresult)(err))<0)
#else
#define NS_IS_ERROR(err) (((((PRUint32)(err)) >> 31) & 0x1) == NS_ERROR_SEVERITY_ERROR)
#endif
#define NS_ERROR_GET_CODE(err) ((err) & 0xffff)
#define NS_ERROR_GET_MODULE(err) (((((err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 0x1fff))
#define NS_ERROR_GET_SEVERITY(err) (((err) >> 31) & 0x1)
/**
* @name Standard return values
*/
/*@{*/
/* Standard "it worked" return value */
#define NS_OK 0
/* The backwards COM false */
#define NS_COMFALSE 1
#define NS_ERROR_BASE ((nsresult) 0xC1F30000)
/* Returned when an instance is not initialized */
#define NS_ERROR_NOT_INITIALIZED (NS_ERROR_BASE + 1)
/* Returned when an instance is already initialized */
#define NS_ERROR_ALREADY_INITIALIZED (NS_ERROR_BASE + 2)
/* Returned by a not implemented function */
#define NS_ERROR_NOT_IMPLEMENTED ((nsresult) 0x80004001L)
/* Returned when a given interface is not supported. */
#define NS_NOINTERFACE ((nsresult) 0x80004002L)
#define NS_ERROR_NO_INTERFACE NS_NOINTERFACE
#define NS_ERROR_INVALID_POINTER ((nsresult) 0x80004003L)
#define NS_ERROR_NULL_POINTER NS_ERROR_INVALID_POINTER
/* Returned when a function aborts */
#define NS_ERROR_ABORT ((nsresult) 0x80004004L)
/* Returned when a function fails */
#define NS_ERROR_FAILURE ((nsresult) 0x80004005L)
/* Returned when an unexpected error occurs */
#define NS_ERROR_UNEXPECTED ((nsresult) 0x8000ffffL)
/* Returned when a memory allocation failes */
#define NS_ERROR_OUT_OF_MEMORY ((nsresult) 0x8007000eL)
/* Returned when an illegal value is passed */
#define NS_ERROR_ILLEGAL_VALUE ((nsresult) 0x80070057L)
#define NS_ERROR_INVALID_ARG NS_ERROR_ILLEGAL_VALUE
/* Returned when a class doesn't allow aggregation */
#define NS_ERROR_NO_AGGREGATION ((nsresult) 0x80040110L)
/* Returned when a class doesn't allow aggregation */
#define NS_ERROR_NOT_AVAILABLE ((nsresult) 0x80040111L)
/* Returned when a class is not registered */
#define NS_ERROR_FACTORY_NOT_REGISTERED ((nsresult) 0x80040154L)
/* Returned when a dynamically loaded factory couldn't be found */
#define NS_ERROR_FACTORY_NOT_LOADED ((nsresult) 0x800401f8L)
/* Returned when a factory doesn't support signatures */
#define NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT \
(NS_ERROR_BASE + 0x101)
/* Returned when a factory already is registered */
#define NS_ERROR_FACTORY_EXISTS (NS_ERROR_BASE + 0x100)
/*@}*/
#endif

View 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIAllocator_h___
#define nsIAllocator_h___
#include "nsISupports.h"
/**
* Unlike IMalloc, this interface returns nsresults and doesn't
* implement the problematic GetSize and DidAlloc routines.
*/
class nsIAllocator : public nsISupports {
public:
/**
* Allocates a block of memory of a particular size.
*
* @param size - the size of the block to allocate
* @result the block of memory
*/
NS_IMETHOD_(void*) Alloc(PRUint32 size) = 0;
/**
* Reallocates a block of memory to a new size.
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size) = 0;
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
*/
NS_IMETHOD Free(void* ptr) = 0;
/**
* Attempts to shrink the heap.
*/
NS_IMETHOD HeapMinimize(void) = 0;
};
#define NS_IALLOCATOR_IID \
{ /* 56def700-b1b9-11d2-8177-006008119d7a */ \
0x56def700, \
0xb1b9, \
0x11d2, \
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
// To get the global memory manager service:
#define NS_ALLOCATOR_CID \
{ /* aafe6770-b1bb-11d2-8177-006008119d7a */ \
0xaafe6770, \
0xb1bb, \
0x11d2, \
{0x81, 0x77, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
////////////////////////////////////////////////////////////////////////////////
#endif /* nsIAllocator_h___ */

View File

@@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#include "nsID.h"
#include "prprf.h"
static const char gIDFormat[] =
"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}";
static const char gIDFormat2[] =
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
/*
* Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} string into
* an nsID
*/
NS_COM PRBool nsID::Parse(char *aIDStr)
{
PRInt32 count = 0;
PRInt32 n1, n2, n3[8];
PRInt32 n0;
if (NULL != aIDStr) {
count = PR_sscanf(aIDStr,
(aIDStr[0] == '{') ? gIDFormat : gIDFormat2,
&n0, &n1, &n2,
&n3[0],&n3[1],&n3[2],&n3[3],
&n3[4],&n3[5],&n3[6],&n3[7]);
m0 = (PRInt32) n0;
m1 = (PRInt16) n1;
m2 = (PRInt16) n2;
for (int i = 0; i < 8; i++) {
m3[i] = (PRInt8) n3[i];
}
}
return (PRBool) (count == 11);
}
/*
* Returns an allocated string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
* format. Caller should delete [] the string.
*/
NS_COM char *nsID::ToString() const
{
char *res = new char[39];
if (res != NULL) {
PR_snprintf(res, 39, gIDFormat,
m0, (PRUint32) m1, (PRUint32) m2,
(PRUint32) m3[0], (PRUint32) m3[1], (PRUint32) m3[2],
(PRUint32) m3[3], (PRUint32) m3[4], (PRUint32) m3[5],
(PRUint32) m3[6], (PRUint32) m3[7]);
}
return res;
}

89
mozilla/xpcom/base/nsID.h Normal file
View File

@@ -0,0 +1,89 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsID_h__
#define nsID_h__
#include "prtypes.h"
#include "string.h"
#include "nsCom.h"
/**
* A "unique identifier". This is modeled after OSF DCE UUIDs.
*/
struct nsID {
/**
* @name Indentifier values
*/
//@{
PRUint32 m0;
PRUint16 m1;
PRUint16 m2;
PRUint8 m3[8];
//@}
/**
* @name Methods
*/
//@{
/**
* Equivalency method. Compares this nsID with another.
* @return <b>PR_TRUE</b> if they are the same, <b>PR_FALSE</b> if not.
*/
inline PRBool Equals(const nsID& other) const {
return (PRBool)
((((PRUint32*) &m0)[0] == ((PRUint32*) &other.m0)[0]) &&
(((PRUint32*) &m0)[1] == ((PRUint32*) &other.m0)[1]) &&
(((PRUint32*) &m0)[2] == ((PRUint32*) &other.m0)[2]) &&
(((PRUint32*) &m0)[3] == ((PRUint32*) &other.m0)[3]));
}
/**
* nsID Parsing method. Turns a {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
* string into an nsID
*/
NS_COM PRBool Parse(char *aIDStr);
/**
* nsID string encoder. Returns an allocated string in
* {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format. Caller should free string.
*/
NS_COM char* ToString() const;
//@}
};
/**
* Declare an ID. If NS_IMPL_IDS is set, a variable <i>_name</i> is declared
* with the given values, otherwise <i>_name</i> is declared as an
* <tt>extern</tt> variable.
*/
#ifdef NS_IMPL_IDS
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
extern "C" const nsID _name = {m0,m1,m2,{m30,m31,m32,m33,m34,m35,m36,m37}}
#else
#define NS_DECLARE_ID(_name,m0,m1,m2,m30,m31,m32,m33,m34,m35,m36,m37) \
extern "C" const nsID _name
#endif
#endif

142
mozilla/xpcom/base/nsIPtr.h Normal file
View File

@@ -0,0 +1,142 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsIPtr_h___
#define nsIPtr_h___
#include "nsISupports.h"
/*
* nsIPtr is an "auto-release pointer" class for nsISupports based interfaces
*
* It's intent is to be a "set and forget" pointer to help with managing
* active references to nsISupports bases objects.
*
* The pointer object ensures that the underlying pointer is always
* released whenever the value is changed or when the object leaves scope.
*
* Proper care needs to be taken when assigning pointers to a nsIPtr.
* When asigning from a C pointer (nsISupports*), the pointer presumes
* an active reference and subsumes it. When assigning from another nsIPtr,
* a new reference is established.
*
* There are 3 ways to assign a value to a nsIPtr.
* 1) Direct construction or assignment from a C pointer.
* 2) Direct construction or assignment form another nsIPtr.
* 3) Usage of an "out parameter" method.
* a) AssignRef() releases the underlying pointer and returns a reference to it.
* Useful for pointer reference out paramaters.
* b) AssignPtr() releases the underlying pointer and returns a pointer to it.
* c) Query() releases the underlying pointer and returns a (void**) pointer to it.
* Useful for calls to QueryInterface()
* 4) The SetAddRef() method. This is equivalent to an assignment followed by an AddRef().
*
* examples:
*
* class It {
* void NS_NewFoo(nsIFoo** aFoo);
* nsIFoo* GetFoo(void);
* void GetBar(nsIBar*& aBar);
* };
*
* nsIFooPtr foo = it->GetFoo();
* nsIBarPtr bar;
*
* it->NS_NewFoo(foo.AssignPtr());
* it->GetBar(bar.AssignRef());
* it->QueryInterface(kIFooIID, foo.Query());
* bar.SetAddRef(new Bar());
*
* Advantages:
* Set and forget. Once a pointer is assigned to a nsIPtr, it is impossible
* to forget to release it.
* Always pre-initialized. You can't forget to initialize the pointer.
*
* Disadvantages:
* Usage of this class doesn't eliminate the need to think about ref counts
* and assign values properly, AddRef'ing as needed.
* The nsIPtr doesn't typecast exactly like a C pointer. In order to achieve
* typecasting, it may be necessary to first cast to a C pointer of the
* underlying type.
*
*/
#define NS_DEF_PTR(cls) \
class cls##Ptr { \
public: \
cls##Ptr(void) : mPtr(0) {} \
cls##Ptr(const cls##Ptr& aCopy) : mPtr(aCopy.mPtr) \
{ NS_IF_ADDREF(mPtr); } \
cls##Ptr(cls* aInterface) : mPtr(aInterface) {} \
~cls##Ptr(void) { NS_IF_RELEASE(mPtr); } \
cls##Ptr& operator=(const cls##Ptr& aCopy) \
{ if(mPtr == aCopy.mPtr) return *this; \
NS_IF_ADDREF(aCopy.mPtr); \
NS_IF_RELEASE(mPtr); \
mPtr = aCopy.mPtr; return *this; } \
cls##Ptr& operator=(cls* aInterface) \
{ if(mPtr == aInterface) return *this; \
NS_IF_RELEASE(mPtr); mPtr = aInterface; \
return *this; } \
cls##Ptr& operator=(PRInt32 aInt) \
{ NS_IF_RELEASE(mPtr); \
return *this; } \
void SetAddRef(cls* aInterface) \
{ if(aInterface == mPtr) return; \
NS_IF_ADDREF(aInterface); \
NS_IF_RELEASE(mPtr); mPtr = aInterface; } \
cls* AddRef(void) { NS_ADDREF(mPtr); return mPtr; } \
cls* IfAddRef(void) \
{ NS_IF_ADDREF(mPtr); return mPtr; } \
cls*& AssignRef(void) \
{ NS_IF_RELEASE(mPtr); return mPtr; } \
cls** AssignPtr(void) \
{ NS_IF_RELEASE(mPtr); return &mPtr; } \
void** Query(void) \
{ NS_IF_RELEASE(mPtr); return (void**)&mPtr; } \
PRBool IsNull() const \
{ return PRBool(0 == mPtr); } \
PRBool IsNotNull() const \
{ return PRBool(0 != mPtr); } \
PRBool operator==(const cls##Ptr& aCopy) const \
{ return PRBool(mPtr == aCopy.mPtr); } \
PRBool operator==(cls* aInterface) const \
{ return PRBool(mPtr == aInterface); } \
PRBool operator!=(const cls##Ptr& aCopy) const \
{ return PRBool(mPtr != aCopy.mPtr); } \
PRBool operator!=(cls* aInterface) const \
{ return PRBool(mPtr != aInterface); } \
cls* operator->(void) { return mPtr; } \
cls& operator*(void) { return *mPtr; } \
operator cls*(void) { return mPtr; } \
const cls* operator->(void) const { return mPtr; } \
const cls& operator*(void) const { return *mPtr; } \
operator const cls* (void) const { return mPtr; } \
private: \
void* operator new(size_t size) { return 0; } \
void operator delete(void* aPtr) {} \
cls* mPtr; \
public: \
friend inline PRBool operator==(const cls* aInterface, const cls##Ptr& aPtr) \
{ return PRBool(aInterface == aPtr.mPtr); } \
friend inline PRBool operator!=(const cls* aInterface, const cls##Ptr& aPtr) \
{ return PRBool(aInterface != aPtr.mPtr); } \
}
#endif // nsIPtr_h___

View File

@@ -0,0 +1,314 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.h"
#include "prprf.h"
#include "prlog.h"
#if defined(_WIN32)
#include <windows.h>
#endif
static PRLogModuleInfo* gTraceRefcntLog;
#if defined(NS_MT_SUPPORTED)
#include "prlock.h"
static PRLock* gTraceLock;
#define LOCK_TRACELOG() PR_Lock(gTraceLock)
#define UNLOCK_TRACELOG() PR_Unlock(gTraceLock)
#else /* ! NT_MT_SUPPORTED */
#define LOCK_TRACELOG()
#define UNLOCK_TRACELOG()
#endif /* ! NS_MT_SUPPORTED */
static void InitTraceLog(void)
{
if (0 == gTraceRefcntLog) {
gTraceRefcntLog = PR_NewLogModule("xpcomrefcnt");
#if defined(NS_MT_SUPPORTED)
gTraceLock = PR_NewLock();
#endif /* NS_MT_SUPPORTED */
}
}
#if defined(_WIN32)
#include "imagehlp.h"
#include <stdio.h>
#if 0
static BOOL __stdcall
EnumSymbolsCB(LPSTR aSymbolName,
ULONG aSymbolAddress,
ULONG aSymbolSize,
PVOID aUserContext)
{
int* countp = (int*) aUserContext;
int count = *countp;
if (count < 3) {
printf(" %p[%4d]: %s\n", aSymbolAddress, aSymbolSize, aSymbolName);
count++;
*countp = count++;
}
return TRUE;
}
static BOOL __stdcall
EnumModulesCB(LPSTR aModuleName,
ULONG aBaseOfDll,
PVOID aUserContext)
{
HANDLE myProcess = ::GetCurrentProcess();
printf("module=%s dll=%x\n", aModuleName, aBaseOfDll);
// int count = 0;
// SymEnumerateSymbols(myProcess, aBaseOfDll, EnumSymbolsCB, (void*) &count);
return TRUE;
}
#endif
/**
* Walk the stack, translating PC's found into strings and recording the
* chain in aBuffer. For this to work properly, the dll's must be rebased
* so that the address in the file agrees with the address in memory.
* Otherwise StackWalk will return FALSE when it hits a frame in a dll's
* whose in memory address doesn't match it's in-file address.
*
* Fortunately, there is a handy dandy routine in IMAGEHLP.DLL that does
* the rebasing and accordingly I've made a tool to use it to rebase the
* DLL's in one fell swoop (see xpcom/tools/windows/rebasedlls.cpp).
*/
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
CONTEXT context;
STACKFRAME frame;
char* cp = aBuffer;
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
// Get the context information for this thread. That way we will
// know where our sp, fp, pc, etc. are and can fill in the
// STACKFRAME with the initial values.
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(myThread, &context);
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
#if 0
SymEnumerateModules(myProcess, EnumModulesCB, NULL);
#endif
// Setup initial stack frame to walk from
memset(&frame, 0, sizeof(frame));
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrPC.Offset = context.Eip;
frame.AddrReturn.Mode = AddrModeFlat;
frame.AddrReturn.Offset = context.Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Ebp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrStack.Offset = context.Esp;
frame.Params[0] = context.Eax;
frame.Params[1] = context.Ecx;
frame.Params[2] = context.Edx;
frame.Params[3] = context.Ebx;
// Now walk the stack and map the pc's to symbol names that we stuff
// append to *cp.
int skip = 2;
int syms = 0;
while (aBufLen > 0) {
char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512];
PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer;
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
pSymbol->MaxNameLength = 512;
DWORD oldAddress = frame.AddrPC.Offset;
BOOL b = ::StackWalk(IMAGE_FILE_MACHINE_I386, myProcess, myThread,
&frame, &context, NULL,
SymFunctionTableAccess,
SymGetModuleBase,
NULL);
if (!b || (0 == frame.AddrPC.Offset)) {
if (syms <= 1) {
skip = 7;
}
break;
}
if (--skip >= 0) {
continue;
}
DWORD disp;
if (SymGetSymFromAddr(myProcess, frame.AddrPC.Offset, &disp, pSymbol)) {
int nameLen = strlen(pSymbol->Name);
if (nameLen + 2 > aBufLen) {
break;
}
memcpy(cp, pSymbol->Name, nameLen);
cp += nameLen;
*cp++ = ' ';
aBufLen -= nameLen + 1;
syms++;
}
else {
if (11 > aBufLen) {
break;
}
char tmp[30];
PR_snprintf(tmp, sizeof(tmp), "0x%08x ", frame.AddrPC.Offset);
memcpy(cp, tmp, 11);
cp += 11;
aBufLen -= 11;
syms++;
}
}
*cp = 0;
}
#else /* _WIN32 */
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
aBuffer[0] = '\0';
}
#endif /* _WIN32 */
NS_COM void
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
#if defined(_WIN32)
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
HANDLE myProcess = ::GetCurrentProcess();
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
BOOL b = ::SymLoadModule(myProcess,
NULL,
(char*)aLibraryName,
(char*)aLibraryName,
0,
0);
// DWORD lastError = 0;
// if (!b) lastError = ::GetLastError();
// printf("loading symbols for library %s => %s [%d]\n", aLibraryName,
// b ? "true" : "false", lastError);
}
#endif
#endif
}
NS_COM unsigned long
nsTraceRefcnt::AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("AddRef: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt-1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM unsigned long
nsTraceRefcnt::Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Release: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt+1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM void
nsTraceRefcnt::Create(void* aPtr,
const char* aType,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Create: %p[%s]: [%s] in %s (line %d)",
aPtr, aType, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}
NS_COM void
nsTraceRefcnt::Destroy(void* aPtr,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Destroy: %p: [%s] in %s (line %d)",
aPtr, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}

View File

@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 nsTraceRefcnt_h___
#define nsTraceRefcnt_h___
#include "nsCom.h"
/**
* This class is used to support tracing (and logging using nspr) of
* addref and release calls. Note that only calls that use the
* NS_ADDREF and related macros in nsISupports can be traced.
*
* The name of the nspr log module is "xpcomrefcnt" (case matters).
*
* This code only performs tracing built with debugging AND when
* built with -DMOZ_TRACE_XPCOM_REFCNT (because it's expensive!).
*/
class nsTraceRefcnt {
public:
static NS_COM unsigned long AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM unsigned long Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM void Create(void* aPtr,
const char* aType,
const char* aFile,
int aLine);
static NS_COM void Destroy(void* aPtr,
const char* aFile,
int aLine);
static NS_COM void LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle);
static NS_COM void WalkTheStack(char* aBuffer, int aBufLen);
};
#endif /* nsTraceRefcnt_h___ */

View File

@@ -0,0 +1,314 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.h"
#include "prprf.h"
#include "prlog.h"
#if defined(_WIN32)
#include <windows.h>
#endif
static PRLogModuleInfo* gTraceRefcntLog;
#if defined(NS_MT_SUPPORTED)
#include "prlock.h"
static PRLock* gTraceLock;
#define LOCK_TRACELOG() PR_Lock(gTraceLock)
#define UNLOCK_TRACELOG() PR_Unlock(gTraceLock)
#else /* ! NT_MT_SUPPORTED */
#define LOCK_TRACELOG()
#define UNLOCK_TRACELOG()
#endif /* ! NS_MT_SUPPORTED */
static void InitTraceLog(void)
{
if (0 == gTraceRefcntLog) {
gTraceRefcntLog = PR_NewLogModule("xpcomrefcnt");
#if defined(NS_MT_SUPPORTED)
gTraceLock = PR_NewLock();
#endif /* NS_MT_SUPPORTED */
}
}
#if defined(_WIN32)
#include "imagehlp.h"
#include <stdio.h>
#if 0
static BOOL __stdcall
EnumSymbolsCB(LPSTR aSymbolName,
ULONG aSymbolAddress,
ULONG aSymbolSize,
PVOID aUserContext)
{
int* countp = (int*) aUserContext;
int count = *countp;
if (count < 3) {
printf(" %p[%4d]: %s\n", aSymbolAddress, aSymbolSize, aSymbolName);
count++;
*countp = count++;
}
return TRUE;
}
static BOOL __stdcall
EnumModulesCB(LPSTR aModuleName,
ULONG aBaseOfDll,
PVOID aUserContext)
{
HANDLE myProcess = ::GetCurrentProcess();
printf("module=%s dll=%x\n", aModuleName, aBaseOfDll);
// int count = 0;
// SymEnumerateSymbols(myProcess, aBaseOfDll, EnumSymbolsCB, (void*) &count);
return TRUE;
}
#endif
/**
* Walk the stack, translating PC's found into strings and recording the
* chain in aBuffer. For this to work properly, the dll's must be rebased
* so that the address in the file agrees with the address in memory.
* Otherwise StackWalk will return FALSE when it hits a frame in a dll's
* whose in memory address doesn't match it's in-file address.
*
* Fortunately, there is a handy dandy routine in IMAGEHLP.DLL that does
* the rebasing and accordingly I've made a tool to use it to rebase the
* DLL's in one fell swoop (see xpcom/tools/windows/rebasedlls.cpp).
*/
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
CONTEXT context;
STACKFRAME frame;
char* cp = aBuffer;
aBuffer[0] = '\0';
aBufLen--; // leave room for nul
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
// Get the context information for this thread. That way we will
// know where our sp, fp, pc, etc. are and can fill in the
// STACKFRAME with the initial values.
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(myThread, &context);
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
#if 0
SymEnumerateModules(myProcess, EnumModulesCB, NULL);
#endif
// Setup initial stack frame to walk from
memset(&frame, 0, sizeof(frame));
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrPC.Offset = context.Eip;
frame.AddrReturn.Mode = AddrModeFlat;
frame.AddrReturn.Offset = context.Ebp;
frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context.Ebp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrStack.Offset = context.Esp;
frame.Params[0] = context.Eax;
frame.Params[1] = context.Ecx;
frame.Params[2] = context.Edx;
frame.Params[3] = context.Ebx;
// Now walk the stack and map the pc's to symbol names that we stuff
// append to *cp.
int skip = 2;
int syms = 0;
while (aBufLen > 0) {
char symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512];
PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer;
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
pSymbol->MaxNameLength = 512;
DWORD oldAddress = frame.AddrPC.Offset;
BOOL b = ::StackWalk(IMAGE_FILE_MACHINE_I386, myProcess, myThread,
&frame, &context, NULL,
SymFunctionTableAccess,
SymGetModuleBase,
NULL);
if (!b || (0 == frame.AddrPC.Offset)) {
if (syms <= 1) {
skip = 7;
}
break;
}
if (--skip >= 0) {
continue;
}
DWORD disp;
if (SymGetSymFromAddr(myProcess, frame.AddrPC.Offset, &disp, pSymbol)) {
int nameLen = strlen(pSymbol->Name);
if (nameLen + 2 > aBufLen) {
break;
}
memcpy(cp, pSymbol->Name, nameLen);
cp += nameLen;
*cp++ = ' ';
aBufLen -= nameLen + 1;
syms++;
}
else {
if (11 > aBufLen) {
break;
}
char tmp[30];
PR_snprintf(tmp, sizeof(tmp), "0x%08x ", frame.AddrPC.Offset);
memcpy(cp, tmp, 11);
cp += 11;
aBufLen -= 11;
syms++;
}
}
*cp = 0;
}
#else /* _WIN32 */
void
nsTraceRefcnt::WalkTheStack(char* aBuffer, int aBufLen)
{
aBuffer[0] = '\0';
}
#endif /* _WIN32 */
NS_COM void
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
#if defined(_WIN32)
InitTraceLog();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
HANDLE myProcess = ::GetCurrentProcess();
if (!SymInitialize(myProcess, ".;..\\lib", TRUE)) {
return;
}
BOOL b = ::SymLoadModule(myProcess,
NULL,
(char*)aLibraryName,
(char*)aLibraryName,
0,
0);
// DWORD lastError = 0;
// if (!b) lastError = ::GetLastError();
// printf("loading symbols for library %s => %s [%d]\n", aLibraryName,
// b ? "true" : "false", lastError);
}
#endif
#endif
}
NS_COM unsigned long
nsTraceRefcnt::AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("AddRef: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt-1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM unsigned long
nsTraceRefcnt::Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Release: %p: %d=>%d [%s] in %s (line %d)",
aPtr, aNewRefcnt+1, aNewRefcnt, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
return aNewRefcnt;
}
NS_COM void
nsTraceRefcnt::Create(void* aPtr,
const char* aType,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Create: %p[%s]: [%s] in %s (line %d)",
aPtr, aType, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}
NS_COM void
nsTraceRefcnt::Destroy(void* aPtr,
const char* aFile,
PRIntn aLine)
{
#ifdef MOZ_TRACE_XPCOM_REFCNT
InitTraceLog();
LOCK_TRACELOG();
if (PR_LOG_TEST(gTraceRefcntLog,PR_LOG_DEBUG)) {
char sb[1000];
WalkTheStack(sb, sizeof(sb));
PR_LOG(gTraceRefcntLog, PR_LOG_DEBUG,
("Destroy: %p: [%s] in %s (line %d)",
aPtr, sb, aFile, aLine));
}
UNLOCK_TRACELOG();
#endif
}

View File

@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 nsTraceRefcnt_h___
#define nsTraceRefcnt_h___
#include "nsCom.h"
/**
* This class is used to support tracing (and logging using nspr) of
* addref and release calls. Note that only calls that use the
* NS_ADDREF and related macros in nsISupports can be traced.
*
* The name of the nspr log module is "xpcomrefcnt" (case matters).
*
* This code only performs tracing built with debugging AND when
* built with -DMOZ_TRACE_XPCOM_REFCNT (because it's expensive!).
*/
class nsTraceRefcnt {
public:
static NS_COM unsigned long AddRef(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM unsigned long Release(void* aPtr,
unsigned long aNewRefcnt,
const char* aFile,
int aLine);
static NS_COM void Create(void* aPtr,
const char* aType,
const char* aFile,
int aLine);
static NS_COM void Destroy(void* aPtr,
const char* aFile,
int aLine);
static NS_COM void LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle);
static NS_COM void WalkTheStack(char* aBuffer, int aBufLen);
};
#endif /* nsTraceRefcnt_h___ */

View File

@@ -0,0 +1,168 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef __mozIClassRegistry_h
#define __mozIClassRegistry_h
#include "nsRepository.h"
/*---------------------------- mozIClassRegistry -------------------------------
| This interface provides access to a mapping from mnemonic interface names |
| to shared libraries where implementations of those interfaces can be located.|
| |
| This interface is designed to provide two things: |
| 1. A means of less static binding between clients and the code that |
| implements the XPCOM interfaces those clients use. This accomplished |
| by the mapping from interface names to nsCID (and the shared libraries |
| that implement those classes). |
| 2. A means of dynamically changing the mapping from interface name to |
| implementation. The canonical example of this is to switch to a |
| "native" widget set versus an "XP" (implemented using gfx) set. |
| |
| The first goal is achieved by storing (in a "Netscape Registry" file, see |
| nsReg.h) information that maps interface/class "names" to information about |
| where to load implementations of those interfaces. That information |
| includes the interface ID, class ID (of the implementation class), and the |
| name of the shared library that contains the implementation. |
| |
| The class registry object will register those classes with the "repository" |
| (see nsRepository.h) the first time a request is made to create an |
| instance. Subsequent requests will simply be forwarded to the repository |
| after the appropriate interface and class IDs are determined. |
| |
| The second goal is accomplished by permitting the mnemonic interface |
| "names" to be "overloaded", that is, mapped to distinct implementations |
| by separate class registry objects. Further, class registries can be |
| cascaded: they can be chained together so that when a name is not |
| recognized by one registry, it can pass the request to the next registry in |
| the chain. Users can control resolution by making the request of a |
| registry further up/down the chain. |
| |
| For example, consider the case of "native" vs. "gfx" widgets. This might |
| be structured by a class registry arrangment like this: |
| |
| nativeWidgetRegistry baseWidgetRegistry |
| +----------+ +----------+ |
| | ----+---------------->| | |
| +----------+ +----------+ |
| |toolbar| -+-----+ |toolbar| -+-----+ |
| +----------+ | +----------+ | |
| |button | -+-----+ |button | -+-----+ |
| +----------+ | +----------+ | |
| V V |
| +-----------------+ +-----------------+ |
| | native.dll | | base.dll | |
| +-----------------+ +-----------------+ |
| |
| If a specialized implementation of widgets is present (e.g., native.dll) |
| then a corresponding class registry object is created and added to the |
| head of the registry chain. Object creation requests (normal ones) are |
| resolved to the native implementation. If such a library is not present, |
| then the resolution is to the base implementation. If objects of the |
| base implementation are required, then creation requests can be directed |
| directly to the baseWidgetRegistry object, rather than the head of the |
| registry chain. |
| |
| It is intended that there be a single instance of this interface, accessed |
| via the Service Manager (see nsServiceManager.h). |
------------------------------------------------------------------------------*/
struct mozIClassRegistry : public ISupports {
/*------------------------------ CreateInstance ----------------------------
| Create an instance of the requested class/interface. The interface |
| ID is required to specify how the result will be treated. The class |
| named by aName must support this interface. The result is placed in |
| ncomment aResult (NULL if the request fails). "start" specifies the |
| registry at which the search for an implementation of the named |
| interface should start. It defaults to 0 (indicating to start at the |
| head of the registry chain). |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateInstance( const char *anInterfaceName,
const nsIID &aIID,
void* *aResult,
const char *start = 0 ) = 0;
/*--------------------------- CreateEnumerator -----------------------------
| Creates an nsIEnumerator interface object that can be used to examine |
| the contents of the registry. "pattern" specifies either "*" or the |
| name of a specific interface that you want to query. "result" will |
| be set to point to a new object (which will be freed on the last call |
| to its Release() member). See nsIEnumerator.h for details on how to |
| use the returned interface pointer. |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateEnumerator( const char *pattern,
nsIEnumerator* *result ) = 0;
}; // mozIClassRegistry
/*-------------------------- mozIClassRegistryEntry ----------------------------
| Objects of this class represent the individual elements that comprise a |
| mozIClassRegistry interface. You obtain such objects by applying the |
| CreateEnumerator member function to the class registry and then applying |
| the CurrentItem member function to the resulting nsIEnumerator interface. |
| |
| Each entry can be queried for the following information: |
| o sub-registry name |
| o interface name |
| o Class ID |
| o IIDs implemented |
| |
| The information obtained from the entry (specifically, the const char* |
| strings) remains valid for the life of the entry (i.e., until you |
| Release() it). |
| |
| Here is an example of code that uses this interface to dump the contents |
| of a mozIClassRegistry: |
| |
| mozIClassRegistry *reg = nsServiceManager::GetService( kIDRegistry ); |
| nsIEnumerator *enum; |
| reg->CreateEnumerator( "*", &enum ); |
| for ( enum->First(); !enum->IsDone(); enum->Next(); ) { |
| mozIClassRegistryEntry *entry; |
| enum->CurrentItem( &entry ); |
| const char *subreg; |
| const char *name; |
| nsCID cid; |
| int numIIDs; |
| entry->GetSubRegistryName( &subreg ); |
| entry->GetInterfaceName( &name ); |
| entry->GetClassID( &cid ); |
| entry->GetNumIIDs( &numIIDs ); |
| cout << subreg << "/" << name << " = " << cid.ToString() << endl; |
| for ( int i = 0; i < numIIDs; i++ ) { |
| nsIID iid; |
| entry->GetInterfaceID( i, &iid ); |
| cout << "/tIID[" << i << "] = " << iid.ToString() << endl; |
| } |
| entry->Release(); |
| } |
| enum->Release(); |
------------------------------------------------------------------------------*/
struct mozIClassRegistryEntry : public nsISupports {
NS_IMETHOD GetSubRegistryName( const char **result ) = 0;
NS_IMETHOD GetInterfaceName( const char **result ) = 0;
NS_IMETHOD GetClassID( nsCID *result ) = 0;
NS_IMETHOD GetNumIIDs( int *result ) = 0;
NS_IMETHOD GetInterfaceID( int n, nsIID *result ) = 0;
}; // mozIClassRegistryEntry
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define MOZ_ICLASSREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define MOZ_ICLASSREGISTRYENTRY_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
#endif

View File

@@ -0,0 +1,326 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef __mozIRegistry_h
#define __mozIRegistry_h
#include "nsISupports.h"
class nsIEnumerator;
/*------------------------------- mozIRegistry ---------------------------------
| This interface provides access to a tree of arbitrary values. |
| |
| Each node of the tree contains either a value or a subtree or both. |
| |
| The value at any of these leaf nodes can be any of these "primitive" types: |
| o string (null terminated UTF string) |
| o array of 32-bit integers |
| o arbitrary array of bytes |
| o file identifier |
| Of course, since you can store an arbitrary array of bytes, you can put |
| any data you like into a registry (although you have the burden of |
| encoding/decoding your data in that case). |
| |
| Each branch of the tree is labelled with a string "key." The entire path |
| from a given point of the tree to another point further down can be |
| presented as a single string composed of each branch's label, concatenated |
| to the next, with an intervening forward slash ('/'). The term "key" |
| refers to both specific tree branch labels and to such concatenated paths. |
| |
| The branches from a given node must have unique labels. Distinct nodes can |
| have branches with the same label. |
| |
| For example, here's a small registry tree: |
| | |
| /\ |
| / \ |
| / \ |
| / \ |
| "Classes" "Users" |
| / \ |
| / \ |
| / ["joe"] |
| / / \ |
| | / \ |
| /\ / \ |
| / \ "joe" "bob" |
| / \ / \ |
| / \ |
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
| | | |
| /\ /\ |
| / \ / \ |
| / \ / \ |
| "Library" "Version" "Library" "Version" |
| / \ / \ |
| ["foo.dll"] 2 ["bar.dll"] 1 |
| |
| In this example, there are 2 keys under the root: "Classes" and "Users". |
| The first denotes a subtree only (which has two subtrees, ...). The second |
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
| |
| The registry interface provides functions that let you navigate the tree |
| and manipulate it's contents. |
| |
| Please note that the registry itself does not impose any structure or |
| meaning on the contents of the tree. For example, the registry doesn't |
| control whether the value at the key "/Users" is the label for the subtree |
| with information about the last active user. That meaning is applied by |
| the code that stores these values and uses them for that purpose. |
| |
| [Any resemblence between this example and actual contents of any actual |
| registry is purely coincidental.] |
------------------------------------------------------------------------------*/
struct mozIRegistry : public nsISupports {
/*------------------------------ Constants ---------------------------------
| The following enumerated types and values are used by the registry |
| interface. |
--------------------------------------------------------------------------*/
typedef enum {
String = 1,
Int32,
Bytes,
File
} DataType;
/*-------------------------------- Types -----------------------------------
| The following data types are used by this interface. All are basically |
| opaque types. You obtain objects of these types via certain member |
| function calls and re-use them later (without having to know what they |
| contain). |
| |
| Key - Placeholder to represent a particular node in a registry |
| tree. There are 3 enumerated values that correspond to |
| specific nodes: |
| Common - Where most stuff goes. |
| Users - Special subtree to hold info about |
| "users"; if you don't know what goes |
| here, don't mess with it. |
| CurrentUser - Subtree under Users corresponding to |
| whatever user is designed the "current" |
| one; see note above. |
| You can specify any of these enumerated values as "keys" |
| on any member function that takes a mozRegistry::Key. |
| ValueInfo - Structure describing a registry value. |
--------------------------------------------------------------------------*/
typedef uint32 Key;
enum { Users = 1, Common = 2, CurrentUser = 3 };
struct ValueInfo {
DataType type;
uint32 length;
};
/*--------------------------- Opening/Closing ------------------------------
| These functions open the specified registry file (Open() with a non-null |
| argument) or the default "standard" registry file (Open() with a null |
| argument or OpenDefault()). |
| |
| Once opened, you can access the registry contents via the read/write |
| or query functions. |
| |
| The registry file will be closed automatically when the registry object |
| is destroyed. You can close the file prior to that by using the |
| Close() function. |
--------------------------------------------------------------------------*/
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
NS_IMETHOD OpenDefault() = 0;
NS_IMETHOD Close() = 0;
/*----------------------- Reading/Writing Values ---------------------------
| These functions read/write the registry values at a given node. |
| |
| All functions require you to specify where in the registry key to |
| get/set the value. The location is specified using two components: |
| o A "base key" indicating where to start from; this is a value of type |
| mozIRegistry::Key. You use either one of the special "root" key |
| values or a subkey obtained via some other member function call. |
| o A "relative path," expressed as a sequence of subtree names |
| separated by forward slashes. This path describes how to get from |
| the base key to the node at which you want to store the data. This |
| component can be a null pointer which means the value goes directly |
| at the node denoted by the base key. |
| |
| When you request a value of a given type, the data stored at the |
| specified node must be of the type requested. If not, an error results. |
| |
| GetString - Obtains a newly allocated copy of a string type value. The |
| caller is obligated to free the returned string using |
| PR_Free. |
| SetString - Stores the argument string at the specified node. |
| GetInt - Obtains an int32 value at the specified node. The result |
| is returned into an int32 location you specify. |
| SetInt - Stores a given int32 value at a node. |
| GetBytes - Obtains a byte array value; this returns both an allocated |
| array of bytes and a length (necessary because there may be |
| embedded null bytes in the array). You must free the |
| resulting array using PR_Free. |
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
| pointer and a length. |
| GetIntArray - Obtains the array of int32 values stored at a given node. |
| The result is composed of two values: a pointer to an |
| array of integer values (which must be freed using |
| PR_Free) and the number of elements in that array. |
| SetIntArray - Stores a set of int32 values at a given node. You must |
| provide a pointer to the array and the number of entries. |
--------------------------------------------------------------------------*/
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
/*------------------------------ Navigation --------------------------------
| These functions let you navigate through the registry tree, querying |
| its contents. |
| |
| As above, all these functions requires a starting tree location ("base |
| key") specified as a mozIRegistry::Key. Some also require a path |
| name to locate the registry node location relative to this base key. |
| |
| AddSubtree - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| RemoveNode - Removes the specified registry subtree or |
| value at the specified location. |
| GetSubtree - Returns a mozIRegistry::Key that can be used |
| to refer to the specified registry location. |
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
| use to enumerate all the subtrees descending |
| from a specified location. You must free the |
| enumerator via Release() when you're done with |
| it. |
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
| enumerate lower-level subtrees, too. |
| GetValueInfo - Returns a uint32 value that designates the type |
| of data stored at this location in the registry; |
| the possible values are defined by the enumerated |
| type mozIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
| EnumerateValues - Returns a nsIEnumerator that you can use to |
| enumerate all the value nodes descending from |
| a specified location. |
--------------------------------------------------------------------------*/
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
/*------------------------------ User Name ---------------------------------
| These functions manipulate the current "user name." This value controls |
| the behavior of certain registry functions (namely, ?). |
| |
| GetCurrentUserName allocates a copy of the current user name (which the |
| caller should free using PR_Free). |
--------------------------------------------------------------------------*/
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
/*------------------------------ Utilities ---------------------------------
| Various utility functions: |
| |
| Pack() is used to compress the contents of an open registry file. |
--------------------------------------------------------------------------*/
NS_IMETHOD Pack() = 0;
}; // mozIRegistry
/*----------------------------- mozIRegistryNode -------------------------------
| This interface is implemented by all the objects obtained from the |
| nsIEnumerators that mozIRegistry provides when you call either of the |
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
| |
| You can call this function to get the name of this subtree. This is the |
| relative path from the base key from which you got this interface. |
| |
| GetName - Returns the path name of this node; this is the relative path |
| from the base key from which this subtree was obtained. The |
| function allocates a copy of the name; the caller must free it |
| using PR_Free. |
------------------------------------------------------------------------------*/
struct mozIRegistryNode : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
}; // mozIRegistryNode
/*----------------------------- mozIRegistryValue ------------------------------
| This interface is implemented by the objects obtained from the |
| nsIEnumerators that mozIRegistry provides when you call the |
| EnumerateValues function. An object supporting this interface is |
| returned when you call the CurrentItem() function on that enumerator. |
| |
| You use the member functions of this interface to obtain information |
| about each registry value. |
| |
| GetName - Returns the path name of this node; this is the relative |
| path\ from the base key from which this value was obtained. |
| The function allocates a copy of the name; the caller must |
| subsequently free it via PR_Free. |
| GetValueType - Returns (into a location provided by the caller) the type |
| of the value; the types are defined by the enumerated |
| type mozIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
------------------------------------------------------------------------------*/
struct mozIRegistryValue : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
NS_IMETHOD GetValueType( uint32 *result ) = 0;
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
}; // mozIRegistryEntry
/*------------------------------- Error Codes ----------------------------------
------------------------------------------------------------------------------*/
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define MOZ_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define MOZ_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
#define MOZ_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef __nsIFactory_h
#define __nsIFactory_h
#include "prtypes.h"
#include "nsISupports.h"
/*
* Datatypes and helper macros
*/
typedef nsID nsCID;
// Define an CID
#define NS_DEFINE_CID(_name, _cidspec) \
const nsCID _name = _cidspec
#define REFNSCID const nsCID&
/*
* nsIFactory interface
*/
// {00000001-0000-0000-c000-000000000046}
#define NS_IFACTORY_IID \
{ 0x00000001, 0x0000, 0x0000, \
{ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }
class nsIFactory: public nsISupports {
public:
static const nsIID& IID() { static nsIID iid = NS_IFACTORY_IID; return iid; }
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult) = 0;
NS_IMETHOD LockFactory(PRBool aLock) = 0;
};
#if 0
/* Excluding IFactory2 until there is proof of its use - dp */
/**
* nsIFactory2 allows passing in a signature token when creating an
* instance. This allows instance recycling.
*/
// {19997C41-A343-11d1-B665-00805F8A2676}
#define NS_IFACTORY2_IID \
{ 0x19997c41, 0xa343, 0x11d1, \
{ 0xb6, 0x65, 0x0, 0x80, 0x5f, 0x8a, 0x26, 0x76 } }
class nsIFactory2: public nsIFactory {
public:
static const nsIID& IID() { static nsIID iid = NS_IFACTORY2_IID; return iid; }
NS_IMETHOD CreateInstance2(nsISupports *aOuter,
REFNSIID aIID,
void *aSignature,
void **aResult) = 0;
};
#endif /* 0 */
#endif

View File

@@ -0,0 +1,326 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef __nsIRegistry_h
#define __nsIRegistry_h
#include "nsISupports.h"
class nsIEnumerator;
/*-------------------------------- nsIRegistry ---------------------------------
| This interface provides access to a tree of arbitrary values. |
| |
| Each node of the tree contains either a value or a subtree or both. |
| |
| The value at any of these leaf nodes can be any of these "primitive" types: |
| o string (null terminated UTF string) |
| o array of 32-bit integers |
| o arbitrary array of bytes |
| o file identifier |
| Of course, since you can store an arbitrary array of bytes, you can put |
| any data you like into a registry (although you have the burden of |
| encoding/decoding your data in that case). |
| |
| Each branch of the tree is labelled with a string "key." The entire path |
| from a given point of the tree to another point further down can be |
| presented as a single string composed of each branch's label, concatenated |
| to the next, with an intervening forward slash ('/'). The term "key" |
| refers to both specific tree branch labels and to such concatenated paths. |
| |
| The branches from a given node must have unique labels. Distinct nodes can |
| have branches with the same label. |
| |
| For example, here's a small registry tree: |
| | |
| /\ |
| / \ |
| / \ |
| / \ |
| "Classes" "Users" |
| / \ |
| / \ |
| / ["joe"] |
| / / \ |
| | / \ |
| /\ / \ |
| / \ "joe" "bob" |
| / \ / \ |
| / \ |
| "{xxxx-xx-1}" "{xxxx-xx-2}" ["c:/joe"] ["d:/Robert"] |
| | | |
| /\ /\ |
| / \ / \ |
| / \ / \ |
| "Library" "Version" "Library" "Version" |
| / \ / \ |
| ["foo.dll"] 2 ["bar.dll"] 1 |
| |
| In this example, there are 2 keys under the root: "Classes" and "Users". |
| The first denotes a subtree only (which has two subtrees, ...). The second |
| denotes both a value ["joe"] and two subtrees labelled "joe" and "bob". |
| The value at the node "/Users" is ["joe"], at "/Users/bob" is ["d:/Robert"]. |
| The value at "/Classes/{xxxx-xx-1}/Version" is 2. |
| |
| The registry interface provides functions that let you navigate the tree |
| and manipulate it's contents. |
| |
| Please note that the registry itself does not impose any structure or |
| meaning on the contents of the tree. For example, the registry doesn't |
| control whether the value at the key "/Users" is the label for the subtree |
| with information about the last active user. That meaning is applied by |
| the code that stores these values and uses them for that purpose. |
| |
| [Any resemblence between this example and actual contents of any actual |
| registry is purely coincidental.] |
------------------------------------------------------------------------------*/
struct nsIRegistry : public nsISupports {
/*------------------------------ Constants ---------------------------------
| The following enumerated types and values are used by the registry |
| interface. |
--------------------------------------------------------------------------*/
typedef enum {
String = 1,
Int32,
Bytes,
File
} DataType;
/*-------------------------------- Types -----------------------------------
| The following data types are used by this interface. All are basically |
| opaque types. You obtain objects of these types via certain member |
| function calls and re-use them later (without having to know what they |
| contain). |
| |
| Key - Placeholder to represent a particular node in a registry |
| tree. There are 3 enumerated values that correspond to |
| specific nodes: |
| Common - Where most stuff goes. |
| Users - Special subtree to hold info about |
| "users"; if you don't know what goes |
| here, don't mess with it. |
| CurrentUser - Subtree under Users corresponding to |
| whatever user is designed the "current" |
| one; see note above. |
| You can specify any of these enumerated values as "keys" |
| on any member function that takes a nsRegistry::Key. |
| ValueInfo - Structure describing a registry value. |
--------------------------------------------------------------------------*/
typedef uint32 Key;
enum { Users = 1, Common = 2, CurrentUser = 3 };
struct ValueInfo {
DataType type;
uint32 length;
};
/*--------------------------- Opening/Closing ------------------------------
| These functions open the specified registry file (Open() with a non-null |
| argument) or the default "standard" registry file (Open() with a null |
| argument or OpenDefault()). |
| |
| Once opened, you can access the registry contents via the read/write |
| or query functions. |
| |
| The registry file will be closed automatically when the registry object |
| is destroyed. You can close the file prior to that by using the |
| Close() function. |
--------------------------------------------------------------------------*/
NS_IMETHOD Open( const char *regFile = 0 ) = 0;
NS_IMETHOD OpenDefault() = 0;
NS_IMETHOD Close() = 0;
/*----------------------- Reading/Writing Values ---------------------------
| These functions read/write the registry values at a given node. |
| |
| All functions require you to specify where in the registry key to |
| get/set the value. The location is specified using two components: |
| o A "base key" indicating where to start from; this is a value of type |
| nsIRegistry::Key. You use either one of the special "root" key |
| values or a subkey obtained via some other member function call. |
| o A "relative path," expressed as a sequence of subtree names |
| separated by forward slashes. This path describes how to get from |
| the base key to the node at which you want to store the data. This |
| component can be a null pointer which means the value goes directly |
| at the node denoted by the base key. |
| |
| When you request a value of a given type, the data stored at the |
| specified node must be of the type requested. If not, an error results. |
| |
| GetString - Obtains a newly allocated copy of a string type value. The |
| caller is obligated to free the returned string using |
| PR_Free. |
| SetString - Stores the argument string at the specified node. |
| GetInt - Obtains an int32 value at the specified node. The result |
| is returned into an int32 location you specify. |
| SetInt - Stores a given int32 value at a node. |
| GetBytes - Obtains a byte array value; this returns both an allocated |
| array of bytes and a length (necessary because there may be |
| embedded null bytes in the array). You must free the |
| resulting array using PR_Free. |
| SetBytes - Stores a given array of bytes; you specify the bytes via a |
| pointer and a length. |
| GetIntArray - Obtains the array of int32 values stored at a given node. |
| The result is composed of two values: a pointer to an |
| array of integer values (which must be freed using |
| PR_Free) and the number of elements in that array. |
| SetIntArray - Stores a set of int32 values at a given node. You must |
| provide a pointer to the array and the number of entries. |
--------------------------------------------------------------------------*/
NS_IMETHOD GetString( Key baseKey, const char *path, char **result ) = 0;
NS_IMETHOD SetString( Key baseKey, const char *path, const char *value ) = 0;
NS_IMETHOD GetInt( Key baseKey, const char *path, int32 *result ) = 0;
NS_IMETHOD SetInt( Key baseKey, const char *path, int32 value ) = 0;
NS_IMETHOD GetBytes( Key baseKey, const char *path, void **result, uint32 *len ) = 0;
NS_IMETHOD SetBytes( Key baseKey, const char *path, void *value, uint32 len ) = 0;
NS_IMETHOD GetIntArray( Key baseKey, const char *path, int32 **result, uint32 *len ) = 0;
NS_IMETHOD SetIntArray( Key baseKey, const char *path, const int32 *value, uint32 len ) = 0;
/*------------------------------ Navigation --------------------------------
| These functions let you navigate through the registry tree, querying |
| its contents. |
| |
| As above, all these functions requires a starting tree location ("base |
| key") specified as a nsIRegistry::Key. Some also require a path |
| name to locate the registry node location relative to this base key. |
| |
| AddSubtree - Adds a new registry subtree at the specified |
| location. Returns the resulting key in |
| the location specified by the third argument |
| (unless that pointer is 0). |
| RemoveNode - Removes the specified registry subtree or |
| value at the specified location. |
| GetSubtree - Returns a nsIRegistry::Key that can be used |
| to refer to the specified registry location. |
| EnumerateSubtrees - Returns a nsIEnumerator object that you can |
| use to enumerate all the subtrees descending |
| from a specified location. You must free the |
| enumerator via Release() when you're done with |
| it. |
| EnumerateAllSubtrees - Like EnumerateSubtrees, but will recursively |
| enumerate lower-level subtrees, too. |
| GetValueInfo - Returns a uint32 value that designates the type |
| of data stored at this location in the registry; |
| the possible values are defined by the enumerated |
| type nsIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
| EnumerateValues - Returns a nsIEnumerator that you can use to |
| enumerate all the value nodes descending from |
| a specified location. |
--------------------------------------------------------------------------*/
NS_IMETHOD AddSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD RemoveSubtree( Key baseKey, const char *path ) = 0;
NS_IMETHOD GetSubtree( Key baseKey, const char *path, Key *result ) = 0;
NS_IMETHOD EnumerateSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD EnumerateAllSubtrees( Key baseKey, nsIEnumerator **result ) = 0;
NS_IMETHOD GetValueType( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD GetValueLength( Key baseKey, const char *path, uint32 *result ) = 0;
NS_IMETHOD EnumerateValues( Key baseKey, nsIEnumerator **result ) = 0;
/*------------------------------ User Name ---------------------------------
| These functions manipulate the current "user name." This value controls |
| the behavior of certain registry functions (namely, ?). |
| |
| GetCurrentUserName allocates a copy of the current user name (which the |
| caller should free using PR_Free). |
--------------------------------------------------------------------------*/
NS_IMETHOD GetCurrentUserName( char **result ) = 0;
NS_IMETHOD SetCurrentUserName( const char *name ) = 0;
/*------------------------------ Utilities ---------------------------------
| Various utility functions: |
| |
| Pack() is used to compress the contents of an open registry file. |
--------------------------------------------------------------------------*/
NS_IMETHOD Pack() = 0;
}; // nsIRegistry
/*------------------------------ nsIRegistryNode -------------------------------
| This interface is implemented by all the objects obtained from the |
| nsIEnumerators that nsIRegistry provides when you call either of the |
| subtree enumeration functions EnumerateSubtrees or EnumerateAllSubtrees. |
| |
| You can call this function to get the name of this subtree. This is the |
| relative path from the base key from which you got this interface. |
| |
| GetName - Returns the path name of this node; this is the relative path |
| from the base key from which this subtree was obtained. The |
| function allocates a copy of the name; the caller must free it |
| using PR_Free. |
------------------------------------------------------------------------------*/
struct nsIRegistryNode : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
}; // nsIRegistryNode
/*------------------------------ nsIRegistryValue ------------------------------
| This interface is implemented by the objects obtained from the |
| nsIEnumerators that nsIRegistry provides when you call the |
| EnumerateValues function. An object supporting this interface is |
| returned when you call the CurrentItem() function on that enumerator. |
| |
| You use the member functions of this interface to obtain information |
| about each registry value. |
| |
| GetName - Returns the path name of this node; this is the relative |
| path\ from the base key from which this value was obtained. |
| The function allocates a copy of the name; the caller must |
| subsequently free it via PR_Free. |
| GetValueType - Returns (into a location provided by the caller) the type |
| of the value; the types are defined by the enumerated |
| type nsIRegistry::DataType. |
| GetValueLength - Returns a uint32 value that indicates the length |
| of this registry value; the length is the number |
| of characters (for Strings), the number of bytes |
| (for Bytes), or the number of int32 values (for |
| Int32). |
------------------------------------------------------------------------------*/
struct nsIRegistryValue : public nsISupports {
NS_IMETHOD GetName( char **result ) = 0;
NS_IMETHOD GetValueType( uint32 *result ) = 0;
NS_IMETHOD GetValueLength( uint32 *result ) = 0;
}; // nsIRegistryEntry
/*------------------------------- Error Codes ----------------------------------
------------------------------------------------------------------------------*/
#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define NS_IREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define NS_IREGISTRYNODE_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {5316C380-B2F8-11d2-A374-0080C6F80E4B}
#define NS_IREGISTRYVALUE_IID { 0x5316c380, 0xb2f8, 0x11d2, { 0xa3, 0x74, 0x0, 0x80, 0xc6, 0xf8, 0xe, 0x4b } }
#endif

View File

@@ -0,0 +1,148 @@
/* -*- Mode: C++; tab-width: 2; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIServiceManager_h___
#define nsIServiceManager_h___
#include "nsRepository.h"
class nsIShutdownListener;
/**
* The nsIServiceManager manager interface provides a means to obtain
* global services in an application. The service manager depends on the
* repository to find and instantiate factories to obtain services.
*
* Users of the service manager must first obtain a pointer to the global
* service manager by calling NS_GetGlobalServiceManager. After that,
* they can request specific services by calling GetService. When they are
* finished with a service the release it by calling ReleaseService (instead
* of releasing the service object directly):
*
* nsICacheManager* cm;
* nsServiceManager::GetService(kCacheManagerCID, kICacheManagerIID, (nsISupports**)&cm);
*
* ... use cm, and then sometime later ...
*
* nsServiceManager::ReleaseService(kCacheManagerCID, cm);
*
* A user of a service may keep references to particular services indefinitely
* and only must call ReleaseService when it shuts down. However if the user
* wishes to voluntarily cooperate with the shutdown of the service it is
* using, it may supply an nsIShutdownListener to provide for asynchronous
* release of the services it is using. The shutdown listener's OnShutdown
* method will be called for a service that is being shut down, and it is
* its responsiblity to release references obtained from that service if at
* all possible.
*
* The process of shutting down a particular service is initiated by calling
* the service manager's ShutdownService method. This will iterate through
* all the registered shutdown listeners for the service being shut down, and
* then will attempt to unload the library associated with the service if
* possible. The status result of ShutdownService indicates whether the
* service was successfully shut down, failed, or was not in service.
*
* XXX QUESTIONS:
* - Should a "service" be more than nsISupports? Should it be a factory
* and/or have Startup(), Shutdown(), etc.
* - If the asynchronous OnShutdown operation gets called, does the user
* of a service still need to call ReleaseService? (Or should they _not_
* call it?)
*/
class nsIServiceManager : public nsISupports {
public:
NS_IMETHOD
GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL) = 0;
NS_IMETHOD
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL) = 0;
/**
* Requests a service to be shut down, possibly unloading its DLL.
*
* @returns NS_OK - if shutdown was successful and service was unloaded,
* @returns NS_ERROR_SERVICE_NOT_FOUND - if shutdown failed because
* the service was not currently loaded
* @returns NS_ERROR_SERVICE_IN_USE - if shutdown failed because some
* user of the service wouldn't voluntarily release it by using
* a shutdown listener.
*/
NS_IMETHOD
ShutdownService(const nsCID& aClass) = 0;
};
#define NS_ISERVICEMANAGER_IID \
{ /* cf0df3b0-3401-11d2-8163-006008119d7a */ \
0xcf0df3b0, \
0x3401, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
#define NS_ERROR_SERVICE_NOT_FOUND NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 22)
#define NS_ERROR_SERVICE_IN_USE NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 23)
////////////////////////////////////////////////////////////////////////////////
class nsIShutdownListener : public nsISupports {
public:
NS_IMETHOD
OnShutdown(const nsCID& aClass, nsISupports* service) = 0;
};
#define NS_ISHUTDOWNLISTENER_IID \
{ /* 56decae0-3406-11d2-8163-006008119d7a */ \
0x56decae0, \
0x3406, \
0x11d2, \
{0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
}
////////////////////////////////////////////////////////////////////////////////
// Interface to Global Services
class NS_COM nsServiceManager {
public:
static nsresult GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
static nsresult ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
static nsresult ShutdownService(const nsCID& aClass);
// Since the global Service Manager is truly global, there's no need to
// release it.
static nsresult GetGlobalServiceManager(nsIServiceManager* *result);
protected:
static nsIServiceManager* globalServiceManager;
};
////////////////////////////////////////////////////////////////////////////////
#endif /* nsIServiceManager_h___ */

View File

@@ -0,0 +1,31 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef __nsIServerProvider_h
#define __nsIServerProvider_h
#include "nsISupports.h"
typedef nsID nsSID;
#define NSSIDREF const nsSID&
class nsIServiceProvider: public nsISupports {
public:
NS_IMETHOD QueryService(NSSIDREF aSID, NSIIDREF sIID, (void **) pService);
};
#endif /* __nsIServerProvider_h */

View File

@@ -0,0 +1,118 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifdef XP_MAC
#ifdef MOZ_NGLAYOUT
#error "nsMacRepository.h became obsolete when the shared lib conversion was completed."
// The Mac NGLayout is not based on shared libraries yet.
// All the DLLs are built as static libraries and we present them as
// shared libraries by redefining PR_LoadLibrary(), PR_UnloadLibrary()
// and PR_FindSymbol() below.
//
// If you add or remove shared libraries on other platforms, you must
// - Add the library name to the defines below.
// - Rename the "NSGetFactory" and "NSCanUnload" procs for the Mac:
// just append the library name to the function name.
// - Add the library and its procs to the static list below.
typedef struct MacLibrary
{
char * name;
nsFactoryProc factoryProc;
nsCanUnloadProc unloadProc;
} MacLibrary;
// library names
#define WIDGET_DLL "WIDGET_DLL"
#define GFXWIN_DLL "GFXWIN_DLL"
#define VIEW_DLL "VIEW_DLL"
#define WEB_DLL "WEB_DLL"
#define PLUGIN_DLL "PLUGIN_DLL"
#define PREF_DLL "PREF_DLL"
#define PARSER_DLL "PARSER_DLL"
#define DOM_DLL "DOM_DLL"
#define LAYOUT_DLL "LAYOUT_DLL"
#define NETLIB_DLL "NETLIB_DLL"
#define EDITOR_DLL "EDITOR_DLL"
#ifdef IMPL_MAC_REPOSITORY
extern "C" nsresult NSGetFactory_WIDGET_DLL(const nsCID &, nsISupports* , nsIFactory ** );
extern "C" nsresult NSGetFactory_GFXWIN_DLL(const nsCID &, nsISupports*, nsIFactory ** );
extern "C" nsresult NSGetFactory_VIEW_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" nsresult NSGetFactory_WEB_DLL(const nsCID &, nsISupports*, nsIFactory **);
//extern "C" nsresult NSGetFactory_PLUGIN_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" nsresult NSGetFactory_PREF_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" nsresult NSGetFactory_PARSER_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" nsresult NSGetFactory_DOM_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" nsresult NSGetFactory_LAYOUT_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" nsresult NSGetFactory_NETLIB_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" nsresult NSGetFactory_EDITOR_DLL(const nsCID &, nsISupports*, nsIFactory **);
extern "C" PRBool NSCanUnload_PREF_DLL(void);
// library list
static MacLibrary libraries[] = {
#if 0
WIDGET_DLL, NSGetFactory_WIDGET_DLL, NULL,
GFXWIN_DLL, NSGetFactory_GFXWIN_DLL, NULL,
VIEW_DLL, NSGetFactory_VIEW_DLL, NULL,
WEB_DLL, NSGetFactory_WEB_DLL, NULL,
//PLUGIN_DLL, NSGetFactory_PLUGIN_DLL, NULL,
PREF_DLL, NSGetFactory_PREF_DLL, NSCanUnload_PREF_DLL,
PARSER_DLL, NSGetFactory_PARSER_DLL, NULL,
DOM_DLL, NSGetFactory_DOM_DLL, NULL,
LAYOUT_DLL, NSGetFactory_LAYOUT_DLL, NULL,
NETLIB_DLL, NSGetFactory_NETLIB_DLL, NULL,
//EDITOR_DLL, NSGetFactory_EDITOR_DLL, NULL, // FIX ME
#endif
NULL
};
static void* FindMacSymbol(char* libName, const char *symbolName)
{
MacLibrary * macLib;
for (macLib = libraries; ; macLib ++)
{
if (macLib->name == NULL)
return NULL;
if (PL_strcmp(macLib->name, libName) == 0)
break;
}
if (PL_strcmp(symbolName, "NSGetFactory") == 0) {
return macLib->factoryProc;
}
else if (PL_strcmp(symbolName, "NSCanUnload") == 0) {
return macLib->unloadProc;
}
return NULL;
}
#define PR_LoadLibrary(libName) (PRLibrary *)libName
#define PR_UnloadLibrary(lib) lib = NULL
#define PR_FindSymbol(lib, symbolName) FindMacSymbol((char*)lib, symbolName)
#endif // IMPL_MAC_REPOSITORY
#endif // MOZ_NGLAYOUT
#endif // XP_MAC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,213 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef __nsRespository_h
#define __nsRespository_h
#include "prtypes.h"
#include "prlog.h"
#include "prmon.h"
#include "nsCom.h"
#include "nsID.h"
#include "nsError.h"
#include "nsISupports.h"
#include "nsIFactory.h"
#include "nsHashtable.h"
/*
* Prototypes for dynamic library export functions
*/
class nsIServiceManager;
//***********************************************************
//
// NSGetFactory should take nsISupports instead of nsIServiceManager
// as the second param. This is done on purpose!! Please don't change
// it.
// sudu / stanley
//
//***********************************************************
extern "C" NS_EXPORT nsresult NSGetFactory(const nsCID &aClass,
nsISupports* serviceMgr,
nsIFactory **aFactory);
extern "C" NS_EXPORT PRBool NSCanUnload();
extern "C" NS_EXPORT nsresult NSRegisterSelf(const char *fullpath);
extern "C" NS_EXPORT nsresult NSUnregisterSelf(const char *fullpath);
/* Quick Registration
*
* For quick registration, dlls can define
* NSQuickRegisterClassData g_NSQuickRegisterData[];
* and export the symbol "g_NSQuickRegisterData"
*
* Quick registration is tried only if the symbol "NSRegisterSelf"
* is not found. If it is found but fails registration, quick registration
* will not kick in.
*
* The array is terminated by having a NULL last element. Specifically, the
* array will be assumed to end when
* (g_NSQuickRegisterData[i].classIdStr == NULL)
*
*/
#define NS_QUICKREGISTER_DATA_SYMBOL "g_NSQuickRegisterData"
typedef struct NSQuickRegisterClassData {
const char *CIDString; // {98765-8776-8958758759-958785}
const char *className; // "Layout Engine"
const char *progID; // "Gecko.LayoutEngine.1"
} NSQuickRegisterClassData;
typedef NSQuickRegisterClassData* NSQuickRegisterData;
/* Autoregistration will try only files with these extensions.
* All extensions are case insensitive.
".dll", // Windows
".dso", // Unix
".so", // Unix
".sl", // Unix: HP
"_dll", // Mac
".dlm", // new for all platforms
*/
/*
* Dynamic library export function types
*/
typedef nsresult (*nsFactoryProc)(const nsCID &aCLass,
nsISupports* serviceMgr,
nsIFactory **aFactory);
typedef PRBool (*nsCanUnloadProc)(void);
typedef nsresult (*nsRegisterProc)(const char *path);
typedef nsresult (*nsUnregisterProc)(const char *path);
/*
* Support types
*/
class FactoryEntry;
class nsDllStore;
class nsDll;
enum NSRegistrationInstant
{
NS_Startup = 0,
NS_Script = 1,
NS_Timer = 2
};
/* Error codes generated by the repository methods */
#define NS_XPCOM_ERRORCODE_IS_DIR 1
/* The separator for each path part in the pathlist for autoregistration */
#define NS_PATH_SEPARATOR ';'
/*
* nsRepository class
*/
class NS_COM nsRepository {
private:
#define NS_MAX_FILENAME_LEN 1024
static nsHashtable *factories;
static PRMonitor *monitor;
static nsresult checkInitialized(void);
static nsresult loadFactory(FactoryEntry *aEntry, nsIFactory **aFactory);
static nsresult SelfRegisterDll(nsDll *dll);
static nsresult SelfUnregisterDll(nsDll *dll);
public:
static nsDllStore *dllStore;
static nsresult Initialize(void);
// Finds a factory for a specific class ID
static nsresult FindFactory(const nsCID &aClass,
nsIFactory **aFactory);
// Finds a class ID for a specific Program ID
static nsresult ProgIDToCLSID(const char *aProgID,
nsCID *aClass);
// Creates a class instance for a specific class ID
static nsresult CreateInstance(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void **aResult);
// Creates a class instance for a specific class ID
/*
static nsresult CreateInstance2(const nsCID &aClass,
nsISupports *aDelegate,
const nsIID &aIID,
void *aSignature,
void **aResult);
*/
// Manually registry a factory for a class
static nsresult RegisterFactory(const nsCID &aClass,
nsIFactory *aFactory,
PRBool aReplace);
// Manually registry a dynamically loaded factory for a class
static nsresult RegisterFactory(const nsCID &aClass,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist);
// Manually register a dynamically loaded component.
static nsresult RegisterComponent(const nsCID &aClass,
const char *aClassName,
const char *aProgID,
const char *aLibrary,
PRBool aReplace,
PRBool aPersist);
// Manually unregister a factory for a class
static nsresult UnregisterFactory(const nsCID &aClass,
nsIFactory *aFactory);
// Manually unregister a dynamically loaded factory for a class
static nsresult UnregisterFactory(const nsCID &aClass,
const char *aLibrary);
// Manually unregister a dynamically loaded component
static nsresult UnregisterComponent(const nsCID &aClass,
const char *aLibrary);
// Unload dynamically loaded factories that are not in use
static nsresult FreeLibraries(void);
// DLL registration support
static nsresult AutoRegister(NSRegistrationInstant when,
const char* pathlist);
// Pathlist is a semicolon separated list of pathnames
static nsresult AddToDefaultPathList(const char *pathlist);
static nsresult SyncComponentsInPathList(const char *pathlist);
static nsresult SyncComponentsInDir(const char *path);
static nsresult SyncComponentsInFile(const char *fullname);
};
#endif

View File

@@ -0,0 +1,350 @@
/* -*- Mode: C++; tab-width: 2; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIServiceManager.h"
#include "nsVector.h"
#include "prcmon.h"
#include "prthread.h" /* XXX: only used for the NSPR initialization hack (rick) */
class nsServiceEntry {
public:
nsServiceEntry(const nsCID& cid, nsISupports* service);
~nsServiceEntry();
nsresult AddListener(nsIShutdownListener* listener);
nsresult RemoveListener(nsIShutdownListener* listener);
nsresult NotifyListeners(void);
const nsCID& mClassID;
nsISupports* mService;
nsVector* mListeners; // nsVector<nsIShutdownListener>
PRBool mShuttingDown;
};
nsServiceEntry::nsServiceEntry(const nsCID& cid, nsISupports* service)
: mClassID(cid), mService(service), mListeners(NULL), mShuttingDown(PR_FALSE)
{
}
nsServiceEntry::~nsServiceEntry()
{
if (mListeners) {
NS_ASSERTION(mListeners->GetSize() == 0, "listeners not removed or notified");
#if 0
PRUint32 size = mListeners->GetSize();
for (PRUint32 i = 0; i < size; i++) {
nsIShutdownListener* listener = (nsIShutdownListener*)(*mListeners)[i];
listener->Release();
}
#endif
delete mListeners;
}
}
nsresult
nsServiceEntry::AddListener(nsIShutdownListener* listener)
{
if (listener == NULL)
return NS_OK;
if (mListeners == NULL) {
mListeners = new nsVector();
if (mListeners == NULL)
return NS_ERROR_OUT_OF_MEMORY;
}
PRInt32 err = mListeners->Add(listener);
listener->AddRef();
return err == -1 ? NS_ERROR_FAILURE : NS_OK;
}
nsresult
nsServiceEntry::RemoveListener(nsIShutdownListener* listener)
{
if (listener == NULL)
return NS_OK;
NS_ASSERTION(mListeners, "no listeners added yet");
PRUint32 size = mListeners->GetSize();
for (PRUint32 i = 0; i < size; i++) {
if ((*mListeners)[i] == listener) {
mListeners->Remove(i);
listener->Release();
return NS_OK;
}
}
NS_ASSERTION(0, "unregistered shutdown listener");
return NS_ERROR_FAILURE;
}
nsresult
nsServiceEntry::NotifyListeners(void)
{
if (mListeners) {
PRUint32 size = mListeners->GetSize();
for (PRUint32 i = 0; i < size; i++) {
nsIShutdownListener* listener = (nsIShutdownListener*)(*mListeners)[0];
nsresult err = listener->OnShutdown(mClassID, mService);
if (err) return err;
listener->Release();
mListeners->Remove(0);
}
NS_ASSERTION(mListeners->GetSize() == 0, "failed to notify all listeners");
delete mListeners;
mListeners = NULL;
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
class nsServiceManagerImpl : public nsIServiceManager {
public:
NS_IMETHOD
GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener = NULL);
NS_IMETHOD
ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener = NULL);
NS_IMETHOD
ShutdownService(const nsCID& aClass);
nsServiceManagerImpl(void);
NS_DECL_ISUPPORTS
protected:
virtual ~nsServiceManagerImpl(void);
nsHashtable* mServices; // nsHashtable<nsServiceEntry>
};
nsServiceManagerImpl::nsServiceManagerImpl(void)
{
NS_INIT_REFCNT();
mServices = new nsHashtable();
NS_ASSERTION(mServices, "out of memory already?");
}
static PRBool
DeleteEntry(nsHashKey *aKey, void *aData, void* closure)
{
nsServiceEntry* entry = (nsServiceEntry*)aData;
entry->mService->Release();
delete entry;
return PR_TRUE;
}
nsServiceManagerImpl::~nsServiceManagerImpl(void)
{
mServices->Enumerate(DeleteEntry);
delete mServices;
}
static NS_DEFINE_IID(kIServiceManagerIID, NS_ISERVICEMANAGER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
NS_IMPL_ADDREF(nsServiceManagerImpl);
NS_IMPL_RELEASE(nsServiceManagerImpl);
nsresult
nsServiceManagerImpl::QueryInterface(const nsIID& aIID, void* *aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
if (aIID.Equals(kIServiceManagerIID) ||
aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsresult
nsServiceManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener)
{
nsresult err = NS_OK;
/* XXX: This is a hack to force NSPR initialization.. This should be
* removed once PR_CEnterMonitor(...) initializes NSPR... (rick)
*/
(void)PR_GetCurrentThread();
PR_CEnterMonitor(this);
nsIDKey key(aClass);
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
if (entry) {
nsISupports* service;
err = entry->mService->QueryInterface(aIID, (void**)&service);
if (err == NS_OK) {
err = entry->AddListener(shutdownListener);
if (err == NS_OK) {
*result = service;
// If someone else requested the service to be shut down,
// and we just asked to get it again before it could be
// released, then cancel their shutdown request:
if (entry->mShuttingDown) {
entry->mShuttingDown = PR_FALSE;
service->AddRef(); // Released in ShutdownService
}
}
}
}
else {
nsISupports* service;
err = nsRepository::CreateInstance(aClass, NULL, aIID, (void**)&service);
if (err == NS_OK) {
entry = new nsServiceEntry(aClass, service);
if (entry == NULL) {
service->Release();
err = NS_ERROR_OUT_OF_MEMORY;
}
else {
err = entry->AddListener(shutdownListener);
if (err == NS_OK) {
mServices->Put(&key, entry);
*result = service;
service->AddRef(); // Released in ShutdownService
}
else {
service->Release();
delete entry;
}
}
}
}
PR_CExitMonitor(this);
return err;
}
nsresult
nsServiceManagerImpl::ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener)
{
nsresult err = NS_OK;
PR_CEnterMonitor(this);
nsIDKey key(aClass);
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
NS_ASSERTION(entry, "service not found");
NS_ASSERTION(entry->mService == service, "service looked failed");
if (entry) {
err = entry->RemoveListener(shutdownListener);
nsrefcnt cnt = service->Release();
if (err == NS_OK && cnt == 0) {
mServices->Remove(&key);
delete entry;
err = nsRepository::FreeLibraries();
}
}
PR_CExitMonitor(this);
return err;
}
nsresult
nsServiceManagerImpl::ShutdownService(const nsCID& aClass)
{
nsresult err = NS_OK;
PR_CEnterMonitor(this);
nsIDKey key(aClass);
nsServiceEntry* entry = (nsServiceEntry*)mServices->Get(&key);
if (entry == NULL) {
err = NS_ERROR_SERVICE_NOT_FOUND;
}
else {
err = entry->NotifyListeners(); // break the cycles
entry->mShuttingDown = PR_TRUE;
nsrefcnt cnt = entry->mService->Release(); // AddRef in GetService
if (err == NS_OK && cnt == 0) {
mServices->Remove(&key);
delete entry;
err = nsRepository::FreeLibraries();
}
else
err = NS_ERROR_SERVICE_IN_USE;
}
PR_CExitMonitor(this);
return err;
}
////////////////////////////////////////////////////////////////////////////////
// Global service manager interface (see nsIServiceManager.h)
nsIServiceManager* nsServiceManager::globalServiceManager = NULL;
nsresult
nsServiceManager::GetGlobalServiceManager(nsIServiceManager* *result)
{
if (globalServiceManager == NULL) {
globalServiceManager = new nsServiceManagerImpl();
if (globalServiceManager == NULL)
return NS_ERROR_OUT_OF_MEMORY;
globalServiceManager->AddRef();
}
*result = globalServiceManager;
return NS_OK;
}
nsresult
nsServiceManager::GetService(const nsCID& aClass, const nsIID& aIID,
nsISupports* *result,
nsIShutdownListener* shutdownListener)
{
nsIServiceManager* mgr;
nsresult rslt = GetGlobalServiceManager(&mgr);
if (rslt != NS_OK) return rslt;
return mgr->GetService(aClass, aIID, result, shutdownListener);
}
nsresult
nsServiceManager::ReleaseService(const nsCID& aClass, nsISupports* service,
nsIShutdownListener* shutdownListener)
{
nsIServiceManager* mgr;
nsresult rslt = GetGlobalServiceManager(&mgr);
if (rslt != NS_OK) return rslt;
return mgr->ReleaseService(aClass, service, shutdownListener);
}
nsresult
nsServiceManager::ShutdownService(const nsCID& aClass)
{
nsIServiceManager* mgr;
nsresult rslt = GetGlobalServiceManager(&mgr);
if (rslt != NS_OK) return rslt;
return mgr->ShutdownService(aClass);
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,153 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 nsXPComFactory_h__
#define nsXPComFactory_h__
#include "nsIFactory.h"
/*
* This file contains a templatized implementation of a simple XPCOM factory.
*
* To implement a factory for a given component, just provide a function
* like the one below which can be called by your DLL's NSGetFactory(...)
* entry point...
*
* nsresult NS_New_SomeComponent_Factory(nsIFactory** aResult)
* {
* nsresult rv = NS_OK;
* nsIFactory* inst = new nsFactory<SomeComponent>();
* if (NULL == inst) {
* rv = NS_ERROR_OUT_OF_MEMORY;
* } else {
* NS_ADDREF(inst);
* }
* *aResult = inst;
* return rv;
* }
*
* NOTE:
* ----
* The factories created by this template are not thread-safe and do not
* support aggregation.
*
*/
template <class T> class nsFactory : public nsIFactory
{
public:
nsFactory() { NS_INIT_REFCNT(); }
//
// nsISupports interface...
//
// These implementations were copied from the NS_IMPL_ISUPPORTS macro
// in nsISupports.h
//
NS_IMETHOD_(nsrefcnt) AddRef (void)
{
return ++mRefCnt;
}
NS_IMETHOD_(nsrefcnt) Release(void)
{
NS_PRECONDITION(0 != mRefCnt, "dup release");
if (--mRefCnt == 0) {
NS_DELETEXPCOM(this);
return 0;
}
return mRefCnt;
}
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtr = NULL;
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = (void*) this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*) ((nsISupports*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
//
// nsIFactory interface...
//
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult)
{
nsresult rv;
T* inst;
// Parameter validation...
if (NULL == aResult) {
rv = NS_ERROR_NULL_POINTER;
goto done;
}
// Do not support aggregatable components...
*aResult = NULL;
if (NULL != aOuter) {
rv = NS_ERROR_NO_AGGREGATION;
goto done;
}
// Create a new instance of the component...
NS_NEWXPCOM(inst, T);
if (NULL == inst) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto done;
}
// If the QI fails, the component will be destroyed...
NS_ADDREF(inst);
rv = inst->QueryInterface(aIID, aResult);
NS_RELEASE(inst);
done:
return rv;
}
NS_IMETHOD LockFactory(PRBool aLock)
{
// Not implemented in simplest case.
return NS_OK;
}
protected:
virtual ~nsFactory()
{
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
}
// Reference count variable used by nsISupports...
nsrefcnt mRefCnt;
};
#endif /* nsXPComFactory_h__ */

View File

@@ -0,0 +1,184 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
/* nsDll
*
* Abstraction of a Dll. Stores modifiedTime and size for easy detection of
* change in dll.
*
* dp Suresh <dp@netscape.com>
*/
#include "xcDll.h"
#include "plstr.h" // strdup and strfree
nsDll::nsDll(const char *libFullPath) : m_fullpath(NULL), m_instance(NULL),
m_status(DLL_OK)
{
m_lastModTime = LL_ZERO;
m_size = 0;
if (libFullPath == NULL)
{
m_status = DLL_INVALID_PARAM;
return;
}
m_fullpath = PL_strdup(libFullPath);
if (m_fullpath == NULL)
{
// No more memory
m_status = DLL_NO_MEM;
return;
}
PRFileInfo statinfo;
if (PR_GetFileInfo(m_fullpath, &statinfo) != PR_SUCCESS)
{
// The stat things works only if people pass in the full pathname.
// Even if our stat fails, we could be able to load it because of
// LD_LIBRARY_PATH and other such paths where dlls are searched for
// XXX we need a way of marking this occurance.
// XXX m_status = DLL_STAT_ERROR;
}
else
{
m_size = statinfo.size;
m_lastModTime = statinfo.modifyTime;
if (statinfo.type != PR_FILE_FILE)
{
// Not a file. Cant work with it.
m_status = DLL_NOT_FILE;
return;
}
}
m_status = DLL_OK;
}
nsDll::nsDll(const char *libFullPath, PRTime lastModTime, PRUint32 fileSize)
: m_fullpath(NULL), m_instance(NULL), m_status(DLL_OK)
{
m_lastModTime = lastModTime;
m_size = fileSize;
if (libFullPath == NULL)
{
m_status = DLL_INVALID_PARAM;
return;
}
m_fullpath = PL_strdup(libFullPath);
if (m_fullpath == NULL)
{
// No more memory
m_status = DLL_NO_MEM;
return;
}
m_status = DLL_OK;
}
nsDll::~nsDll(void)
{
if (m_instance != NULL)
Unload();
if (m_fullpath != NULL) PL_strfree(m_fullpath);
m_fullpath = NULL;
}
PRBool nsDll::Load(void)
{
// Of course, this is all buggy, because it uses paths instead of nsFileSpec.
// Also, instead of writing yet another converter for path separators, for
// pete's sake use the converters in nsFileSpec.h. Thank you.
#ifdef XP_MAC
char *macFileName = NULL;
int loop;
#endif
if (m_status != DLL_OK)
{
return (PR_FALSE);
}
if (m_instance != NULL)
{
// Already loaded
return (PR_TRUE);
}
#ifdef XP_MAC
// err = ConvertUnixPathToMacPath(m_fullpath, &macFileName);
if ((macFileName = PL_strdup(m_fullpath)) != NULL)
{
if (macFileName[0] == '/')
{
for (loop=0; loop<PL_strlen(macFileName); loop++)
{
if (macFileName[loop] == '/') macFileName[loop] = ':';
}
m_instance = PR_LoadLibrary(&macFileName[1]); // skip over initial slash
}
else
{
m_instance = PR_LoadLibrary(macFileName);
}
}
#else
#ifdef XP_UNIX
// On linux we seem to load multiple copies of the same dll but with different path
// like libraptorhtml.so and ./libraptorhtml.so
// Until this get fixed right, for now for ./libraptorhtml.so remove the "./"
if (m_fullpath[0] == '.' && m_fullpath[1] == '/')
m_instance = PR_LoadLibrary( &(m_fullpath[2]) );
else
#endif /* XP_UNIX */
{
// This is the only right way of doing this...
m_instance = PR_LoadLibrary(m_fullpath);
}
#endif /* XP_MAC */
return ((m_instance == NULL) ? PR_FALSE : PR_TRUE);
}
PRBool nsDll::Unload(void)
{
if (m_status != DLL_OK || m_instance == NULL)
return (PR_FALSE);
PRStatus ret = PR_UnloadLibrary(m_instance);
if (ret == PR_SUCCESS)
{
m_instance = NULL;
return (PR_TRUE);
}
else
return (PR_FALSE);
}
void * nsDll::FindSymbol(const char *symbol)
{
if (symbol == NULL)
return (NULL);
// If not already loaded, load it now.
if (Load() != PR_TRUE)
return (NULL);
return (PR_FindSymbol(m_instance, symbol));
}

View File

@@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
/* Dll
*
* Programmatic representation of a dll. Stores modifiedTime and size for
* easy detection of change in dll.
*
* dp Suresh <dp@netscape.com>
*/
#include "prio.h"
#include "prlink.h"
typedef enum nsDllStatus
{
DLL_OK = 0,
DLL_NO_MEM = 1,
DLL_STAT_ERROR = 2,
DLL_NOT_FILE = 3,
DLL_INVALID_PARAM = 4
} nsDllStatus;
class nsDll
{
private:
char *m_fullpath; // system format full filename of dll
PRTime m_lastModTime; // last modified time
PRUint32 m_size; // size of the dynamic library
PRLibrary *m_instance; // Load instance
nsDllStatus m_status; // holds current status
public:
nsDll(const char *libFullPath);
nsDll(const char *libFullPath, PRTime lastModTime, PRUint32 fileSize);
~nsDll(void);
// Status checking on operations completed
nsDllStatus GetStatus(void) { return (m_status); }
// Dll Loading
PRBool Load(void);
PRBool Unload(void);
PRBool IsLoaded(void)
{
return ((m_instance != 0) ? PR_TRUE : PR_FALSE);
}
void *FindSymbol(const char *symbol);
const char *GetFullPath(void) { return (m_fullpath); }
PRTime GetLastModifiedTime(void) { return(m_lastModTime); }
PRUint32 GetSize(void) { return(m_size); }
PRLibrary *GetInstance(void) { return (m_instance); }
};

View File

@@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
/* nsDllStore
*
* Stores dll and their accociated info in a hash keyed on the system format
* full dll path name e.g C:\Program Files\Netscape\Program\raptor.dll
*
* NOTE: dll names are considered to be case sensitive.
*/
#include "xcDllStore.h"
static PR_CALLBACK PRIntn _deleteDllInfo(PLHashEntry *he, PRIntn i, void *arg)
{
delete (nsDll *)he->value;
return (HT_ENUMERATE_NEXT);
}
nsDllStore::nsDllStore(void) : m_dllHashTable(NULL)
{
PRUint32 initSize = 128;
m_dllHashTable = PL_NewHashTable(initSize, PL_HashString,
PL_CompareStrings, PL_CompareValues, NULL, NULL);
}
nsDllStore::~nsDllStore(void)
{
if (m_dllHashTable)
{
// Delete each of the nsDll stored before deleting the Hash Table
PL_HashTableEnumerateEntries(m_dllHashTable, _deleteDllInfo, NULL);
PL_HashTableDestroy(m_dllHashTable);
}
m_dllHashTable = NULL;
}
nsDll* nsDllStore::Get(const char *dll)
{
nsDll *dllInfo = NULL;
if (m_dllHashTable)
{
dllInfo = (nsDll *)PL_HashTableLookup(m_dllHashTable, dll);
}
return (dllInfo);
}
nsDll* nsDllStore::Remove(const char *dll)
{
if (m_dllHashTable == NULL)
{
return (NULL);
}
nsDll *dllInfo = Get(dll);
PL_HashTableRemove(m_dllHashTable, dll);
return (dllInfo);
}
PRBool nsDllStore::Put(const char *dll, nsDll *dllInfo)
{
if (m_dllHashTable == NULL)
return(PR_FALSE);
PLHashEntry *entry =
PL_HashTableAdd(m_dllHashTable, (void *)dll, (void *)dllInfo);
return ((entry != NULL) ? PR_TRUE : PR_FALSE);
}

View File

@@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
/* nsDllStore
*
* Stores dll and their accociated info in a hash keyed on the system format
* full dll path name e.g C:\Program Files\Netscape\Program\raptor.dll
*
* NOTE: dll names are considered to be case sensitive.
*/
#include "plhash.h"
#include "xcDll.h"
class nsDllStore
{
private:
PLHashTable *m_dllHashTable;
public:
// Constructor
nsDllStore(void);
~nsDllStore(void);
// Caller is not expected to delete nsDll returned
// The nsDll returned in NOT removed from the hash
nsDll* Get(const char *filename);
PRBool Put(const char *filename, nsDll *dllInfo);
// The nsDll returned is removed from the hash
// Caller is expected to delete the returned nsDll
nsDll* Remove(const char *filename);
};

View File

@@ -0,0 +1,117 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; I) [Netscape]">
<TITLE>Gemini Object Model</TITLE>
</HEAD>
<BODY>
<H1>
Gemini Object Model</H1>
The gemini object model is a cross platform component object model modelled
after win32's IUnknown and COM. We do not support a C API to gemini at
this time.
<H2>
nsID</H2>
Like OSF's DCE, we use an "interface id" which is a unique identifer which
names the interface. The nsID and be used as a key into a cross platform
registry service to discover an implementation of an interface. Here is
the declaration of nsID:
<UL><TT>struct nsID {</TT>
<BR><TT>&nbsp; PRUint32 m0;</TT>
<BR><TT>&nbsp; PRUint16 m1, m2;</TT>
<BR><TT>&nbsp; PRUint8 m3[8];</TT>
<P><TT>&nbsp; inline nsbool Equals(const nsID&amp; other) const {</TT>
<BR><TT>&nbsp;&nbsp;&nbsp; return</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[0] == ((PRUint32*)
&amp;other.m0)[0]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[1] == ((PRUint32*)
&amp;other.m0)[1]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[2] == ((PRUint32*)
&amp;other.m0)[2]) &amp;&amp;</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (((PRUint32*) &amp;m0)[3] == ((PRUint32*)
&amp;other.m0)[3]);</TT>
<BR><TT>&nbsp; }</TT>
<BR><TT>};</TT></UL>
On windows, the "uuidgen" program (provided with Visual C++) can be used
to generate these identifiers.
<H2>
nsISupports</H2>
This is the base class for all component objects. Not all objects are component
objects; these rules apply to objects which expose an interface which is
shared across dll/exe boundaries. Here is nsISupports:
<UL><TT>typedef nsID nsIID;</TT>
<BR><TT>class nsISupports {</TT>
<BR><TT>public:</TT>
<BR><TT>&nbsp; virtual nsqresult QueryInterface(const nsIID&amp; aIID,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void** aInstancePtr) = 0;</TT>
<BR><TT>&nbsp; virtual nsrefcnt AddRef() = 0;</TT>
<BR><TT>&nbsp; virtual nsrefcnt Release() = 0;</TT>
<BR><TT>};</TT></UL>
The semantics of this interface are identical to win32's "COM" IUnknown
interface. In addition, the types are carefully mapped and the names are
the same so that if necessary we can "flip a switch" and have the windows
version (or any other platform that embraces COM) use the native COM IUnknown
without source code modification.
<H2>
Factory Procedures</H2>
Factory procedures use this design pattern
<UL><TT>nsqresult NS_NewFoo(nsIFoo** aInstancePtr, nsISupports* aOuter,
...);</TT></UL>
The return value is a status value (see nsISupports.h for the legal return
values); the first argument is a pointer to a cell which will hold the
new instance pointer if the factory procedure succeeds. The second argument
is a pointer to a containing component object that wishes to aggregate
in the Foo object. This pointer will be null if no aggregation is requested.
If the factory procedure cannot support aggregation of the Foo type then
it fails and returns an error if aggregation is requested.
<P>The following symbols are defined for standard error return values from
<TT>QueryInterface</TT> and from factory procedures:
<UL><TT>#define NS_FAILED(_nsresult) ((_nsresult) &lt; 0)</TT>
<BR><TT>#define NS_SUCCEEDED(_nsresult) ((_nsresult) >= 0)</TT>
<P><TT>// Standard "it worked" return value</TT>
<BR><TT>#define NS_OK 0</TT>
<P><TT>// Some standard error codes we use</TT>
<BR><TT>#define NS_ERROR_BASE ((nsresult) 0xC1F30000)</TT>
<BR><TT>#define NS_ERROR_OUT_OF_MEMORY (NS_ERROR_BASE + 0)</TT>
<BR><TT>#define NS_ERROR_NO_AGGREGATION (NS_ERROR_BASE + 1)</TT>
<BR><TT>#define NS_NOINTERFACE ((nqresult) 0x80004002L)</TT></UL>
<H2>
nsIFactory</H2>
Factory classes should eventually replace factory procedures for major
classes. They provide an easy mechanism for placing code in DLLs. The nsIFactory
class is as follows:
<BR>&nbsp;
<UL><TT>class nsIFactory: public nsISupports {</TT>
<BR><TT>public:</TT>
<UL><TT>virtual nsresult CreateInstance(const nsIID &amp;aIID,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
nsISupports *aOuter,</TT>
<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
void **aResult) = 0;</TT>
<BR><TT>virtual void LockFactory(PRBool aLock) = 0;</TT></UL>
<TT>};</TT></UL>
This interface is again identical to the COM version. More on registering
factories shortly.
<H2>
Error Handling</H2>
Because no exceptions are returned, error handling is done in the traditional
"error status value" method.
<H2>
Cross Platform Registry</H2>
A cross platform registry was written for the SmartUpdate feature of Communicator.
We will investigate it's usefulness for our purposes.
<H2>
Library Management</H2>
NSPR 2.x provides the cross platform mechanism for loading and unloading
libraries, and run time linking.
<BR>&nbsp;
</BODY>
</HTML>

View File

@@ -0,0 +1,93 @@
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Kipp E.B. Hickman">
<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (WinNT; U) [Netscape]">
<TITLE>C++ Tips</TITLE>
</HEAD>
<BODY>
<H1>
C++ Tips</H1>
This is a compilation of tips on how to write cross-platform C++ code that
compiles everywhere.
<H2>
General</H2>
<UL>
<LI>
Always use the nspr types for intrinsic integer types. The only exception
to this rule is when writing machine dependent code that is called from
xp code. In this case you will probably need to bridge the type systems
and cast from an nspr type to a native type. The other exception is floating
point; nspr defines PRFloat as a double (!).</LI>
<LI>
Exceptions do not work everywhere so don't use them anywhere except in
machine specific code, and then if you do use them in machine specific
code you must catch all exceptions there because you can't throw the exception
across xp code.</LI>
<LI>
Templates do not work everywhere so don't use them anywhere.</LI>
<LI>
Do not wrap include statements with an #ifdef. The reason is that when
the symbol is not defined, other compiler symbols will not be defined and
it will be hard to test the code on all platforms. An example of what <B>not</B>
to do:</LI>
<BR>&nbsp;
<UL><TT>#ifdef X</TT>
<BR><TT>#include "foo.h"</TT>
<BR><TT>#endif</TT>
<BR><TT></TT>&nbsp;</UL>
<LI>
For types that do not need operator= or a copy constructor, declare them
yourselves and make them private. Example:</LI>
<BR>&nbsp;
<UL><TT>class foo {</TT>
<BR><TT>...</TT>
<BR><TT>private:</TT>
<BR><TT>&nbsp; // These are not supported and are not implemented!</TT>
<BR><TT>&nbsp; foo(const foo&amp; x);</TT>
<BR><TT>&nbsp; foo&amp; operator=(const foo&amp; x);</TT>
<BR><TT>};</TT></UL>
<LI>
</LI>
</UL>
<H2>
Windows Compatability</H2>
<H2>
Metroworks Compatability</H2>
<UL>
<LI>
MAC compilers do not handle #include path names in the same manner as other
systems. Consequently #include statements should not contain path names,
just simple file names. An example of what <B>not</B> to do:</LI>
<BR>&nbsp;
<UL>#include "gemini/nsICSSParser.h"
<BR>&nbsp;</UL>
<LI>
</LI>
</UL>
<H2>
G++ Compatability</H2>
<UL>
<LI>
Use void in argument lists for functions that have no arguments (this works
around a bug in g++ 2.6.3)</LI>
</UL>
</BODY>
</HTML>

View File

@@ -0,0 +1,175 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#include "prmem.h"
#include "nsHashtable.h"
//
// Key operations
//
static PR_CALLBACK PLHashNumber _hashValue(const void *key)
{
return ((const nsHashKey *) key)->HashValue();
}
static PR_CALLBACK PRIntn _hashKeyCompare(const void *key1, const void *key2) {
return ((const nsHashKey *) key1)->Equals((const nsHashKey *) key2);
}
static PR_CALLBACK PRIntn _hashValueCompare(const void *value1,
const void *value2) {
// We're not going to make any assumptions about value equality
return 0;
}
//
// Memory callbacks
//
static PR_CALLBACK void *_hashAllocTable(void *pool, PRSize size) {
return PR_MALLOC(size);
}
static PR_CALLBACK void _hashFreeTable(void *pool, void *item) {
PR_DELETE(item);
}
static PR_CALLBACK PLHashEntry *_hashAllocEntry(void *pool, const void *key) {
return PR_NEW(PLHashEntry);
}
static PR_CALLBACK void _hashFreeEntry(void *pool, PLHashEntry *entry,
PRUintn flag) {
if (flag == HT_FREE_ENTRY) {
delete (nsHashKey *) (entry->key);
PR_DELETE(entry);
}
}
static PLHashAllocOps _hashAllocOps = {
_hashAllocTable, _hashFreeTable,
_hashAllocEntry, _hashFreeEntry
};
//
// Enumerator callback
//
struct _HashEnumerateArgs {
nsHashtableEnumFunc fn;
void* arg;
};
static PR_CALLBACK PRIntn _hashEnumerate(PLHashEntry *he, PRIntn i, void *arg)
{
_HashEnumerateArgs* thunk = (_HashEnumerateArgs*)arg;
return thunk->fn((nsHashKey *) he->key, he->value, thunk->arg)
? HT_ENUMERATE_NEXT
: HT_ENUMERATE_STOP;
}
//
// HashKey
//
nsHashKey::nsHashKey(void)
{
}
nsHashKey::~nsHashKey(void)
{
}
nsHashtable::nsHashtable(PRUint32 aInitSize) {
hashtable = PL_NewHashTable(aInitSize,
_hashValue,
_hashKeyCompare,
_hashValueCompare,
&_hashAllocOps,
NULL);
}
nsHashtable::~nsHashtable() {
PL_HashTableDestroy(hashtable);
}
void *nsHashtable::Put(nsHashKey *aKey, void *aData) {
void *res = NULL;
PLHashNumber hash = aKey->HashValue();
PLHashEntry *he;
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
if ((he = *hep) != NULL) {
res = he->value;
he->value = aData;
} else {
PL_HashTableRawAdd(hashtable, hep, hash,
(void *) aKey->Clone(), aData);
}
return res;
}
void *nsHashtable::Get(nsHashKey *aKey) {
return PL_HashTableLookup(hashtable, (void *) aKey);
}
void *nsHashtable::Remove(nsHashKey *aKey) {
PLHashNumber hash = aKey->HashValue();
PLHashEntry *he;
PLHashEntry **hep = PL_HashTableRawLookup(hashtable, hash, (void *) aKey);
void *res = NULL;
if ((he = *hep) != NULL) {
res = he->value;
PL_HashTableRawRemove(hashtable, hep, he);
}
return res;
}
static PR_CALLBACK PRIntn _hashEnumerateCopy(PLHashEntry *he, PRIntn i, void *arg)
{
nsHashtable *newHashtable = (nsHashtable *)arg;
newHashtable->Put((nsHashKey *) he->key, he->value);
return HT_ENUMERATE_NEXT;
}
nsHashtable * nsHashtable::Clone() {
nsHashtable *newHashTable = new nsHashtable(hashtable->nentries);
PL_HashTableEnumerateEntries(hashtable, _hashEnumerateCopy, newHashTable);
return newHashTable;
}
void nsHashtable::Enumerate(nsHashtableEnumFunc aEnumFunc, void* closure) {
_HashEnumerateArgs thunk;
thunk.fn = aEnumFunc;
thunk.arg = closure;
PL_HashTableEnumerateEntries(hashtable, _hashEnumerate, &thunk);
}
static PR_CALLBACK PRIntn _hashEnumerateRemove(PLHashEntry *he, PRIntn i, void *arg)
{
return HT_ENUMERATE_REMOVE;
}
void nsHashtable::Reset() {
PL_HashTableEnumerateEntries(hashtable, _hashEnumerateRemove, NULL);
}

View File

@@ -0,0 +1,141 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsHashtable_h__
#define nsHashtable_h__
#include "plhash.h"
#include "nsCom.h"
class NS_COM nsHashKey {
protected:
nsHashKey(void);
public:
virtual ~nsHashKey(void);
virtual PRUint32 HashValue(void) const = 0;
virtual PRBool Equals(const nsHashKey *aKey) const = 0;
virtual nsHashKey *Clone(void) const = 0;
};
// Enumerator callback function. Use
typedef PRBool (*nsHashtableEnumFunc)(nsHashKey *aKey, void *aData, void* closure);
class NS_COM nsHashtable {
private:
// members
PLHashTable *hashtable;
public:
nsHashtable(PRUint32 aSize = 256);
~nsHashtable();
PRInt32 Count(void) { return hashtable->nentries; }
void *Put(nsHashKey *aKey, void *aData);
void *Get(nsHashKey *aKey);
void *Remove(nsHashKey *aKey);
nsHashtable *Clone();
void Enumerate(nsHashtableEnumFunc aEnumFunc, void* closure = NULL);
void Reset();
};
////////////////////////////////////////////////////////////////////////////////
// nsISupportsKey: Where keys are nsISupports objects that get refcounted.
#include "nsISupports.h"
class nsISupportsKey : public nsHashKey {
private:
nsISupports* mKey;
public:
nsISupportsKey(nsISupports* key) {
mKey = key;
NS_IF_ADDREF(mKey);
}
~nsISupportsKey(void) {
NS_IF_RELEASE(mKey);
}
PRUint32 HashValue(void) const {
return (PRUint32)mKey;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mKey == ((nsISupportsKey *) aKey)->mKey);
}
nsHashKey *Clone(void) const {
return new nsISupportsKey(mKey);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsVoidKey: Where keys are void* objects that don't get refcounted.
class nsVoidKey : public nsHashKey {
private:
const void* mKey;
public:
nsVoidKey(const void* key) {
mKey = key;
}
PRUint32 HashValue(void) const {
return (PRUint32)mKey;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mKey == ((const nsVoidKey *) aKey)->mKey);
}
nsHashKey *Clone(void) const {
return new nsVoidKey(mKey);
}
};
////////////////////////////////////////////////////////////////////////////////
// nsIDKey: Where keys are nsIDs (e.g. nsIID, nsCID).
#include "nsID.h"
class nsIDKey : public nsHashKey {
private:
nsID mID;
public:
nsIDKey(const nsID &aID) {
mID = aID;
}
PRUint32 HashValue(void) const {
return mID.m0;
}
PRBool Equals(const nsHashKey *aKey) const {
return (mID.Equals(((const nsIDKey *) aKey)->mID));
}
nsHashKey *Clone(void) const {
return new nsIDKey(mID);
}
};
#endif

View File

@@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 specifzic 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.
*/
#ifndef nsICollection_h___
#define nsICollection_h___
#include "nsISupports.h"
// IID for the nsICollection interface
#define NS_ICOLLECTION_IID \
{ 0xaeca730, 0x835b, 0x11d2, \
{ 0x8f, 0x30, 0x0, 0x60, 0x8, 0x31, 0x1, 0x94 } }
// IID for the nsICollection Factort interface
#define NS_ICOLLECTIONFACTORY_IID \
{ 0xf8052641, 0x8768, 0x11d2, \
{ 0x8f, 0x39, 0x0, 0x60, 0x8, 0x31, 0x1, 0x94 } }
//----------------------------------------------------------------------
/** nsICollection Interface
* this may be ordered or not. a list or array, the implementation is opaque
*/
class nsICollection : public nsISupports {
public:
static const nsIID& IID() { static nsIID iid = NS_ICOLLECTION_IID; return iid; }
/** AddItem will take an ISupports and keep track of it
* @param aItem is the Item to be added WILL BE ADDREFFED
*/
virtual nsresult AddItem(nsISupports *aItem)=0;
/** RemoveItem will take an nsISupports and remove it from the collection
* @param aItem is the item to be removed WILL BE RELEASED
*/
virtual nsresult RemoveItem(nsISupports *aItem)=0;
/** Clear will clear all items from list
*/
virtual nsresult Clear()=0;
};
#endif /* nsICollection_h___ */

View File

@@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsIEnumerator_h___
#define nsIEnumerator_h___
#include "nsISupports.h"
// {646F4FB0-B1F2-11d1-AA29-000000000000}
#define NS_IENUMERATOR_IID \
{0x646f4fb0, 0xb1f2, 0x11d1, \
{ 0xaa, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
class nsIEnumerator : public nsISupports {
public:
static const nsIID& IID() { static nsIID iid = NS_IENUMERATOR_IID; return iid; }
/** First will reset the list. will return NS_FAILED if no items
*/
NS_IMETHOD First()=0;
/** Last will reset the list to the end. will return NS_FAILED if no items
*/
NS_IMETHOD Last()=0;
/** Next will advance the list. will return failed if allready at end
*/
NS_IMETHOD Next()=0;
/** Prev will decrement the list. will return failed if allready at beginning
*/
NS_IMETHOD Prev()=0;
/** CurrentItem will return the CurrentItem item it will fail if the list is empty
* @param aItem return value
*/
NS_IMETHOD CurrentItem(nsISupports **aItem)=0;
/** return if the collection is at the end. that is the beginning following a call to Prev
* and it is the end of the list following a call to next
* @param aItem return value
*/
NS_IMETHOD IsDone()=0;
};
#endif // __nsIEnumerator_h

View File

@@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsISupportsArray_h___
#define nsISupportsArray_h___
#include "nsCom.h"
#include "nsISupports.h"
// {791eafa0-b9e6-11d1-8031-006008159b5a}
#define NS_ISUPPORTSARRAY_IID \
{0x791eafa0, 0xb9e6, 0x11d1, \
{0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
// Enumerator callback function. Return PR_FALSE to stop
typedef PRBool (*nsISupportsArrayEnumFunc)(nsISupports* aElement, void *aData);
class nsISupportsArray : public nsISupports {
public:
static const nsIID& IID() { static nsIID iid = NS_ISUPPORTSARRAY_IID; return iid; }
NS_IMETHOD_(nsISupportsArray&) operator=(const nsISupportsArray& other) = 0;
NS_IMETHOD_(PRBool) operator==(const nsISupportsArray& other) const = 0;
NS_IMETHOD_(PRBool) Equals(const nsISupportsArray* other) const = 0;
NS_IMETHOD_(PRInt32) Count(void) const = 0;
NS_IMETHOD_(nsISupports*) ElementAt(PRInt32 aIndex) const = 0;
NS_IMETHOD_(nsISupports*) operator[](PRInt32 aIndex) const = 0;
NS_IMETHOD_(PRInt32) IndexOf(const nsISupports* aPossibleElement, PRInt32 aStartIndex = 0) const = 0;
NS_IMETHOD_(PRInt32) LastIndexOf(const nsISupports* aPossibleElement) const = 0;
NS_IMETHOD_(PRBool) InsertElementAt(nsISupports* aElement, PRInt32 aIndex) = 0;
NS_IMETHOD_(PRBool) ReplaceElementAt(nsISupports* aElement, PRInt32 aIndex) = 0;
NS_IMETHOD_(PRBool) AppendElement(nsISupports* aElement) = 0;
NS_IMETHOD_(PRBool) RemoveElementAt(PRInt32 aIndex) = 0;
NS_IMETHOD_(PRBool) RemoveElement(const nsISupports* aElement, PRInt32 aStartIndex = 0) = 0;
NS_IMETHOD_(PRBool) RemoveLastElement(const nsISupports* aElement) = 0;
NS_IMETHOD_(PRBool) AppendElements(nsISupportsArray* aElements) = 0;
NS_IMETHOD_(void) Clear(void) = 0;
NS_IMETHOD_(void) Compact(void) = 0;
NS_IMETHOD_(PRBool) EnumerateForwards(nsISupportsArrayEnumFunc aFunc, void* aData) const = 0;
NS_IMETHOD_(PRBool) EnumerateBackwards(nsISupportsArrayEnumFunc aFunc, void* aData) const = 0;
private:
// Copy constructors are not allowed
// XXX test wether this has to be here nsISupportsArray(const nsISupportsArray& other);
};
extern NS_COM nsresult
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult);
#endif // nsISupportsArray_h___

View File

@@ -0,0 +1,382 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#include "nsISupportsArray.h"
static NS_DEFINE_IID(kISupportsArrayIID, NS_ISUPPORTSARRAY_IID);
static const PRInt32 kGrowArrayBy = 8;
static const PRInt32 kAutoArraySize = 4;
class SupportsArrayImpl : public nsISupportsArray {
public:
SupportsArrayImpl(void);
~SupportsArrayImpl(void);
NS_DECL_ISUPPORTS
NS_IMETHOD_(nsISupportsArray&) operator=(const nsISupportsArray& aOther);
NS_IMETHOD_(PRBool) operator==(const nsISupportsArray& aOther) const { return Equals(&aOther); }
NS_IMETHOD_(PRBool) Equals(const nsISupportsArray* aOther) const;
NS_IMETHOD_(PRInt32) Count(void) const { return mCount; }
NS_IMETHOD_(nsISupports*) ElementAt(PRInt32 aIndex) const;
NS_IMETHOD_(nsISupports*) operator[](PRInt32 aIndex) const { return ElementAt(aIndex); }
NS_IMETHOD_(PRInt32) IndexOf(const nsISupports* aPossibleElement, PRInt32 aStartIndex = 0) const;
NS_IMETHOD_(PRInt32) LastIndexOf(const nsISupports* aPossibleElement) const;
NS_IMETHOD_(PRBool) InsertElementAt(nsISupports* aElement, PRInt32 aIndex);
NS_IMETHOD_(PRBool) ReplaceElementAt(nsISupports* aElement, PRInt32 aIndex);
NS_IMETHOD_(PRBool) AppendElement(nsISupports* aElement) {
return InsertElementAt(aElement, mCount);
}
NS_IMETHOD_(PRBool) RemoveElementAt(PRInt32 aIndex);
NS_IMETHOD_(PRBool) RemoveElement(const nsISupports* aElement, PRInt32 aStartIndex = 0);
NS_IMETHOD_(PRBool) RemoveLastElement(const nsISupports* aElement);
NS_IMETHOD_(PRBool) AppendElements(nsISupportsArray* aElements);
NS_IMETHOD_(void) Clear(void);
NS_IMETHOD_(void) Compact(void);
NS_IMETHOD_(PRBool) EnumerateForwards(nsISupportsArrayEnumFunc aFunc, void* aData) const;
NS_IMETHOD_(PRBool) EnumerateBackwards(nsISupportsArrayEnumFunc aFunc, void* aData) const;
protected:
void DeleteArray(void);
nsISupports** mArray;
PRInt32 mArraySize;
PRInt32 mCount;
nsISupports* mAutoArray[kAutoArraySize];
private:
// Copy constructors are not allowed
SupportsArrayImpl(const nsISupportsArray& other);
};
SupportsArrayImpl::SupportsArrayImpl()
{
NS_INIT_REFCNT();
mArray = &(mAutoArray[0]);
mArraySize = kAutoArraySize;
mCount = 0;
}
SupportsArrayImpl::~SupportsArrayImpl()
{
DeleteArray();
}
NS_IMPL_ISUPPORTS(SupportsArrayImpl, kISupportsArrayIID);
void SupportsArrayImpl::DeleteArray(void)
{
Clear();
if (mArray != &(mAutoArray[0])) {
delete[] mArray;
mArray = &(mAutoArray[0]);
mArraySize = kAutoArraySize;
}
}
nsISupportsArray& SupportsArrayImpl::operator=(const nsISupportsArray& aOther)
{
PRInt32 otherCount = aOther.Count();
if (otherCount > mArraySize) {
DeleteArray();
mArraySize = otherCount;
mArray = new nsISupports*[mArraySize];
}
else {
Clear();
}
mCount = otherCount;
while (0 <= --otherCount) {
mArray[otherCount] = aOther.ElementAt(otherCount);
}
return *this;
}
PRBool SupportsArrayImpl::Equals(const nsISupportsArray* aOther) const
{
if (0 != aOther) {
const SupportsArrayImpl* other = (const SupportsArrayImpl*)aOther;
if (mCount == other->mCount) {
PRInt32 index = mCount;
while (0 <= --index) {
if (mArray[index] != other->mArray[index]) {
return PR_FALSE;
}
}
return PR_TRUE;
}
}
return PR_FALSE;
}
nsISupports* SupportsArrayImpl::ElementAt(PRInt32 aIndex) const
{
if ((0 <= aIndex) && (aIndex < mCount)) {
nsISupports* element = mArray[aIndex];
NS_ADDREF(element);
return element;
}
return 0;
}
PRInt32 SupportsArrayImpl::IndexOf(const nsISupports* aPossibleElement, PRInt32 aStartIndex) const
{
if ((0 <= aStartIndex) && (aStartIndex < mCount)) {
const nsISupports** start = (const nsISupports**)mArray; // work around goofy compiler behavior
const nsISupports** ep = (start + aStartIndex);
const nsISupports** end = (start + mCount);
while (ep < end) {
if (aPossibleElement == *ep) {
return (ep - start);
}
ep++;
}
}
return -1;
}
PRInt32 SupportsArrayImpl::LastIndexOf(const nsISupports* aPossibleElement) const
{
if (0 < mCount) {
const nsISupports** start = (const nsISupports**)mArray; // work around goofy compiler behavior
const nsISupports** ep = (start + mCount);
while (start <= --ep) {
if (aPossibleElement == *ep) {
return (ep - start);
}
}
}
return -1;
}
PRBool SupportsArrayImpl::InsertElementAt(nsISupports* aElement, PRInt32 aIndex)
{
if ((0 <= aIndex) && (aIndex <= mCount)) {
if (mArraySize < (mCount + 1)) { // need to grow the array
mArraySize += kGrowArrayBy;
nsISupports** oldArray = mArray;
mArray = new nsISupports*[mArraySize];
if (0 == mArray) { // ran out of memory
mArray = oldArray;
mArraySize -= kGrowArrayBy;
return PR_FALSE;
}
if (0 != oldArray) { // need to move old data
if (0 < aIndex) {
::memcpy(mArray, oldArray, aIndex * sizeof(nsISupports*));
}
PRInt32 slide = (mCount - aIndex);
if (0 < slide) {
::memcpy(mArray + aIndex + 1, oldArray + aIndex, slide * sizeof(nsISupports*));
}
if (oldArray != &(mAutoArray[0])) {
delete[] oldArray;
}
}
}
else {
PRInt32 slide = (mCount - aIndex);
if (0 < slide) {
::memmove(mArray + aIndex + 1, mArray + aIndex, slide * sizeof(nsISupports*));
}
}
mArray[aIndex] = aElement;
NS_ADDREF(aElement);
mCount++;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool SupportsArrayImpl::ReplaceElementAt(nsISupports* aElement, PRInt32 aIndex)
{
if ((0 <= aIndex) && (aIndex < mCount)) {
NS_ADDREF(aElement); // addref first in case it's the same object!
NS_RELEASE(mArray[aIndex]);
mArray[aIndex] = aElement;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool SupportsArrayImpl::RemoveElementAt(PRInt32 aIndex)
{
if ((0 <= aIndex) && (aIndex < mCount)) {
NS_RELEASE(mArray[aIndex]);
mCount--;
PRInt32 slide = (mCount - aIndex);
if (0 < slide) {
::memmove(mArray + aIndex, mArray + aIndex + 1,
slide * sizeof(nsISupports*));
}
return PR_TRUE;
}
return PR_FALSE;
}
PRBool SupportsArrayImpl::RemoveElement(const nsISupports* aElement, PRInt32 aStartIndex)
{
if ((0 <= aStartIndex) && (aStartIndex < mCount)) {
nsISupports** ep = mArray;
nsISupports** end = ep + mCount;
while (ep < end) {
if (*ep == aElement) {
return RemoveElementAt(PRInt32(ep - mArray));
}
ep++;
}
}
return PR_FALSE;
}
PRBool SupportsArrayImpl::RemoveLastElement(const nsISupports* aElement)
{
if (0 < mCount) {
nsISupports** ep = (mArray + mCount);
while (mArray <= --ep) {
if (*ep == aElement) {
return RemoveElementAt(PRInt32(ep - mArray));
}
}
}
return PR_FALSE;
}
PRBool SupportsArrayImpl::AppendElements(nsISupportsArray* aElements)
{
SupportsArrayImpl* elements = (SupportsArrayImpl*)aElements;
if (elements && (0 < elements->mCount)) {
if (mArraySize < (mCount + elements->mCount)) { // need to grow the array
PRInt32 count = mCount + elements->mCount;
PRInt32 oldSize = mArraySize;
while (mArraySize < count) { // ick
mArraySize += kGrowArrayBy;
}
nsISupports** oldArray = mArray;
mArray = new nsISupports*[mArraySize];
if (0 == mArray) { // ran out of memory
mArray = oldArray;
mArraySize = oldSize;
return PR_FALSE;
}
if (0 != oldArray) { // need to move old data
if (0 < mCount) {
::memcpy(mArray, oldArray, mCount);
}
if (oldArray != &(mAutoArray[0])) {
delete[] oldArray;
}
}
}
PRInt32 index = 0;
while (index < elements->mCount) {
NS_ADDREF(elements->mArray[index]);
mArray[mCount++] = elements->mArray[index++];
}
return PR_TRUE;
}
return PR_FALSE;
}
void SupportsArrayImpl::Clear(void)
{
while (0 <= --mCount) {
NS_RELEASE(mArray[mCount]);
}
mCount = 0;
}
void SupportsArrayImpl::Compact(void)
{
if ((mArraySize != mCount) && (kAutoArraySize < mArraySize)) {
nsISupports** oldArray = mArray;
PRInt32 oldArraySize = mArraySize;
if (mCount <= kAutoArraySize) {
mArray = &(mAutoArray[0]);
mArraySize = kAutoArraySize;
}
else {
mArray = new nsISupports*[mCount];
mArraySize = mCount;
}
if (0 == mArray) {
mArray = oldArray;
mArraySize = oldArraySize;
return;
}
::memcpy(mArray, oldArray, mCount * sizeof(nsISupports*));
delete[] oldArray;
}
}
PRBool SupportsArrayImpl::EnumerateForwards(nsISupportsArrayEnumFunc aFunc, void* aData) const
{
PRInt32 index = -1;
PRBool running = PR_TRUE;
while (running && (++index < mCount)) {
running = (*aFunc)(mArray[index], aData);
}
return running;
}
PRBool SupportsArrayImpl::EnumerateBackwards(nsISupportsArrayEnumFunc aFunc, void* aData) const
{
PRInt32 index = mCount;
PRBool running = PR_TRUE;
while (running && (0 <= --index)) {
running = (*aFunc)(mArray[index], aData);
}
return running;
}
NS_COM nsresult
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult)
{
if (aInstancePtrResult == 0) {
return NS_ERROR_NULL_POINTER;
}
SupportsArrayImpl *it = new SupportsArrayImpl();
if (0 == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kISupportsArrayIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,74 @@
/* -*- 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsVector_h__
#define nsVector_h__
#include "plvector.h"
#include "nsCom.h"
class nsVector : public PLVector {
public:
// Construction
nsVector(PRUint32 initialSize = 0, PRInt32 initialGrowBy = 0) {
PL_VectorInitialize(this, initialSize, initialGrowBy);
}
~nsVector(void) { PL_VectorFinalize(this); }
// Attributes
PRUint32 GetSize(void) const { return PL_VectorGetSize(this); }
PRUint32 GetUpperBound(void) const { return GetSize() - 1; }
PRBool SetSize(PRUint32 nNewSize, PRInt32 nGrowBy = PL_VECTOR_GROW_DEFAULT) {
return PL_VectorSetSize(this, nNewSize, nGrowBy);
}
PRBool IsValidIndex(PRUint32 index) { return PL_VectorIsValidIndex(this, index); }
// Operations
// Clean up
void Compact(void) { PL_VectorCompact(this); }
void RemoveAll(void) { SetSize(0); }
void Copy(nsVector* src, PRUint32 len, PRUint32 dstPos = 0, PRUint32 srcPos = 0) {
PL_VectorCopy(this, dstPos, src, srcPos, len);
}
// Accessing elements
void* Get(PRUint32 index) const { return PL_VectorGet(this, index); }
void Set(PRUint32 index, void* newElement) { PL_VectorSet(this, index, newElement); }
void*& ElementAt(PRUint32 index) { return *PL_VectorGetAddr(this, index); }
// Potentially growing the array
PRInt32 Add(void* newElement) { return PL_VectorAdd(this, newElement); }
// overloaded operator helpers
void* operator[](PRUint32 index) const { return Get(index); }
void*& operator[](PRUint32 index) { return ElementAt(index); }
// Operations that move elements around
void Insert(PRUint32 index, void* newElement, PRInt32 count = 1) {
PL_VectorInsert(this, index, newElement, count);
}
void Remove(PRUint32 index, PRInt32 count = 1) {
PL_VectorRemove(this, index, count);
}
#ifdef DEBUG
void AssertValid(void) const { PL_VectorAssertValid((PLVector*)this); }
#endif
};
#endif

318
mozilla/xpcom/ds/plvector.c Normal file
View 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "plvector.h"
#include "prmem.h"
#include <string.h>
#ifdef XP_WIN16
#define SIZE_T_MAX 0xFF80 /* a little less than 64K, the max alloc size on win16. */
#define MAX_ARR_ELEMS SIZE_T_MAX/sizeof(void*)
#endif
PR_IMPLEMENT(PLVector*)
PL_NewVector(PRUint32 initialSize, PRInt32 initialGrowBy)
{
PLVector* v = (PLVector*)PR_Malloc(sizeof(PLVector*));
if (v == NULL)
return NULL;
PL_VectorInitialize(v, initialSize, initialGrowBy);
return v;
}
PR_IMPLEMENT(void)
PL_VectorDestroy(PLVector* v)
{
PL_VectorFinalize(v);
PR_Free(v);
}
/* Initializes an existing vector */
PR_IMPLEMENT(void)
PL_VectorInitialize(PLVector* v, PRUint32 initialSize, PRInt32 initialGrowBy)
{
v->data = NULL;
v->size = v->maxSize = v->growBy = 0;
if (initialSize > 0 || initialGrowBy > 0)
PL_VectorSetSize(v, initialSize, initialGrowBy);
}
/* Destroys the elements, but doesn't free the vector */
PR_IMPLEMENT(void)
PL_VectorFinalize(PLVector* v)
{
/* This implementation doesn't do anything to delete the elements
in the vector -- that's up to the caller. (Don't shoot me,
I just copied the code from libmsg.) */
PR_Free(v->data);
}
PR_IMPLEMENT(PRBool)
PL_VectorSetSize(PLVector* v, PRUint32 newSize, PRInt32 growBy)
{
if (growBy != -1)
v->growBy = growBy; /* set new size */
if (newSize == 0) {
/* shrink to nothing */
PR_Free(v->data);
v->data = NULL;
v->size = v->maxSize = 0;
}
else if (v->data == NULL) {
/* create one with exact size */
#ifdef SIZE_T_MAX
PR_ASSERT(newSize <= SIZE_T_MAX/sizeof(void*)); /* no overflow */
#endif
v->data = (void**)PR_Malloc(newSize * sizeof(void *));
if (v->data == NULL) {
v->size = 0;
return PR_FALSE;
}
memset(v->data, 0, newSize * sizeof(void *)); /* zero fill */
v->size = v->maxSize = newSize;
}
else if (newSize <= v->maxSize) {
/* it fits */
if (newSize > v->size) {
/* initialize the new elements */
memset(&v->data[v->size], 0, (newSize-v->size) * sizeof(void *));
}
v->size = newSize;
}
else {
/* otherwise, grow array */
PRUint32 newMax;
void** newData;
PRInt32 growBy = v->growBy;
if (growBy == 0) {
/* heuristically determine growth when growBy == 0
(this avoids heap fragmentation in many situations) */
growBy = PR_MIN(1024, PR_MAX(4, v->size / 8));
}
#ifdef MAX_ARR_ELEMS
if (v->size + growBy > MAX_ARR_ELEMS)
growBy = MAX_ARR_ELEMS - v->size;
#endif
if (newSize < v->maxSize + growBy)
newMax = v->maxSize + growBy; /* granularity */
else
newMax = newSize; /* no slush */
#ifdef SIZE_T_MAX
if (newMax >= SIZE_T_MAX/sizeof(void*))
return PR_FALSE;
PR_ASSERT(newMax <= SIZE_T_MAX/sizeof(void*)); /* no overflow */
#endif
PR_ASSERT(newMax >= v->maxSize); /* no wrap around */
newData = (void**)PR_Malloc(newMax * sizeof(void*));
if (newData != NULL) {
/* copy new data from old */
memcpy(newData, v->data, v->size * sizeof(void*));
/* construct remaining elements */
PR_ASSERT(newSize > v->size);
memset(&newData[v->size], 0, (newSize-v->size) * sizeof(void*));
/* get rid of old stuff (note: no destructors called) */
PR_Free(v->data);
v->data = newData;
v->size = newSize;
v->maxSize = newMax;
}
else {
return PR_FALSE;
}
}
return PR_TRUE;
}
PR_IMPLEMENT(PRBool)
PL_VectorIsValidIndex(PLVector* v, PRUint32 index)
{
return (index < v->size) ? PR_TRUE : PR_FALSE;
}
PR_IMPLEMENT(void)
PL_VectorCompact(PLVector* v)
{
if (v->size != v->maxSize) {
/* shrink to desired size */
#ifdef SIZE_T_MAX
PR_ASSERT(v->size <= SIZE_T_MAX/sizeof(void *)); /* no overflow */
#endif
void ** newData = NULL;
if (v->size != 0) {
newData = (void **)PR_Malloc(v->size * sizeof(void *));
/* copy new data from old */
memcpy(newData, v->data, v->size * sizeof(void *));
}
/* get rid of old stuff (note: no destructors called) */
PR_Free(v->data);
v->data = newData;
v->maxSize = v->size;
}
}
#if 0 /* becomes Copy */
PR_IMPLEMENT(void)
PL_VectorSplice(PLVector* v, PRUint32 startIndex, PLVector* newVector)
{
PRUint32 i;
PR_ASSERT(newVector != NULL);
if (PL_VectorGetSize(newVector) > 0) {
PL_VectorInsert(v, startIndex, PL_VectorGet(newVector, 0),
PL_VectorGetSize(newVector));
for (i = 0; i < PL_VectorGetSize(newVector); i++)
PL_VectorSet(v, startIndex + i, PL_VectorGet(newVector, i));
}
}
#endif
PR_IMPLEMENT(void)
PL_VectorCopy(PLVector* dstVector, PRUint32 dstPosition,
PLVector* srcVector, PRUint32 srcPosition, PRUint32 length)
{
PR_ASSERT(0); /* XXX not implemented yet */
#if 0
PL_VectorSetSize(dstVector, PR_MAX(PL_VectorGetSize(dstVector),
PL_VectorGetSize(srcVector)),
PL_VECTOR_GROW_DEFAULT);
if (v->data)
PR_Free(v->data);
v->size = oldA->v->size;
v->maxSize = oldA->v->maxSize;
v->growBy = oldA->v->growBy;
v->data = (void**)PR_Malloc(v->size * sizeof(void *));
if (v->data == NULL) {
v->size = 0;
}
else {
memcpy(v->data, oldA->v->data, v->size * sizeof(void *));
}
#endif
}
PR_IMPLEMENT(PLVector*)
PL_VectorClone(PLVector* v)
{
PLVector* newVec = PL_NewVector(v->size, v->growBy);
PL_VectorCopy(newVec, 0, v, 0, v->size);
return newVec;
}
/* Accessing elements */
PR_IMPLEMENT(void)
PL_VectorSet(PLVector* v, PRUint32 index, void* newElement)
{
if (index >= v->size) {
if (!PL_VectorSetSize(v, index+1, PL_VECTOR_GROW_DEFAULT))
return;
}
v->data[index] = newElement;
}
/* Adds at the end */
PR_IMPLEMENT(PRUint32)
PL_VectorAdd(PLVector* v, void* newElement)
{
PRUint32 index = v->size;
#ifdef XP_WIN16
if (index >= SIZE_T_MAX / 4L) {
return -1;
}
#endif
PL_VectorSet(v, index, newElement);
return index;
}
/* Inserts new element count times at index */
PR_IMPLEMENT(void)
PL_VectorInsert(PLVector* v, PRUint32 index, void* newElement, PRUint32 count)
{
PR_ASSERT(count > 0); /* zero or negative size not allowed */
if (index >= v->size) {
/* adding after the end of the array */
if (!PL_VectorSetSize(v, index + count, PL_VECTOR_GROW_DEFAULT))
return; /* grow so index is valid */
}
else {
/* inserting in the middle of the array */
PRUint32 nOldSize = v->size;
if (!PL_VectorSetSize(v, v->size + count, PL_VECTOR_GROW_DEFAULT))
return; /* grow it to new size */
/* shift old data up to fill gap */
memmove(&v->data[index+count], &v->data[index],
(nOldSize-index) * sizeof(void *));
/* re-init slots we copied from */
memset(&v->data[index], 0, count * sizeof(void *));
}
/* insert new value in the gap */
PR_ASSERT(index + count <= v->size);
while (count--)
v->data[index++] = newElement;
}
/* Removes count elements at index */
PR_IMPLEMENT(void)
PL_VectorRemove(PLVector* v, PRUint32 index, PRUint32 count)
{
PRUint32 moveCount;
PR_ASSERT(count >= 0);
PR_ASSERT(index + count <= v->size);
/* just remove a range */
moveCount = v->size - (index + count);
if (moveCount)
memmove(&v->data[index], &v->data[index + count],
moveCount * sizeof(void *));
v->size -= count;
}
#ifdef DEBUG
PR_IMPLEMENT(void)
PL_VectorAssertValid(PLVector* v)
{
if (v->data == NULL) {
PR_ASSERT(v->size == 0);
PR_ASSERT(v->maxSize == 0);
}
else {
PR_ASSERT(v->size >= 0);
PR_ASSERT(v->maxSize >= 0);
PR_ASSERT(v->size <= v->maxSize);
}
}
#endif

100
mozilla/xpcom/ds/plvector.h Normal file
View File

@@ -0,0 +1,100 @@
/* -*- 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef plvector_h__
#define plvector_h__
#include "prtypes.h"
#include "prlog.h"
PR_BEGIN_EXTERN_C
/* Vectors are extensible arrays */
typedef struct PLVector {
void** data; /* the actual array of data */
PRUint32 size; /* # of elements (upperBound - 1) */
PRUint32 maxSize; /* max allocated */
PRInt32 growBy; /* grow amount */
} PLVector;
PR_EXTERN(PLVector*)
PL_NewVector(PRUint32 initialSize, PRInt32 initialGrowBy);
PR_EXTERN(void)
PL_VectorDestroy(PLVector* v);
/* Initializes an existing vector */
PR_EXTERN(void)
PL_VectorInitialize(PLVector* v, PRUint32 initialSize, PRInt32 initialGrowBy);
/* Destroys the elements, but doesn't free the vector */
PR_EXTERN(void)
PL_VectorFinalize(PLVector* v);
#define PL_VectorGetSize(v) ((v)->size)
#define PL_VECTOR_GROW_DEFAULT (-1)
PR_EXTERN(PRBool)
PL_VectorSetSize(PLVector* v, PRUint32 newSize, PRInt32 growBy);
PR_EXTERN(PRBool)
PL_VectorIsValidIndex(PLVector* v, PRUint32 index);
PR_EXTERN(void)
PL_VectorCompact(PLVector* v);
PR_EXTERN(void)
PL_VectorCopy(PLVector* dstVector, PRUint32 dstPosition,
PLVector* srcVector, PRUint32 srcPosition, PRUint32 length);
PR_EXTERN(PLVector*)
PL_VectorClone(PLVector* v);
/* Accessing elements */
#define PL_VectorGetAddr(v, index) (PR_ASSERT((index) < (v)->size), &(v)->data[index])
#define PL_VectorGet(v, index) (*PL_VectorGetAddr(v, index))
PR_EXTERN(void)
PL_VectorSet(PLVector* v, PRUint32 index, void* newElement);
/* Adds at the end */
PR_EXTERN(PRUint32)
PL_VectorAdd(PLVector* v, void* newElement);
/* Inserts new element count times at index */
PR_EXTERN(void)
PL_VectorInsert(PLVector* v, PRUint32 index, void* newElement, PRUint32 count);
/* Removes count elements at index */
PR_EXTERN(void)
PL_VectorRemove(PLVector* v, PRUint32 index, PRUint32 count);
#ifdef DEBUG
PR_EXTERN(void)
PL_VectorAssertValid(PLVector* v);
#endif
PR_END_EXTERN_C
#endif /* plvector_h__ */

View File

@@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#include "nsCOMPtr.h"
void
nsCOMPtr_base::assign_with_AddRef( nsISupports* rawPtr )
{
if ( rawPtr )
NSCAP_ADDREF(rawPtr);
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
}
void
nsCOMPtr_base::assign_with_QueryInterface( nsISupports* rawPtr, const nsIID& iid, nsresult* result )
{
nsresult status = NS_OK;
if ( !rawPtr || !NS_SUCCEEDED( status = rawPtr->QueryInterface(iid, NSCAP_REINTERPRET_CAST(void**, &rawPtr)) ) )
rawPtr = 0;
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rawPtr;
if ( result )
*result = status;
}
void**
nsCOMPtr_base::begin_assignment()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = 0;
return NSCAP_REINTERPRET_CAST(void**, &mRawPtr);
}

View File

@@ -0,0 +1,668 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsCOMPtr_h___
#define nsCOMPtr_h___
// Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
#ifndef nsDebug_h___
#include "nsDebug.h"
// for |NS_PRECONDITION|
#endif
#ifndef nsISupports_h___
#include "nsISupports.h"
// for |nsresult|, |NS_ADDREF|, et al
#endif
/*
TO DO...
+ make alternative function for |getter_AddRefs| (or something)
+ make constructor for |nsQueryInterface| explicit (suddenly construct/assign from raw pointer becomes illegal)
+ Improve internal documentation
+ mention *&
+ alternatives for comparison
+ do_QueryInterface
*/
/* USER MANUAL
See also:
<http://www.meer.net/ScottCollins/doc/nsCOMPtr.html>, or
<http://www.mozilla.org/projects/xpcom/nsCOMPtr.html>
What is |nsCOMPtr|?
|nsCOMPtr| is a `smart-pointer'. It is a template class that acts, syntactically,
just like an ordinary pointer in C or C++, i.e., you can apply |*| or |->| to it to
`get to' what it points at. |nsCOMPtr| is smart in that, unlike a raw COM
interface pointer, |nsCOMPtr| manages |AddRef|, |Release|, and |QueryInterface|
_for_ you.
For instance, here is a typical snippet of code (at its most compact) where you assign
a COM interface pointer into a member variable:
NS_IF_RELEASE(mFoop); // If I have one already, I must release it before over-writing it.
if ( mFooP = aPtr ) // Now it's safe to assign it in, and, if it's not NULL
mFooP->AddRef(); // I must |AddRef| it, since I'll be holding on to it.
If our member variable |mFooP| were a |nsCOMPtr|, however, the snippet above
would look like this:
mFoop = aPtr; // Note: automatically |Release|s the old and |AddRef|s the new
|nsCOMPtr| helps you write code that is leak-proof, exception safe, and significantly
less verbose than you would with raw COM interface pointers. With |nsCOMPtr|, you
may never have to call |AddRef|, |Release|, or |QueryInterface| by hand.
You still have to understand COM. You still have to know which functions return
interface pointers that have already been |AddRef|ed and which don't. You still
have to ensure your program logic doesn't produce circularly referencing garbage.
|nsCOMPtr| is not a panacea. It is, however, helpful, easy to use, well-tested,
and polite. It doesn't require that a function author cooperate with you, nor does
your use force others to use it.
Where should I use |nsCOMPtr|?
...
Where _shouldn't_ I use |nsCOMPtr|?
In public interfaces... [[others]]
How does a |nsCOMPtr| differ from a raw pointer?
A |nsCOMPtr| differs, syntactically, from a raw COM interface pointer in three
ways:
+ It's declared differently, e.g.,
// instead of saying // you say
IFoo* fooP; nsCOMPtr<IFoo> fooP;
+ You can't call |AddRef| or |Release| through it,
fooP->AddRef(); // OK fooP->AddRef(); // Error: no permission
fooP->Release(); // OK fooP->Release(); // Error: no permission
+ You can't just apply an |&| to it to pass it to the typical `getter' function
AcquireFoo(&fooP); AcquireFoo( getter_AddRefs(fooP) );
GetFoo(&fooP); GetFoo( getter_doesnt_AddRef(fooP) );
How do I use |nsCOMPtr|?
Typically, you can use a |nsCOMPtr| exactly as you would a standard COM
interface pointer:
IFoo* fooP; nsCOMPtr<IFoo> fooP;
// ... // ...
fooP->SomeFunction(x, y, z); fooP->SomeFunction(x, y, z);
AnotherFunction(fooP); AnotherFunction(fooP);
if ( fooP ) if ( fooP )
// ... // ...
if ( fooP == barP ) if ( fooP == barP )
// ... // ...
There are some differences, though. In particular, you can't call |AddRef| or |Release|
through a |nsCOMPtr| directly, nor would you need to. |AddRef| is called for you
whenever you assign a COM interface pointer _into_ a |nsCOMPtr|. |Release| is
called on the old value, and also when the |nsCOMPtr| goes out of scope. Trying
to call |AddRef| or |Release| yourself will generate a compile-time error.
fooP->AddRef(); // fooP->AddRef(); // ERROR: no permission
fooP->Release(); // fooP->Release(); // ERROR: no permission
The final difference is that a bare |nsCOMPtr| (or rather a pointer to it) can't
be supplied as an argument to a function that `fills in' a COM interface pointer.
Rather it must be wrapped with a utility call that says whether the function calls
|AddRef| before returning, e.g.,
...->QueryInterface(riid, &fooP) ...->QueryInterface(riid, getter_AddRefs(fooP))
LookupFoo(&fooP); LookupFoo( getter_doesnt_AddRef(fooP) );
Don't worry. It's a compile-time error if you forget to wrap it.
Compare the raw-pointer way...
IFoo* foo = 0;
nsresult status = CreateIFoo(&foo);
if ( NS_SUCCEEDED(status) )
{
IBar* bar = 0;
if ( NS_SUCCEEDED(status = foo->QueryInterface(riid, &bar)) )
{
IFooBar* foobar = 0;
if ( NS_SUCCEEDED(status = CreateIFooBar(foo, bar, &foobar)) )
{
foobar->DoTheReallyHardThing();
foobar->Release();
}
bar->Release();
}
foo->Release();
}
To the smart-pointer way...
nsCOMPtr<IFoo> fooP;
nsresult status = CreateIFoo( getter_AddRefs(fooP) );
if ( NS_SUCCEEDED(status) )
if ( nsCOMPtr<IBar> barP( fooP ) )
{
nsCOMPtr<IFooBar> fooBarP;
if ( NS_SUCCEEDED(status = CreateIFooBar(fooP, barP, getter_AddRefs(fooBarP))) )
fooBarP->DoTheReallyHardThing();
}
Is there an easy way to convert my current code?
...
What do I have to beware of?
VC++ < 6.0 _can't_ handle the following situation
class nsIFoo; // forward declare some class
// ...
nsCOMPtr<nsIFoo> bar; // ERROR: incomplete type nsIFoo, etc.
Instead, you must make sure that you actually defined the underlying interface class, e.g.,
#include "nsIFoo.h" // fully defines |class nsIFoo|
// ...
nsCOMPtr<nsIFoo> bar; // no problem
Why is this? It's because VC++ tries to instantiate every member of the template
as soon as it sees the template declarations. Bad compiler. No cookie!
[[Thanks to mjudge, waterson, and pinkerton on this one.]]
Why does |getter_AddRefs| have such a funny name? I.e., why doesn't it follow our
naming conventions?
|getter_AddRefs| and |getter_doesnt_AddRef| use underscores for the same
reason our special macros do, quoting from our coding conventions "...to make them
stick out like a sore thumb". Note also that since |AddRef| is one word,
|getter_AddRefs| and |getter_doesnt_AddRef| couldn't have the right spacing if only inter-
caps were used.
*/
/*
WARNING:
This file defines several macros for internal use only. These macros begin with the
prefix |NSCAP_|. Do not use these macros in your own code. They are for internal use
only for cross-platform compatibility, and are subject to change without notice.
*/
/*
Set up some |#define|s to turn off a couple of troublesome C++ features.
Interestingly, none of the compilers barf on template stuff.
Ideally, we would want declarations like these in a configuration file
that everybody would get. Deciding exactly how to do that should
be part of the process of moving from experimental to production.
Update: ramiro is working on getting these into the configuration system.
*/
#if defined(__GNUG__) && (__GNUC_MINOR__ <= 90) && !defined(SOLARIS)
#define NSCAP_NO_MEMBER_USING_DECLARATIONS
#if (defined(LINUX) || defined(__bsdi__)) && (__GNUC_MINOR__ <= 7)
#define NSCAP_NEED_UNUSED_VIRTUAL_IMPLEMENTATIONS
#endif
#endif
#if defined(SOLARIS) && !defined(__GNUG__)
#define NSCAP_NO_BOOL
#define NSCAP_NO_EXPLICIT
#define NSCAP_NO_NEW_CASTS
#define NSCAP_NO_MEMBER_USING_DECLARATIONS
#endif
#if defined(_MSC_VER) && (_MSC_VER<1100)
#define NSCAP_NO_EXPLICIT
#define NSCAP_NO_BOOL
#endif
#if defined(IRIX)
#define NSCAP_NO_MEMBER_USING_DECLARATIONS
#define NSCAP_NO_EXPLICIT
#define NSCAP_NO_NEW_CASTS
#define NSCAP_NO_BOOL
#endif
#ifdef NSCAP_NO_EXPLICIT
#define explicit
#endif
#ifndef NSCAP_NO_NEW_CASTS
#define NSCAP_REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
#else
#define NSCAP_REINTERPRET_CAST(T,x) ((T)(x))
#endif
#ifndef NSCAP_NO_BOOL
typedef bool NSCAP_BOOL;
#else
typedef PRBool NSCAP_BOOL;
#endif
#ifdef NSCAP_FEATURE_DEBUG_MACROS
#define NSCAP_ADDREF(ptr) NS_ADDREF(ptr)
#define NSCAP_RELEASE(ptr) NS_RELEASE(ptr)
#else
#define NSCAP_ADDREF(ptr) (ptr)->AddRef()
#define NSCAP_RELEASE(ptr) (ptr)->Release()
#endif
/*
WARNING:
VC++4.2 is very picky. To compile under VC++4.2, the classes must be defined
in an order that satisfies:
nsDerivedSafe < nsCOMPtr
nsDontAddRef < nsCOMPtr
nsCOMPtr < nsGetterAddRefs
The other compilers probably won't complain, so please don't reorder these
classes, on pain of breaking 4.2 compatibility.
*/
template <class T>
class nsDerivedSafe : public T
/*
No client should ever see or have to type the name of this class. It is the
artifact that makes it a compile-time error to call |AddRef| and |Release|
on a |nsCOMPtr|.
See |nsCOMPtr::operator->|, |nsCOMPtr::operator*|, et al.
*/
{
private:
#ifndef NSCAP_NO_MEMBER_USING_DECLARATIONS
using T::AddRef;
using T::Release;
#else
nsrefcnt AddRef();
nsrefcnt Release();
#endif
void operator delete( void* ); // NOT TO BE IMPLEMENTED
// declaring |operator delete| private makes calling delete on an interface pointer a compile error
nsDerivedSafe& operator=( const nsDerivedSafe& ); // NOT TO BE IMPLEMENTED
// you may not call |operator=()| through a dereferenced |nsCOMPtr|, because you'd get the wrong one
};
#if defined(NSCAP_NO_MEMBER_USING_DECLARATIONS) && defined(NSCAP_NEED_UNUSED_VIRTUAL_IMPLEMENTATIONS)
template <class T>
nsrefcnt
nsDerivedSafe<T>::AddRef()
{
return 0;
}
template <class T>
nsrefcnt
nsDerivedSafe<T>::Release()
{
return 0;
}
#endif
template <class T>
struct nsDontQueryInterface
/*
...
*/
{
explicit
nsDontQueryInterface( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
nsDontQueryInterface<T>
dont_QueryInterface( T* aRawPtr )
{
return nsDontQueryInterface<T>(aRawPtr);
}
struct nsQueryInterface
{
// explicit
nsQueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
: mRawPtr(aRawPtr),
mErrorPtr(error)
{
// nothing else to do here
}
nsISupports* mRawPtr;
nsresult* mErrorPtr;
};
inline
nsQueryInterface
do_QueryInterface( nsISupports* aRawPtr, nsresult* error = 0 )
{
return nsQueryInterface(aRawPtr, error);
}
template <class T>
struct nsDontAddRef
/*
...cooperates with |nsCOMPtr| to allow you to assign in a pointer _without_
|AddRef|ing it. You would rarely use this directly, but rather through the
machinery of |getter_AddRefs| in the argument list to functions that |AddRef|
their results before returning them to the caller.
See also |getter_AddRefs()| and |class nsGetterAddRefs|.
*/
{
explicit
nsDontAddRef( T* aRawPtr )
: mRawPtr(aRawPtr)
{
// nothing else to do here
}
T* mRawPtr;
};
template <class T>
inline
nsDontAddRef<T>
dont_AddRef( T* aRawPtr )
/*
...makes typing easier, because it deduces the template type, e.g.,
you write |dont_AddRef(fooP)| instead of |nsDontAddRef<IFoo>(fooP)|.
Like the class it is shorthand for, you would rarely use this directly,
but rather through |getter_AddRefs|.
*/
{
return nsDontAddRef<T>(aRawPtr);
}
class nsCOMPtr_base
{
public:
nsCOMPtr_base( nsISupports* rawPtr = 0 )
: mRawPtr(rawPtr)
{
// nothing else to do here
}
~nsCOMPtr_base()
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
}
NS_EXPORT void assign_with_AddRef( nsISupports* );
NS_EXPORT void assign_with_QueryInterface( nsISupports*, const nsIID&, nsresult* );
NS_EXPORT void** begin_assignment();
protected:
nsISupports* mRawPtr;
};
template <class T>
class nsCOMPtr : private nsCOMPtr_base
/*
...
*/
{
public:
typedef T element_type;
nsCOMPtr()
// : nsCOMPtr_base(0)
{
// nothing else to do here
}
nsCOMPtr( const nsQueryInterface& aSmartPtr )
// : nsCOMPtr_base(0)
{
assign_with_QueryInterface(aSmartPtr.mRawPtr, T::IID(), aSmartPtr.mErrorPtr);
}
nsCOMPtr( const nsDontAddRef<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
// nothing else to do here
}
nsCOMPtr( const nsDontQueryInterface<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr( const nsCOMPtr<T>& aSmartPtr )
: nsCOMPtr_base(aSmartPtr.mRawPtr)
{
if ( mRawPtr )
NSCAP_ADDREF(mRawPtr);
}
nsCOMPtr<T>&
operator=( const nsQueryInterface& rhs )
{
assign_with_QueryInterface(rhs.mRawPtr, T::IID(), rhs.mErrorPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontAddRef<T>& rhs )
{
if ( mRawPtr )
NSCAP_RELEASE(mRawPtr);
mRawPtr = rhs.mRawPtr;
return *this;
}
nsCOMPtr<T>&
operator=( const nsDontQueryInterface<T>& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsCOMPtr<T>&
operator=( const nsCOMPtr& rhs )
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsDerivedSafe<T>*
get() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
return NSCAP_REINTERPRET_CAST(nsDerivedSafe<T>*, mRawPtr);
}
nsDerivedSafe<T>*
operator->() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
return get();
}
nsDerivedSafe<T>&
operator*() const
// returns a |nsDerivedSafe<T>*| to deny clients the use of |AddRef| and |Release|
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator*().");
return *get();
}
operator nsDerivedSafe<T>*() const
{
return get();
}
#if 0
private:
friend class nsGetterAddRefs<T>;
/*
In a perfect world, the following member function, |StartAssignment|, would be private.
It is and should be only accessed by the closely related class |nsGetterAddRefs<T>|.
Unfortunately, some compilers---most notably VC++5.0---fail to grok the
friend declaration above or in any alternate acceptable form. So, physically
it will be public (until our compilers get smarter); but it is not to be
considered part of the logical public interface.
*/
#endif
T**
StartAssignment()
{
return NSCAP_REINTERPRET_CAST(T**, begin_assignment());
}
};
template <class T>
class nsGetterAddRefs
/*
...
This class is designed to be used for anonymous temporary objects in the
argument list of calls that return COM interface pointers, e.g.,
nsCOMPtr<IFoo> fooP;
...->QueryInterface(iid, nsGetterAddRefs<IFoo>(fooP))
...->QueryInterface(iid, getter_AddRefs(fooP))
When initialized with a |nsCOMPtr|, as in the example above, it returns
a |void**| (or |T**| if needed) that the outer call (|QueryInterface| in this
case) can fill in. When this temporary object goes out of scope, just after
the call returns, its destructor assigned the resulting interface pointer, i.e.,
|QueryInterface|s result, into the |nsCOMPtr| it was initialized with.
See also |nsGetterDoesntAddRef|.
*/
{
public:
explicit
nsGetterAddRefs( nsCOMPtr<T>& aSmartPtr )
: mTargetSmartPtr(aSmartPtr)
{
// nothing else to do
}
operator void**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return NSCAP_REINTERPRET_CAST(void**, mTargetSmartPtr.StartAssignment());
}
T*&
operator*()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return *(mTargetSmartPtr.StartAssignment());
}
operator T**()
{
// NS_PRECONDITION(mTargetSmartPtr != 0, "getter_AddRefs into no destination");
return mTargetSmartPtr.StartAssignment();
}
private:
nsCOMPtr<T>& mTargetSmartPtr;
};
template <class T>
inline
nsGetterAddRefs<T>
getter_AddRefs( nsCOMPtr<T>& aSmartPtr )
/*
Used around a |nsCOMPtr| when
...makes the class |nsGetterAddRefs<T>| invisible.
*/
{
return nsGetterAddRefs<T>(aSmartPtr);
}
#endif // !defined(nsCOMPtr_h___)

View File

@@ -0,0 +1,169 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#include "nsDebug.h"
#include "prlog.h"
#if defined(_WIN32)
#include <windows.h>
#elif defined(XP_MAC)
#define TEMP_MAC_HACK
//------------------------
#ifdef TEMP_MAC_HACK
#include <MacTypes.h>
#include <Processes.h>
// TEMPORARY UNTIL WE HAVE MACINTOSH ENVIRONMENT VARIABLES THAT CAN TURN ON
// LOGGING ON MACINTOSH
// At this moment, NSPR's logging is a no-op on Macintosh.
#include <stdarg.h>
#include <stdio.h>
#undef PR_LOG
#define PR_LOG(module,level,args) dprintf args
static void dprintf(const char *format, ...)
{
va_list ap;
Str255 buffer;
va_start(ap, format);
buffer[0] = vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
va_end(ap);
DebugStr(buffer);
}
#endif // TEMP_MAC_HACK
//------------------------
#endif
/**
* Implementation of the nsDebug methods. Note that this code is
* always compiled in, in case some other module that uses it is
* compiled with debugging even if this library is not.
*/
static PRLogModuleInfo* gDebugLog;
static void InitLog(void)
{
if (0 == gDebugLog) {
gDebugLog = PR_NewLogModule("nsDebug");
gDebugLog->level = PR_LOG_DEBUG;
}
}
NS_COM void nsDebug::Abort(const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Abort: at file %s, line %d", aFile, aLine));
PR_LogFlush();
#if defined(_WIN32)
long* __p = (long*) 0x7;
*__p = 0x7;
#elif defined(XP_MAC)
ExitToShell();
#elif defined(XP_UNIX)
::abort();
#endif
}
NS_COM void nsDebug::Break(const char* aFile, PRIntn aLine)
{
#ifndef TEMP_MAC_HACK
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Break: at file %s, line %d", aFile, aLine));
PR_LogFlush();
//XXX this works on win32 only for now. For all the other platforms call Abort
#if defined(_WIN32)
::DebugBreak();
#else
Abort(aFile, aLine);
#endif
#endif // TEMP_MAC_HACK
}
NS_COM void nsDebug::PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PreCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("PostCondition: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Assertion: \"%s\" (%s) at file %s, line %d", aStr, aExpr,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotYetImplemented: \"%s\" at file %s, line %d", aMessage,
aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::NotReached(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("NotReached: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Error(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Error: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
Break(aFile, aLine);
}
NS_COM void nsDebug::Warning(const char* aMessage,
const char* aFile, PRIntn aLine)
{
InitLog();
PR_LOG(gDebugLog, PR_LOG_ERROR,
("Warning: \"%s\" at file %s, line %d", aMessage, aFile, aLine));
}

View File

@@ -0,0 +1,179 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef nsDebug_h___
#define nsDebug_h___
#include "nsCom.h"
#include "prtypes.h"
#ifdef DEBUG
#define NS_DEBUG
#endif
/**
* Namespace for debugging methods. Note that your code must use the
* macros defined later in this file so that the debug code can be
* conditionally compiled out.
*/
class nsDebug {
public:
// XXX add in log controls here
// XXX probably want printf type arguments
/**
* Abort the executing program. This works on all architectures.
*/
static NS_COM void Abort(const char* aFile, PRIntn aLine);
/**
* Break the executing program into the debugger.
*/
static NS_COM void Break(const char* aFile, PRIntn aLine);
/**
* Log a pre-condition message to the debug log
*/
static NS_COM void PreCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a post-condition message to the debug log
*/
static NS_COM void PostCondition(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log an assertion message to the debug log
*/
static NS_COM void Assertion(const char* aStr, const char* aExpr,
const char* aFile, PRIntn aLine);
/**
* Log a not-yet-implemented message to the debug log
*/
static NS_COM void NotYetImplemented(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a not-reached message to the debug log
*/
static NS_COM void NotReached(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log an error message to the debug log. This call returns.
*/
static NS_COM void Error(const char* aMessage,
const char* aFile, PRIntn aLine);
/**
* Log a warning message to the debug log.
*/
static NS_COM void Warning(const char* aMessage,
const char* aFile, PRIntn aLine);
};
#ifdef NS_DEBUG
/**
* Test a precondition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_PRECONDITION(expr,str) \
if (!(expr)) \
nsDebug::PreCondition(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_ASSERTION(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test an assertion for truth. If the expression is not true then
* trigger a program failure. The expression will still be
* executed in release mode.
*/
#define NS_VERIFY(expr,str) \
if (!(expr)) \
nsDebug::Assertion(str, #expr, __FILE__, __LINE__)
/**
* Test a post-condition for truth. If the expression is not true then
* trigger a program failure.
*/
#define NS_POSTCONDITION(expr,str) \
if (!(expr)) \
nsDebug::PostCondition(str, #expr, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTYETIMPLEMENTED(str) \
nsDebug::NotYetImplemented(str, __FILE__, __LINE__)
/**
* This macros triggers a program failure if executed. It indicates that
* an attempt was made to execute some unimplimented functionality.
*/
#define NS_NOTREACHED(str) \
nsDebug::NotReached(str, __FILE__, __LINE__)
/**
* Log an error message.
*/
#define NS_ERROR(str) \
nsDebug::Error(str, __FILE__, __LINE__)
/**
* Log a warning message.
*/
#define NS_WARNING(str) \
nsDebug::Warning(str, __FILE__, __LINE__)
/**
* Trigger an abort
*/
#define NS_ABORT() \
nsDebug::Abort(__FILE__, __LINE__)
/**
* Cause a break
*/
#define NS_BREAK() \
nsDebug::Break(__FILE__, __LINE__)
#else /* NS_DEBUG */
#define NS_PRECONDITION(expr,str) {}
#define NS_ASSERTION(expr,str) {}
#define NS_VERIFY(expr,str) expr
#define NS_POSTCONDITION(expr,str) {}
#define NS_NOTYETIMPLEMENTED(str) {}
#define NS_NOTREACHED(str) {}
#define NS_ERROR(str) {}
#define NS_WARNING(str) {}
#define NS_ABORT() {}
#define NS_BREAK() {}
#endif /* ! NS_DEBUG */
#endif /* nsDebug_h___ */

View 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 = public src
DIRS += tests
DIRS += tools
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,21 @@
#
# 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
DIRS=public src # tests tools
include <$(DEPTH)\config\rules.mak>

View 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) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = libxpt
EXPORTS = xpt_struct.h \
xpt_xdr.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,28 @@
#!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.
IGNORE_MANIFEST=1
DEPTH=..\..\..
EXPORTS = xpt_struct.h \
xpt_xdr.h \
$(NULL)
MODULE = libxpt
include <$(DEPTH)\config\rules.mak>

View 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* Structures matching the in-memory representation of typelib structures.
* http://www.mozilla.org/scriptable/typelib_file.html
*/
#ifndef __xpt_struct_h__
#define __xpt_struct_h__
#include "prtypes.h"
/*
* The linkage of XPT API functions differs depending on whether the file is
* used within the XPT library or not. Any source file within the XPT
* library should define EXPORT_XPT_API whereas any client of the library
* should not.
*/
#ifdef EXPORT_XPT_API
#define XPT_PUBLIC_API(t) PR_IMPLEMENT(t)
#define XPT_PUBLIC_DATA(t) PR_IMPLEMENT_DATA(t)
#else
#ifdef _WIN32
# define XPT_PUBLIC_API(t) _declspec(dllimport) t
# define XPT_PUBLIC_DATA(t) _declspec(dllimport) t
#else
# define XPT_PUBLIC_API(t) PR_IMPLEMENT(t)
# define XPT_PUBLIC_DATA(t) t
#endif
#endif
#define XPT_FRIEND_API(t) XPT_PUBLIC_API(t)
#define XPT_FRIEND_DATA(t) XPT_PUBLIC_DATA(t)
PR_BEGIN_EXTERN_C
/*
* Originally, I was going to have structures that exactly matched the on-disk
* representation, but that proved difficult: different compilers can pack
* their structs differently, and that makes overlaying them atop a
* read-from-disk byte buffer troublesome. So now I just have some structures
* that are used in memory, and we're going to write a nice XDR library to
* write them to disk and stuff. It is pure joy. -- shaver
*/
/* Structures for the typelib components */
typedef struct XPTHeader XPTHeader;
typedef struct XPTInterfaceDirectoryEntry XPTInterfaceDirectoryEntry;
typedef struct XPTInterfaceDescriptor XPTInterfaceDescriptor;
typedef struct XPTConstDescriptor XPTConstDescriptor;
typedef struct XPTMethodDescriptor XPTMethodDescriptor;
typedef struct XPTParamDescriptor XPTParamDescriptor;
typedef struct XPTTypeDescriptor XPTTypeDescriptor;
typedef struct XPTTypeDescriptorPrefix XPTTypeDescriptorPrefix;
typedef struct XPTString XPTString;
typedef struct XPTAnnotation XPTAnnotation;
#ifndef nsID_h__
/*
* We can't include nsID.h, because it's full of C++ goop and we're not doing
* C++ here, so we define our own minimal struct. We protect against multiple
* definitions of this struct, though, and use the same field naming.
*/
struct nsID {
PRUint32 m0;
PRUint16 m1;
PRUint16 m2;
PRUint8 m3[8];
};
typedef struct nsID nsID;
#endif
#define XPT_COPY_IID(to, from) \
(to).m0 = (from).m0; \
(to).m1 = (from).m1; \
(to).m2 = (from).m2; \
(to).m3[0] = (from).m3[0]; \
(to).m3[1] = (from).m3[1]; \
(to).m3[2] = (from).m3[2]; \
(to).m3[3] = (from).m3[3]; \
(to).m3[4] = (from).m3[4]; \
(to).m3[5] = (from).m3[5]; \
(to).m3[6] = (from).m3[6]; \
(to).m3[7] = (from).m3[7];
/*
* Every XPCOM typelib file begins with a header.
*/
struct XPTHeader {
char magic[16];
uint8 major_version;
uint8 minor_version;
uint16 num_interfaces;
uint32 file_length;
XPTInterfaceDirectoryEntry *interface_directory;
uint32 data_pool;
XPTAnnotation *annotations;
};
#define XPT_MAGIC "XPCOM\nTypeLib\r\n\032"
#define XPT_MAJOR_VERSION 0x01
#define XPT_MINOR_VERSION 0x00
extern XPT_PUBLIC_API(XPTHeader *)
XPT_NewHeader(uint32 num_interfaces);
/* size of header and annotations */
extern XPT_PUBLIC_API(uint32)
XPT_SizeOfHeader(XPTHeader *header);
/* size of header and annotations and InterfaceDirectoryEntries */
extern XPT_PUBLIC_API(uint32)
XPT_SizeOfHeaderBlock(XPTHeader *header);
/*
* A contiguous array of fixed-size InterfaceDirectoryEntry records begins at
* the byte offset identified by the interface_directory field in the file
* header. The array is used to quickly locate an interface description
* using its IID. No interface should appear more than once in the array.
*/
struct XPTInterfaceDirectoryEntry {
nsID iid;
char *name;
char *name_space;
XPTInterfaceDescriptor *interface_descriptor;
#if 0 /* not yet */
/* not stored on disk */
uint32 offset; /* the offset for an ID still to be read */
#endif
};
extern XPT_PUBLIC_API(PRBool)
XPT_FillInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
nsID *iid, char *name, char *name_space,
XPTInterfaceDescriptor *descriptor);
/*
* An InterfaceDescriptor is a variable-size record used to describe a
* single XPCOM interface, including all of its methods.
*/
struct XPTInterfaceDescriptor {
XPTInterfaceDirectoryEntry *parent_interface;
uint16 num_methods;
XPTMethodDescriptor *method_descriptors;
uint16 num_constants;
XPTConstDescriptor *const_descriptors;
};
extern XPT_PUBLIC_API(PRBool)
XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
uint32 num_interfaces, char *name,
uint16 *indexp);
extern XPT_PUBLIC_API(XPTInterfaceDescriptor *)
XPT_NewInterfaceDescriptor(uint32 parent_interface, uint32 num_methods,
uint32 num_constants);
extern XPT_PUBLIC_API(PRBool)
XPT_InterfaceDescriptorAddMethods(XPTInterfaceDescriptor *id, uint16 num);
/*
* This is our special string struct with a length value associated with it,
* which means that it can contains embedded NULs.
*/
struct XPTString {
uint16 length;
char *bytes;
};
extern XPT_PUBLIC_API(XPTString *)
XPT_NewString(uint16 length, char *bytes);
extern XPT_PUBLIC_API(XPTString *)
XPT_NewStringZ(char *bytes);
/*
* A TypeDescriptor is a variable-size record used to identify the type of a
* method argument or return value.
*
* There are three types of TypeDescriptors:
*
* SimpleTypeDescriptor
* InterfaceTypeDescriptor
* InterfaceIsTypeDescriptor
*
* The tag field in the prefix indicates which of the variant TypeDescriptor
* records is being used, and hence the way any remaining fields should be
* parsed. Values from 0 to 17 refer to SimpleTypeDescriptors. The value 18
* designates an InterfaceTypeDescriptor, while 19 represents an
* InterfaceIsTypeDescriptor.
*/
/* XXX why bother with a struct? */
struct XPTTypeDescriptorPrefix {
uint8 flags;
};
/* flag bits -- fur and jband were right, I was miserably wrong */
#define XPT_TDP_POINTER 0x80
#define XPT_TDP_UNIQUE_POINTER 0x40
#define XPT_TDP_REFERENCE 0x20
#define XPT_TDP_FLAGMASK 0xe0
#define XPT_TDP_TAGMASK (~XPT_TDP_FLAGMASK)
#define XPT_TDP_TAG(tdp) ((tdp).flags & XPT_TDP_TAGMASK)
#define XPT_TDP_IS_POINTER(flags) (flags & XPT_TDP_POINTER)
#define XPT_TDP_IS_UNIQUE_POINTER(flags) (flags & XPT_TDP_UNIQUE_POINTER)
#define XPT_TDP_IS_REFERENCE(flags) (flags & XPT_TDP_REFERENCE)
/* XXX TD #defines should include required flag bits! */
/*
* The following enum maps mnemonic names to the different numeric values
* of XPTTypeDescriptor->tag.
*/
enum XPTTypeDescriptorTags {
TD_INT8 = 0,
TD_INT16 = 1,
TD_INT32 = 2,
TD_INT64 = 3,
TD_UINT8 = 4,
TD_UINT16 = 5,
TD_UINT32 = 6,
TD_UINT64 = 7,
TD_FLOAT = 8,
TD_DOUBLE = 9,
TD_BOOL = 10,
TD_CHAR = 11,
TD_WCHAR = 12,
TD_VOID = 13,
TD_PNSIID = 14,
TD_PBSTR = 15,
TD_PSTRING = 16,
TD_PWSTRING = 17,
TD_INTERFACE_TYPE = 18,
TD_INTERFACE_IS_TYPE = 19
};
struct XPTTypeDescriptor {
XPTTypeDescriptorPrefix prefix;
union {
uint32 interface;
uint8 argnum;
} type;
};
#define XPT_TYPEDESCRIPTOR_SIZE (1 + 4)
#define XPT_COPY_TYPE(to, from) \
(to).prefix.flags = (from).prefix.flags; \
(to).type.interface = (from).type.interface;
/*
* A ConstDescriptor is a variable-size record that records the name and
* value of a scoped interface constant.
*
* The types of the method parameter are restricted to the following subset
* of TypeDescriptors:
*
* int8, uint8, int16, uint16, int32, uint32,
* int64, uint64, wchar_t, char, string
*
* The type (and thus the size) of the value record is determined by the
* contents of the associated TypeDescriptor record. For instance, if type
* corresponds to int16, then value is a two-byte record consisting of a
* 16-bit signed integer. For a ConstDescriptor type of string, the value
* record is of type String*, i.e. an offset within the data pool to a
* String record containing the constant string.
*/
union XPTConstValue {
int8 i8;
uint8 ui8;
int16 i16;
uint16 ui16;
int32 i32;
uint32 ui32;
int64 i64;
uint64 ui64;
float flt;
double dbl;
PRBool bul;
char ch;
uint16 wch;
nsID *iid;
XPTString *string;
char *str;
uint16 *wstr;
}; /* varies according to type */
struct XPTConstDescriptor {
char *name;
XPTTypeDescriptor type;
union XPTConstValue value;
};
/*
* A ParamDescriptor is a variable-size record used to describe either a
* single argument to a method or a method's result.
*/
struct XPTParamDescriptor {
uint8 flags;
XPTTypeDescriptor type;
};
/* flag bits -- jband and fur were right, and I was miserably wrong */
#define XPT_PD_IN 0x80
#define XPT_PD_OUT 0x40
#define XPT_PD_RETVAL 0x20
#define XPT_PD_FLAGMASK 0x70
#define XPT_PD_IS_IN(flags) (flags & XPT_PD_IN)
#define XPT_PD_IS_OUT(flags) (flags & XPT_PD_OUT)
#define XPT_PD_IS_RETVAL(flags) (flags & XPT_PD_RETVAL)
#define XPT_PARAMDESCRIPTOR_SIZE (XPT_TYPEDESCRIPTOR_SIZE + 1)
extern XPT_PUBLIC_API(PRBool)
XPT_FillParamDescriptor(XPTParamDescriptor *pd, uint8 flags,
XPTTypeDescriptor *type);
/*
* A MethodDescriptor is a variable-size record used to describe a single
* interface method.
*/
struct XPTMethodDescriptor {
uint8 flags;
char *name;
uint8 num_args;
XPTParamDescriptor *params;
XPTParamDescriptor *result;
};
/* flag bits -- jband and fur were right, and I was miserably wrong */
#define XPT_MD_GETTER 0x80
#define XPT_MD_SETTER 0x40
#define XPT_MD_VARARGS 0x20
#define XPT_MD_CTOR 0x10
#define XPT_MD_HIDDEN 0x08
#define XPT_MD_FLAGMASK 0xf8
#define XPT_MD_IS_GETTER(flags) (flags & XPT_MD_GETTER)
#define XPT_MD_IS_SETTER(flags) (flags & XPT_MD_SETTER)
#define XPT_MD_IS_VARARGS(flags) (flags & XPT_MD_VARARGS)
#define XPT_MD_IS_CTOR(flags) (flags & XPT_MD_CTOR)
#define XPT_MD_IS_HIDDEN(flags) (flags & XPT_MD_HIDDEN)
extern XPT_PUBLIC_API(PRBool)
XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, uint8 flags, char *name,
uint8 num_args);
/*
* Annotation records are variable-size records used to store secondary
* information about the typelib, e.g. such as the name of the tool that
* generated the typelib file, the date it was generated, etc. The
* information is stored with very loose format requirements so as to
* allow virtually any private data to be stored in the typelib.
*
* There are two types of Annotations:
*
* EmptyAnnotation
* PrivateAnnotation
*
* The tag field of the prefix discriminates among the variant record
* types for Annotation's. If the tag is 0, this record is an
* EmptyAnnotation. EmptyAnnotation's are ignored - they're only used to
* indicate an array of Annotation's that's completely empty. If the tag
* is 1, the record is a PrivateAnnotation.
*/
struct XPTAnnotation {
XPTAnnotation *next;
uint8 flags;
/* remaining fields are present in typelib iff XPT_ANN_IS_PRIVATE */
XPTString *creator;
XPTString *private_data;
};
#define XPT_ANN_LAST 0x80
#define XPT_ANN_IS_LAST(flags) (flags & XPT_ANN_LAST)
#define XPT_ANN_PRIVATE 0x40
#define XPT_ANN_IS_PRIVATE(flags) (flags & XPT_ANN_PRIVATE)
extern XPT_PUBLIC_API(XPTAnnotation *)
XPT_NewAnnotation(uint8 flags, XPTString *creator, XPTString *private_data);
PR_END_EXTERN_C
#endif /* __xpt_struct_h__ */

View File

@@ -0,0 +1,214 @@
/* -*- Mode: C; tab-width: 8; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* Basic APIs for streaming typelib structures to/from disk.
*/
#ifndef __xpt_xdr_h__
#define __xpt_xdr_h__
#include <nspr.h>
#include <plhash.h>
#include <prmem.h>
#include "xpt_struct.h"
PR_BEGIN_EXTERN_C
typedef struct XPTState XPTState;
typedef struct XPTDatapool XPTDatapool;
typedef struct XPTCursor XPTCursor;
extern XPT_PUBLIC_API(PRBool)
XPT_DoString(XPTCursor *cursor, XPTString **strp);
extern XPT_PUBLIC_API(PRBool)
XPT_DoStringInline(XPTCursor *cursor, XPTString **strp);
extern XPT_PUBLIC_API(PRBool)
XPT_DoCString(XPTCursor *cursor, char **strp);
extern XPT_PUBLIC_API(PRBool)
XPT_DoIdentifier(XPTCursor *cursor, char **identp);
extern XPT_PUBLIC_API(PRBool)
XPT_DoIID(XPTCursor *cursor, nsID *iidp);
extern XPT_PUBLIC_API(PRBool)
XPT_Do64(XPTCursor *cursor, PRInt64 *u64p);
extern XPT_PUBLIC_API(PRBool)
XPT_Do32(XPTCursor *cursor, uint32 *u32p);
extern XPT_PUBLIC_API(PRBool)
XPT_Do16(XPTCursor *cursor, uint16 *u16p);
extern XPT_PUBLIC_API(PRBool)
XPT_Do8(XPTCursor *cursor, uint8 *u8p);
/*
* When working with bitfields, use the DoBits call with a uint8.
* Only the appropriate number of bits are manipulated, so when
* you're decoding you probably want to ensure that the uint8 is pre-zeroed.
* When you're done sending bits along, use
* XPT_FlushBits to make sure that you don't eat a leading bit from the
* next structure. (You should probably be writing full bytes' worth of bits
* anyway, and zeroing out the bits you don't use, but just to be sure...)
*/
extern XPT_PUBLIC_API(PRBool)
XPT_DoBits(XPTCursor *cursor, uint8 *u8p, int nbits);
#define XPT_DO_BITS(curs, field, width, scr) (PR_TRUE)
/* returns the number of bits skipped, which should be 0-7 */
extern XPT_PUBLIC_API(int)
XPT_FlushBits(XPTCursor *cursor);
extern XPT_PUBLIC_API(PRBool)
XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp);
typedef enum {
XPT_ENCODE,
XPT_DECODE
} XPTMode;
typedef enum {
XPT_HEADER = 0,
XPT_DATA = 1
} XPTPool;
struct XPTState {
XPTMode mode;
uint32 data_offset;
uint32 next_cursor[2];
XPTDatapool *pool;
};
struct XPTDatapool {
PLHashTable *offset_map;
char *data;
uint32 count;
uint32 allocated;
};
struct XPTCursor {
XPTState *state;
XPTPool pool;
uint32 offset;
uint8 bits;
};
extern XPT_PUBLIC_API(XPTState *)
XPT_NewXDRState(XPTMode mode, char *data, uint32 len);
extern XPT_PUBLIC_API(PRBool)
XPT_MakeCursor(XPTState *state, XPTPool pool, uint32 len, XPTCursor *cursor);
extern XPT_PUBLIC_API(PRBool)
XPT_SeekTo(XPTCursor *cursor, uint32 offset);
extern XPT_PUBLIC_API(void)
XPT_DestroyXDRState(XPTState *state);
/* Set file_length based on the data used in the state. (Only ENCODE.) */
extern XPT_PUBLIC_API(PRBool)
XPT_UpdateFileLength(XPTState *state);
extern XPT_PUBLIC_API(void)
XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, uint32 *len);
/* set or get the data offset for the state, depending on mode */
extern XPT_PUBLIC_API(void)
XPT_DataOffset(XPTState *state, uint32 *data_offsetp);
extern XPT_PUBLIC_API(void)
XPT_SetDataOffset(XPTState *state, uint32 data_offset);
extern XPT_PUBLIC_API(uint32)
XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr);
extern XPT_PUBLIC_API(PRBool)
XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, uint32 offset);
extern XPT_PUBLIC_API(PRBool)
XPT_SetAddrForOffset(XPTCursor *cursor, uint32 offset, void *addr);
extern XPT_PUBLIC_API(void *)
XPT_GetAddrForOffset(XPTCursor *cursor, uint32 offset);
/* all data structures are big-endian */
#if defined IS_BIG_ENDIAN
# define XPT_SWAB32(x) x
# define XPT_SWAB16(x) x
#elif defined IS_LITTLE_ENDIAN
# define XPT_SWAB32(x) (((x) >> 24) | \
(((x) >> 8) & 0xff00) | \
(((x) << 8) & 0xff0000) | \
((x) << 24))
# define XPT_SWAB16(x) (((x) >> 8) | ((x) << 8))
#else
# error "unknown byte order"
#endif
/*
* If we're decoding, we want to read the offset before we check
* for already-decoded values.
*
* Then we check for repetition: CheckForRepeat will see if we've already
* encoded/decoded this value, and if so will set offset/addr correctly
* and make already be true. If not, it will set up the cursor for
* encoding (reserve space) or decoding (seek to correct location) as
* appropriate. In the encode case, it will also set the addr->offset
* mapping.
*/
#define XPT_PREAMBLE_(cursor, addrp, pool, size, new_curs, already) \
XPTMode mode = cursor->state->mode; \
if (!(mode == XPT_ENCODE || XPT_Do32(cursor, &new_curs.offset)) || \
!CheckForRepeat(cursor, (void **)addrp, pool, \
mode == XPT_ENCODE ? size : 0, &new_curs, \
&already) || \
!(mode == XPT_DECODE || XPT_Do32(cursor, &new_curs.offset))) \
return PR_FALSE; \
if (already) \
return PR_TRUE; \
#define XPT_PREAMBLE(cursor, addrp, pool, size, new_curs, already, \
XPTType, localp) \
{ \
XPT_PREAMBLE_(cursor, addrp, pool, size, new_curs, already); \
XPT_ALLOC(addrp, new_curs, XPTType, localp) \
}
#define XPT_PREAMBLE_NO_ALLOC(cursor, addrp, pool, size, new_curs, already) \
{ \
XPT_PREAMBLE_(cursor, addrp, pool, size, new_curs, already) \
}
#define XPT_ERROR_HANDLE(free_it) \
error: \
if (cursor->state->mode == XPT_DECODE) \
PR_FREEIF(free_it); \
return PR_FALSE;
PR_END_EXTERN_C
#endif /* __xpt_xdr_h__ */

View File

@@ -0,0 +1,33 @@
#!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@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = libxpt
LIBRARY_NAME = xpt
CSRCS = xpt_struct.c \
xpt_xdr.c \
$(NULL)
REQUIRES = $(MODULE)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,52 @@
#!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.
IGNORE_MANIFEST=1
MAKE_OBJ_TYPE = DLL
DEPTH=..\..\..
LIBNAME = .\$(OBJDIR)\libxpt$(MOZ_BITS)
DLL = $(LIBNAME).dll
LCFLAGS = -DEXPORT_XPT_API -DWIN32_LEAN_AND_MEAN
LINCS = \
-I$(PUBLIC)\libxpt \
$(NULL)
LLIBS = $(LIBNSPR) \
$(NULL)
CSRCS = \
xpt_struct.c \
xpt_xdr.c \
$(NULL)
C_OBJS = \
.\$(OBJDIR)\xpt_struct.obj \
.\$(OBJDIR)\xpt_xdr.obj \
$(NULL)
MODULE = libxpt
include <$(DEPTH)\config\rules.mak>
libs:: $(DLL)
$(MAKE_INSTALL) $(LIBNAME).$(DLL_SUFFIX) $(DIST)\bin
$(MAKE_INSTALL) $(LIBNAME).$(LIB_SUFFIX) $(DIST)\lib

View File

@@ -0,0 +1,727 @@
/* -*- Mode: C; tab-width: 8; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* Implementation of XDR routines for typelib structures. */
#include "xpt_xdr.h"
#include "xpt_struct.h"
#include <string.h>
static PRBool
DoInterfaceDirectoryEntry(XPTCursor *cursor,
XPTInterfaceDirectoryEntry *ide, uint16 index);
static PRBool
DoInterfaceDirectoryEntryIndex(XPTCursor *cursor,
XPTInterfaceDirectoryEntry **idep);
static PRBool
DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor *cd);
static PRBool
DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor *md);
static PRBool
DoAnnotation(XPTCursor *cursor, XPTAnnotation **annp);
static PRBool
DoInterfaceDescriptor(XPTCursor *outer, XPTInterfaceDescriptor **idp);
static PRBool
DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor *td);
static PRBool
DoParamDescriptor(XPTCursor *cursor, XPTParamDescriptor *pd);
#define CURS_POOL_OFFSET_RAW(cursor) \
((cursor)->pool == XPT_HEADER \
? (cursor)->offset \
: (PR_ASSERT((cursor)->state->data_offset), \
(cursor)->offset + (cursor)->state->data_offset))
#define CURS_POOL_OFFSET(cursor) \
(CURS_POOL_OFFSET_RAW(cursor) - 1)
XPT_PUBLIC_API(uint32)
XPT_SizeOfHeader(XPTHeader *header)
{
XPTAnnotation *ann, *last;
uint32 size = 16 /* magic */ +
1 /* major */ + 1 /* minor */ +
2 /* num_interfaces */ + 4 /* file_length */ +
4 /* interface_directory */ + 4 /* data_pool */;
ann = header->annotations;
do {
size += 1; /* Annotation prefix */
if (XPT_ANN_IS_PRIVATE(ann->flags))
size += 2 + ann->creator->length + 2 + ann->private_data->length;
last = ann;
ann = ann->next;
} while (!XPT_ANN_IS_LAST(last->flags));
return size;
}
XPT_PUBLIC_API(uint32)
XPT_SizeOfHeaderBlock(XPTHeader *header)
{
uint32 size = XPT_SizeOfHeader(header);
size += header->num_interfaces * sizeof (XPTInterfaceDirectoryEntry);
return size;
}
XPT_PUBLIC_API(XPTHeader *)
XPT_NewHeader(uint32 num_interfaces)
{
XPTHeader *header = PR_NEWZAP(XPTHeader);
if (!header)
return NULL;
memcpy(header->magic, XPT_MAGIC, 16);
header->major_version = XPT_MAJOR_VERSION;
header->minor_version = XPT_MINOR_VERSION;
header->num_interfaces = num_interfaces;
header->interface_directory = PR_CALLOC(num_interfaces *
sizeof(XPTInterfaceDirectoryEntry));
if (!header->interface_directory) {
PR_DELETE(header);
return NULL;
}
header->data_pool = 0; /* XXX do we even need this struct any more? */
return header;
}
XPT_PUBLIC_API(PRBool)
XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
{
XPTMode mode = cursor->state->mode;
XPTHeader *header;
uint32 ide_offset;
int i;
if (mode == XPT_DECODE) {
header = PR_NEWZAP(XPTHeader);
if (!header)
return PR_FALSE;
*headerp = header;
} else {
header = *headerp;
}
if (mode == XPT_ENCODE) {
/* IDEs appear after header, including annotations */
ide_offset = XPT_SizeOfHeader(*headerp) + 1; /* one-based offset */
header->data_pool = XPT_SizeOfHeaderBlock(*headerp);
XPT_SetDataOffset(cursor->state, header->data_pool);
}
for (i = 0; i < 16; i++) {
if (!XPT_Do8(cursor, &header->magic[i]))
goto error;
}
if(!XPT_Do8(cursor, &header->major_version) ||
!XPT_Do8(cursor, &header->minor_version) ||
/* XXX check major for compat! */
!XPT_Do16(cursor, &header->num_interfaces) ||
!XPT_Do32(cursor, &header->file_length) ||
!XPT_Do32(cursor, &ide_offset)) {
goto error;
}
if (mode == XPT_ENCODE)
XPT_DataOffset(cursor->state, &header->data_pool);
if (!XPT_Do32(cursor, &header->data_pool))
goto error;
if (mode == XPT_DECODE)
XPT_DataOffset(cursor->state, &header->data_pool);
if (mode == XPT_DECODE) {
header->interface_directory =
PR_CALLOC(header->num_interfaces *
sizeof(XPTInterfaceDirectoryEntry));
if (!header->interface_directory)
goto error;
}
if (!DoAnnotation(cursor, &header->annotations))
goto error;
/* shouldn't be necessary now, but maybe later */
XPT_SeekTo(cursor, ide_offset);
for (i = 0; i < header->num_interfaces; i++) {
if (!DoInterfaceDirectoryEntry(cursor,
&header->interface_directory[i],
i + 1))
goto error;
}
return PR_TRUE;
/* XXX need to free child data sometimes! */
XPT_ERROR_HANDLE(header);
}
XPT_PUBLIC_API(PRBool)
XPT_FillInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
nsID *iid, char *name, char *name_space,
XPTInterfaceDescriptor *descriptor)
{
XPT_COPY_IID(ide->iid, *iid);
ide->name = name ? strdup(name) : NULL; /* what good is it w/o a name? */
ide->name_space = name_space ? strdup(name_space) : NULL;
ide->interface_descriptor = descriptor;
return PR_TRUE;
}
/* InterfaceDirectoryEntry records go in the header */
PRBool
DoInterfaceDirectoryEntry(XPTCursor *cursor,
XPTInterfaceDirectoryEntry *ide, uint16 index)
{
XPTMode mode = cursor->state->mode;
/* write the IID in our cursor space */
if (!XPT_DoIID(cursor, &(ide->iid)) ||
/* write the name string in the data pool, and the offset in our
cursor space */
!XPT_DoCString(cursor, &(ide->name)) ||
/* write the name_space string in the data pool, and the offset in our
cursor space */
!XPT_DoCString(cursor, &(ide->name_space)) ||
/* do InterfaceDescriptors -- later, only on encode (see below) */
!DoInterfaceDescriptor(cursor, &ide->interface_descriptor)) {
goto error;
}
if (mode == XPT_DECODE)
XPT_SetOffsetForAddr(cursor, ide, index);
#if 0 /* not yet -- we eagerly load for now */
/* write the InterfaceDescriptor in the data pool, and the offset
in our cursor space, but only if we're encoding. */
if (mode == XPT_ENCODE) {
if (!DoInterfaceDescriptor(cursor,
&ide->interface_descriptor)) {
goto error;
}
}
#endif
return PR_TRUE;
XPT_ERROR_HANDLE(ide);
}
/*
* Decode: Get the interface directory entry for the on-disk index.
* Encode: Write the index.
*/
PRBool
DoInterfaceDirectoryEntryIndex(XPTCursor *cursor,
XPTInterfaceDirectoryEntry **idep)
{
XPTMode mode = cursor->state->mode;
uint16 index;
if (mode == XPT_ENCODE) {
/* XXX index zero is legal, so how do I detect an error? */
if (*idep) {
index = XPT_GetOffsetForAddr(cursor, *idep);
if (!index)
return PR_FALSE;
} else {
index = 0; /* no interface */
}
}
if (!XPT_Do16(cursor, &index))
return PR_FALSE;
if (mode == XPT_DECODE) {
if (index) {
*idep = XPT_GetAddrForOffset(cursor, index);
if (!*idep)
return PR_FALSE;
} else {
*idep = NULL;
}
}
return PR_TRUE;
}
XPT_PUBLIC_API(XPTInterfaceDescriptor *)
XPT_NewInterfaceDescriptor(uint32 parent_interface, uint32 num_methods,
uint32 num_constants)
{
XPTInterfaceDescriptor *id = PR_NEWZAP(XPTInterfaceDescriptor);
if (!id)
return NULL;
if (num_methods) {
id->method_descriptors = PR_CALLOC(num_methods *
sizeof(XPTMethodDescriptor));
if (!id->method_descriptors)
goto free_id;
id->num_methods = num_methods;
}
if (num_constants) {
id->const_descriptors = PR_CALLOC(num_constants *
sizeof(XPTConstDescriptor));
if (!id->const_descriptors)
goto free_meth;
id->num_constants = num_constants;
}
return id;
free_meth:
PR_FREEIF(id->method_descriptors);
free_id:
PR_DELETE(id);
return NULL;
}
XPT_PUBLIC_API(PRBool)
XPT_InterfaceDescriptorAddMethods(XPTInterfaceDescriptor *id, uint16 num)
{
XPTMethodDescriptor *old = id->method_descriptors, *new;
/* XXX should grow in chunks to minimize realloc overhead */
new = PR_REALLOC(old,
(id->num_methods + num) * sizeof(XPTMethodDescriptor));
if (!new)
return PR_FALSE;
memset(id->method_descriptors + id->num_methods, 0,
sizeof(XPTMethodDescriptor) * num);
id->method_descriptors = new;
id->num_methods += num;
return PR_TRUE;
}
XPT_PUBLIC_API(uint32)
XPT_SizeOfTypeDescriptor(XPTTypeDescriptor *td)
{
uint32 size = 1; /* prefix */
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE)
size += 2; /* interface_index */
else if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE)
size += 1; /* arg_num */
return size;
}
XPT_PUBLIC_API(uint32)
XPT_SizeOfMethodDescriptor(XPTMethodDescriptor *md)
{
uint32 i, size = 1 /* flags */ + 4 /* name */ + 1 /* num_args */;
for (i = 0; i < md->num_args; i++)
size += 1 + XPT_SizeOfTypeDescriptor(&md->params[i].type);
size += 1 + XPT_SizeOfTypeDescriptor(&md->result->type);
return size;
}
XPT_PUBLIC_API(uint32)
XPT_SizeOfConstDescriptor(XPTConstDescriptor *cd)
{
uint32 size = 4 /* name */ + XPT_SizeOfTypeDescriptor(&cd->type);
switch (XPT_TDP_TAG(cd->type.prefix)) {
case TD_INT8:
case TD_UINT8:
case TD_CHAR:
size ++;
break;
case TD_INT16:
case TD_UINT16:
case TD_WCHAR:
size += 2;
break;
case TD_INT32:
case TD_UINT32:
case TD_PBSTR: /* XXX check for pointer! */
size += 4;
break;
case TD_INT64:
case TD_UINT64:
size += 8;
break;
default:
fprintf(stderr, "libxpt: illegal type in ConstDescriptor: 0x%02x\n",
XPT_TDP_TAG(cd->type.prefix));
return 0;
}
return size;
}
XPT_PUBLIC_API(uint32)
XPT_SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *id)
{
uint32 size = 2 /* parent interface */ + 2 /* num_methods */
+ 2 /* num_constants */, i;
for (i = 0; i < id->num_methods; i++)
size += XPT_SizeOfMethodDescriptor(&id->method_descriptors[i]);
for (i = 0; i < id->num_constants; i++)
size += XPT_SizeOfConstDescriptor(&id->const_descriptors[i]);
return size;
}
PRBool
DoInterfaceDescriptor(XPTCursor *outer, XPTInterfaceDescriptor **idp)
{
XPTMode mode = outer->state->mode;
XPTInterfaceDescriptor *id;
XPTCursor curs, *cursor = &curs;
uint32 i, id_sz = 0;
if (mode == XPT_DECODE) {
id = PR_NEWZAP(XPTInterfaceDescriptor);
if (!id)
return PR_FALSE;
*idp = id;
} else {
id = *idp;
if (!id) {
id_sz = 0;
return XPT_Do32(outer, &id_sz);
}
id_sz = XPT_SizeOfInterfaceDescriptor(id);
}
if (!XPT_MakeCursor(outer->state, XPT_DATA, id_sz, cursor))
goto error;
if (!XPT_Do32(outer, &cursor->offset))
goto error;
if (mode == XPT_DECODE && !cursor->offset) {
*idp = NULL;
return PR_TRUE;
}
if(!DoInterfaceDirectoryEntryIndex(cursor, &id->parent_interface) ||
!XPT_Do16(cursor, &id->num_methods)) {
goto error;
}
if (mode == XPT_DECODE && id->num_methods) {
id->method_descriptors = PR_CALLOC(id->num_methods *
sizeof(XPTMethodDescriptor));
if (!id->method_descriptors)
goto error;
}
for (i = 0; i < id->num_methods; i++) {
if (!DoMethodDescriptor(cursor, &id->method_descriptors[i]))
goto error;
}
if (!XPT_Do16(cursor, &id->num_constants)) {
goto error;
}
if (mode == XPT_DECODE)
id->const_descriptors = PR_CALLOC(id->num_constants *
sizeof(XPTConstDescriptor));
for (i = 0; i < id->num_constants; i++) {
if (!DoConstDescriptor(cursor, &id->const_descriptors[i])) {
goto error;
}
}
return PR_TRUE;
XPT_ERROR_HANDLE(id);
}
XPT_PUBLIC_API(PRBool)
XPT_FillConstDescriptor(XPTConstDescriptor *cd, char *name,
XPTTypeDescriptor type, union XPTConstValue value)
{
cd->name = strdup(name);
if (!cd->name)
return PR_FALSE;
XPT_COPY_TYPE(cd->type, type);
/* XXX copy value */
return PR_TRUE;
}
PRBool
DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor *cd)
{
PRBool ok = PR_FALSE;
if (!XPT_DoCString(cursor, &cd->name) ||
!DoTypeDescriptor(cursor, &cd->type)) {
return PR_FALSE;
}
switch(XPT_TDP_TAG(cd->type.prefix)) {
case TD_INT8:
ok = XPT_Do8(cursor, &cd->value.i8);
break;
case TD_INT16:
ok = XPT_Do16(cursor, &cd->value.i16);
break;
case TD_INT32:
ok = XPT_Do32(cursor, &cd->value.i32);
break;
case TD_INT64:
ok = XPT_Do64(cursor, &cd->value.i64);
break;
case TD_UINT8:
ok = XPT_Do8(cursor, &cd->value.ui8);
break;
case TD_UINT16:
ok = XPT_Do16(cursor, &cd->value.ui16);
break;
case TD_UINT32:
ok = XPT_Do32(cursor, &cd->value.ui32);
break;
case TD_UINT64:
ok = XPT_Do64(cursor, &cd->value.ui64);
break;
case TD_CHAR:
ok = XPT_Do8(cursor, &cd->value.ch);
break;
case TD_WCHAR:
ok = XPT_Do16(cursor, &cd->value.wch);
break;
case TD_PBSTR:
if (cd->type.prefix.flags & XPT_TDP_POINTER) {
ok = XPT_DoString(cursor, &cd->value.string);
break;
}
/* fall-through */
default:
fprintf(stderr, "illegal type!\n");
break;
}
return ok;
}
XPT_PUBLIC_API(PRBool)
XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, uint8 flags, char *name,
uint8 num_args)
{
meth->flags = flags & XPT_MD_FLAGMASK;
meth->name = strdup(name);
if (!name)
return PR_FALSE;
meth->num_args = num_args;
if (meth->num_args) {
meth->params = PR_CALLOC(num_args * sizeof(XPTParamDescriptor));
if (!meth->params)
goto free_name;
} else {
meth->params = NULL;
}
meth->result = PR_NEWZAP(XPTParamDescriptor);
if (!meth->result)
goto free_params;
return PR_TRUE;
free_params:
PR_DELETE(meth->params);
free_name:
PR_DELETE(meth->name);
return PR_FALSE;
}
PRBool
DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor *md)
{
XPTMode mode = cursor->state->mode;
int i;
if (!XPT_Do8(cursor, &md->flags) ||
!XPT_DoCString(cursor, &md->name) ||
!XPT_Do8(cursor, &md->num_args))
return PR_FALSE;
if (mode == XPT_DECODE && md->num_args) {
md->params = PR_CALLOC(md->num_args * sizeof(XPTParamDescriptor));
if (!md->params)
return PR_FALSE;
}
for(i = 0; i < md->num_args; i++) {
if (!DoParamDescriptor(cursor, &md->params[i]))
goto error;
}
md->result = PR_NEWZAP(XPTParamDescriptor);
if (!md->result ||
!DoParamDescriptor(cursor, md->result))
goto error;
return PR_TRUE;
XPT_ERROR_HANDLE(md->params);
}
XPT_PUBLIC_API(PRBool)
XPT_FillParamDescriptor(XPTParamDescriptor *pd, uint8 flags,
XPTTypeDescriptor *type)
{
pd->flags = flags & XPT_PD_FLAGMASK;
XPT_COPY_TYPE(pd->type, *type);
return PR_TRUE;
}
PRBool
DoParamDescriptor(XPTCursor *cursor, XPTParamDescriptor *pd)
{
if (!XPT_Do8(cursor, &pd->flags) ||
!DoTypeDescriptor(cursor, &pd->type))
return PR_FALSE;
return PR_TRUE;
}
/* XXX when we lose the useless TDP wrapper struct, #define this to Do8 */
PRBool
DoTypeDescriptorPrefix(XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp)
{
return XPT_Do8(cursor, &tdp->flags);
}
PRBool
DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor *td)
{
if (!DoTypeDescriptorPrefix(cursor, &td->prefix)) {
goto error;
}
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
if (!XPT_Do32(cursor, &td->type.interface))
goto error;
} else {
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE) {
if (!XPT_Do8(cursor, &td->type.argnum))
goto error;
}
}
return PR_TRUE;
XPT_ERROR_HANDLE(td);
}
XPT_PUBLIC_API(XPTAnnotation *)
XPT_NewAnnotation(uint8 flags, XPTString *creator, XPTString *private_data)
{
XPTAnnotation *ann = PR_NEWZAP(XPTAnnotation);
if (!ann)
return NULL;
ann->flags = flags;
if (XPT_ANN_IS_PRIVATE(flags)) {
ann->creator = creator;
ann->private_data = private_data;
}
return ann;
}
PRBool
DoAnnotation(XPTCursor *cursor, XPTAnnotation **annp)
{
XPTMode mode = cursor->state->mode;
XPTAnnotation *ann;
if (mode == XPT_DECODE) {
ann = PR_NEWZAP(XPTAnnotation);
if (!ann)
return PR_FALSE;
*annp = ann;
} else {
ann = *annp;
}
if (!XPT_Do8(cursor, &ann->flags))
goto error;
if (XPT_ANN_IS_PRIVATE(ann->flags)) {
if (!XPT_DoStringInline(cursor, &ann->creator) ||
!XPT_DoStringInline(cursor, &ann->private_data))
goto error_2;
}
/*
* If a subsequent Annotation fails, what to do?
* - free all annotations, return PR_FALSE? (current behaviout)
* - free failed annotation only, return PR_FALSE (caller can check for
* non-NULL *annp on PR_FALSE return to detect partial annotation
* decoding)?
*/
if (!XPT_ANN_IS_LAST(ann->flags) &&
!DoAnnotation(cursor, &ann->next))
goto error_2;
return PR_TRUE;
error_2:
if (ann && XPT_ANN_IS_PRIVATE(ann->flags)) {
PR_FREEIF(ann->creator);
PR_FREEIF(ann->private_data);
}
XPT_ERROR_HANDLE(ann);
}
PRBool
XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
uint32 num_interfaces, char *name,
uint16 *indexp)
{
int i;
for (i=1; i<=num_interfaces; i++) {
fprintf(stderr, "%s == %s ?\n", ide_block[i].name, name);
if (strcmp(ide_block[i].name, name) == 0) {
*indexp = i;
return PR_TRUE;
}
}
indexp = 0;
return PR_FALSE;
}
#if 0 /* need hashtables and stuff */
XPT_PUBLIC_API(XPTInterfaceDescriptor *)
XPT_GetDescriptorByIndex(XPTCursor *cursor, XPTHeader *header, uint16 index)
{
XPTInterfaceDescriptor *id = header->interface_directory + index;
if (id)
return id; /* XXX refcnt? */
/* XXX lazily load and allocate later, for now we always read them all
in */
return id;
}
#endif

View File

@@ -0,0 +1,600 @@
/* -*- Mode: C; tab-width: 8; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* Implementation of XDR primitives. */
#include "xpt_xdr.h"
#include <nspr.h>
#include <string.h> /* strchr */
static PRBool
CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, int len,
XPTCursor *new_cursor, PRBool *already);
#define ENCODING(cursor) \
((cursor)->state->mode == XPT_ENCODE)
#define CURS_POOL_OFFSET_RAW(cursor) \
((cursor)->pool == XPT_HEADER \
? (cursor)->offset \
: (PR_ASSERT((cursor)->state->data_offset), \
(cursor)->offset + (cursor)->state->data_offset))
#define CURS_POOL_OFFSET(cursor) \
(CURS_POOL_OFFSET_RAW(cursor) - 1)
/* can be used as lvalue */
#define CURS_POINT(cursor) \
((cursor)->state->pool->data[CURS_POOL_OFFSET(cursor)])
#ifdef DEBUG_shaver
#define DBG(x) printf##x
#else
#define DBG(x) (0)
#endif
/* XXX fail if XPT_DATA and !state->data_offset */
#define CHECK_COUNT_(cursor, space) \
/* if we're in the header, then exceeding the data_offset is illegal */ \
((cursor)->pool == XPT_HEADER ? \
(ENCODING(cursor) && \
((cursor)->state->data_offset && \
((cursor)->offset - 1 + (space) > (cursor)->state->data_offset)) \
? (DBG(("no space left in HEADER %d + %d > %d\n", (cursor)->offset, \
(space), (cursor)->state->data_offset)), PR_FALSE) \
: PR_TRUE) : \
/* if we're in the data area and we're about to exceed the allocation */ \
(CURS_POOL_OFFSET(cursor) + (space) > (cursor)->state->pool->allocated ? \
/* then grow if we're in ENCODE mode */ \
(ENCODING(cursor) ? GrowPool((cursor)->state->pool) \
/* and fail if we're in DECODE mode */ \
: (DBG(("can't extend in DECODE")), PR_FALSE)) \
/* otherwise we're OK */ \
: PR_TRUE))
#define CHECK_COUNT(cursor, space) \
(CHECK_COUNT_(cursor, space) \
? PR_TRUE \
: (PR_ASSERT(0), \
fprintf(stderr, "FATAL: can't no room for %d in cursor\n", space), \
PR_FALSE))
/* increase the data allocation for the pool by XPT_GROW_CHUNK */
#define XPT_GROW_CHUNK 8192
static PLHashNumber
null_hash(const void *key)
{
return (PLHashNumber)key;
}
XPT_PUBLIC_API(XPTState *)
XPT_NewXDRState(XPTMode mode, char *data, uint32 len)
{
XPTState *state;
state = PR_NEW(XPTState);
if (!state)
return NULL;
state->mode = mode;
state->pool = PR_NEW(XPTDatapool);
state->next_cursor[0] = state->next_cursor[1] = 1;
if (!state->pool)
goto err_free_state;
state->pool->count = 0;
state->pool->offset_map = PL_NewHashTable(32, null_hash, PL_CompareValues,
PL_CompareValues, NULL, NULL);
if (!state->pool->offset_map)
goto err_free_pool;
if (mode == XPT_DECODE) {
state->pool->data = data;
state->pool->allocated = len;
} else {
state->pool->data = PR_MALLOC(XPT_GROW_CHUNK);
if (!state->pool->data)
goto err_free_hash;
state->pool->allocated = XPT_GROW_CHUNK;
}
return state;
err_free_hash:
PL_HashTableDestroy(state->pool->offset_map);
err_free_pool:
PR_DELETE(state->pool);
err_free_state:
PR_DELETE(state);
return NULL;
}
XPT_PUBLIC_API(void)
XPT_DestroyXDRState(XPTState *state)
{
if (state->mode == XPT_ENCODE)
PR_DELETE(state->pool->data);
PR_DELETE(state->pool);
PR_DELETE(state);
}
XPT_PUBLIC_API(void)
XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, uint32 *len)
{
if (pool == XPT_HEADER) {
*data = state->pool->data;
} else {
*data = state->pool->data + state->data_offset;
}
*len = state->next_cursor[pool] - 1;
}
/* All offsets are 1-based */
XPT_PUBLIC_API(void)
XPT_DataOffset(XPTState *state, uint32 *data_offsetp)
{
if (state->mode == XPT_DECODE)
XPT_SetDataOffset(state, *data_offsetp);
else
*data_offsetp = state->data_offset;
}
XPT_PUBLIC_API(void)
XPT_SetDataOffset(XPTState *state, uint32 data_offset)
{
state->data_offset = data_offset;
}
static PRBool
GrowPool(XPTDatapool *pool)
{
char *newdata = realloc(pool->data, pool->allocated + XPT_GROW_CHUNK);
if (!newdata)
return PR_FALSE;
pool->data = newdata;
pool->allocated += XPT_GROW_CHUNK;
return PR_TRUE;
}
XPT_PUBLIC_API(PRBool)
XPT_MakeCursor(XPTState *state, XPTPool pool, uint32 len, XPTCursor *cursor)
{
cursor->state = state;
cursor->pool = pool;
cursor->bits = 0;
cursor->offset = state->next_cursor[pool];
if (!CHECK_COUNT(cursor, len))
return PR_FALSE;
/* this check should be in CHECK_CURSOR */
if (pool == XPT_DATA && !state->data_offset) {
fprintf(stderr, "no data offset for XPT_DATA cursor!\n");
return PR_FALSE;
}
state->next_cursor[pool] += len;
return PR_TRUE;
}
XPT_PUBLIC_API(PRBool)
XPT_SeekTo(XPTCursor *cursor, uint32 offset)
{
/* XXX do some real checking and update len and stuff */
cursor->offset = offset;
return PR_TRUE;
}
XPT_PUBLIC_API(XPTString *)
XPT_NewString(uint16 length, char *bytes)
{
XPTString *str = PR_NEW(XPTString);
if (!str)
return NULL;
str->length = length;
str->bytes = malloc(length);
if (!str->bytes) {
PR_DELETE(str);
return NULL;
}
memcpy(str->bytes, bytes, length);
return str;
}
XPT_PUBLIC_API(XPTString *)
XPT_NewStringZ(char *bytes)
{
uint32 length = strlen(bytes);
if (length > 0xffff)
return NULL; /* too long */
return XPT_NewString((uint16)length, bytes);
}
XPT_PUBLIC_API(PRBool)
XPT_DoStringInline(XPTCursor *cursor, XPTString **strp)
{
XPTString *str = *strp;
XPTMode mode = cursor->state->mode;
int i;
if (mode == XPT_DECODE) {
str = PR_NEWZAP(XPTString);
if (!str)
return PR_FALSE;
*strp = str;
}
if (!XPT_Do16(cursor, &str->length))
goto error;
if (mode == XPT_DECODE)
if (!(str->bytes = malloc(str->length + 1)))
goto error;
for (i = 0; i < str->length; i++)
if (!XPT_Do8(cursor, &str->bytes[i]))
goto error_2;
if (mode == XPT_DECODE)
str->bytes[str->length] = 0;
return PR_TRUE;
error_2:
PR_DELETE(str->bytes);
error:
PR_DELETE(str);
return PR_FALSE;
}
XPT_PUBLIC_API(PRBool)
XPT_DoString(XPTCursor *cursor, XPTString **strp)
{
XPTCursor my_cursor;
XPTString *str = *strp;
PRBool already;
XPT_PREAMBLE_NO_ALLOC(cursor, strp, XPT_DATA, str->length + 2, my_cursor,
already);
return XPT_DoStringInline(&my_cursor, strp);
}
XPT_PUBLIC_API(PRBool)
XPT_DoCString(XPTCursor *cursor, char **identp)
{
XPTCursor my_cursor;
char *ident = *identp;
uint32 offset = 0;
XPTMode mode = cursor->state->mode;
if (mode == XPT_DECODE) {
char *start, *end;
int len;
if (!XPT_Do32(cursor, &offset))
return PR_FALSE;
if (!offset) {
*identp = NULL;
return PR_TRUE;
}
my_cursor.pool = XPT_DATA;
my_cursor.offset = offset;
my_cursor.state = cursor->state;
start = &CURS_POINT(&my_cursor);
end = strchr(start, 0); /* find the end of the string */
if (!end) {
fprintf(stderr, "didn't find end of string on decode!\n");
return PR_FALSE;
}
len = end - start;
ident = PR_MALLOC(len + 1);
if (!ident)
return PR_FALSE;
memcpy(ident, start, len);
ident[len] = 0;
*identp = ident;
} else {
if (!ident) {
offset = 0;
if (!XPT_Do32(cursor, &offset))
return PR_FALSE;
return PR_TRUE;
}
if (!XPT_MakeCursor(cursor->state, XPT_DATA, strlen(ident) + 1,
&my_cursor) ||
!XPT_Do32(cursor, &my_cursor.offset))
return PR_FALSE;
while(*ident)
if (!XPT_Do8(&my_cursor, ident++))
return PR_FALSE;
if (!XPT_Do8(&my_cursor, ident)) /* write trailing zero */
return PR_FALSE;
}
return PR_TRUE;
}
XPT_PUBLIC_API(uint32)
XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr)
{
return (uint32)PL_HashTableLookup(cursor->state->pool->offset_map, addr);
}
XPT_PUBLIC_API(PRBool)
XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, uint32 offset)
{
return PL_HashTableAdd(cursor->state->pool->offset_map,
addr, (void *)offset) != NULL;
}
XPT_PUBLIC_API(PRBool)
XPT_SetAddrForOffset(XPTCursor *cursor, uint32 offset, void *addr)
{
return PL_HashTableAdd(cursor->state->pool->offset_map,
(void *)offset, addr) != NULL;
}
XPT_PUBLIC_API(void *)
XPT_GetAddrForOffset(XPTCursor *cursor, uint32 offset)
{
return PL_HashTableLookup(cursor->state->pool->offset_map, (void *)offset);
}
static PRBool
CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, int len,
XPTCursor *new_cursor, PRBool *already)
{
void *last = *addrp;
*already = PR_FALSE;
new_cursor->state = cursor->state;
new_cursor->pool = pool;
new_cursor->bits = 0;
if (cursor->state->mode == XPT_DECODE) {
last = XPT_GetAddrForOffset(new_cursor, new_cursor->offset);
if (last) {
*already = PR_TRUE;
*addrp = last;
}
} else {
new_cursor->offset = XPT_GetOffsetForAddr(new_cursor, last);
if (new_cursor->offset) {
*already = PR_TRUE;
return PR_TRUE;
}
/* haven't already found it, so allocate room for it. */
if (!XPT_MakeCursor(cursor->state, pool, len, new_cursor) ||
!XPT_SetOffsetForAddr(new_cursor, *addrp, new_cursor->offset))
return PR_FALSE;
}
return PR_TRUE;
}
/*
* IIDs are written in struct order, in the usual big-endian way. From the
* typelib file spec:
*
* "For example, this IID:
* {00112233-4455-6677-8899-aabbccddeeff}
* is converted to the 128-bit value
* 0x00112233445566778899aabbccddeeff
* Note that the byte storage order corresponds to the layout of the nsIID
* C-struct on a big-endian architecture."
*
* (http://www.mozilla.org/scriptable/typelib_file.html#iid)
*/
XPT_PUBLIC_API(PRBool)
XPT_DoIID(XPTCursor *cursor, nsID *iidp)
{
int i;
if (!XPT_Do32(cursor, &iidp->m0) ||
!XPT_Do16(cursor, &iidp->m1) ||
!XPT_Do16(cursor, &iidp->m2))
return PR_FALSE;
for (i = 0; i < 8; i++)
if (!XPT_Do8(cursor, &iidp->m3[i]))
return PR_FALSE;
return PR_TRUE;
}
XPT_PUBLIC_API(PRBool)
XPT_Do64(XPTCursor *cursor, PRInt64 *u64p)
{
return XPT_Do32(cursor, (uint32 *)u64p) &&
XPT_Do32(cursor, ((uint32 *)u64p) + 1);
}
/*
* When we're writing 32- or 16-bit quantities, we write a byte at a time to
* avoid alignment issues. Someone could come and optimize this to detect
* well-aligned cases and do a single store, if they cared. I might care
* later.
*/
XPT_PUBLIC_API(PRBool)
XPT_Do32(XPTCursor *cursor, uint32 *u32p)
{
union {
uint8 b8[4];
uint32 b32;
} u;
if (!CHECK_COUNT(cursor, 4))
return PR_FALSE;
if (ENCODING(cursor)) {
u.b32 = XPT_SWAB32(*u32p);
CURS_POINT(cursor) = u.b8[0];
cursor->offset++;
CURS_POINT(cursor) = u.b8[1];
cursor->offset++;
CURS_POINT(cursor) = u.b8[2];
cursor->offset++;
CURS_POINT(cursor) = u.b8[3];
} else {
u.b8[0] = CURS_POINT(cursor);
cursor->offset++;
u.b8[1] = CURS_POINT(cursor);
cursor->offset++;
u.b8[2] = CURS_POINT(cursor);
cursor->offset++;
u.b8[3] = CURS_POINT(cursor);
*u32p = XPT_SWAB32(u.b32);
}
cursor->offset++;
return PR_TRUE;
}
XPT_PUBLIC_API(PRBool)
XPT_Do16(XPTCursor *cursor, uint16 *u16p)
{
union {
uint8 b8[2];
uint16 b16;
} u;
if (!CHECK_COUNT(cursor, 2))
return PR_FALSE;
if (ENCODING(cursor)) {
u.b16 = XPT_SWAB16(*u16p);
CURS_POINT(cursor) = u.b8[0];
cursor->offset++;
CURS_POINT(cursor) = u.b8[1];
} else {
u.b8[0] = CURS_POINT(cursor);
cursor->offset++;
u.b8[1] = CURS_POINT(cursor);
*u16p = XPT_SWAB16(u.b16);
}
cursor->offset++;
return PR_TRUE;
}
XPT_PUBLIC_API(PRBool)
XPT_Do8(XPTCursor *cursor, uint8 *u8p)
{
if (!CHECK_COUNT(cursor, 1))
return PR_FALSE;
if (cursor->state->mode == XPT_ENCODE)
CURS_POINT(cursor) = *u8p;
else
*u8p = CURS_POINT(cursor);
cursor->offset++;
return PR_TRUE;
}
static PRBool
do_bit(XPTCursor *cursor, uint8 *u8p, int bitno)
{
return PR_FALSE;
#if 0
int bit_value, delta, new_value;
XPTDatapool *pool = cursor->pool;
if (cursor->state->mode == XPT_ENCODE) {
bit_value = (*u8p & 1) << (bitno); /* 7 = 0100 0000, 6 = 0010 0000 */
if (bit_value) {
delta = pool->bit + (bitno) - 7;
new_value = delta >= 0 ? bit_value >> delta : bit_value << -delta;
pool->data[pool->count] |= new_value;
}
} else {
bit_value = pool->data[pool->count] & (1 << (7 - pool->bit));
*u8p = bit_value >> (7 - pool->bit);
}
if (++pool->bit == 8) {
pool->count++;
pool->bit = 0;
}
return CHECK_COUNT(cursor);
#endif
}
XPT_PUBLIC_API(PRBool)
XPT_DoBits(XPTCursor *cursor, uint8 *u8p, int nbits)
{
#define DO_BIT(cursor, u8p, nbits) \
if (!do_bit(cursor, u8p, nbits)) \
return PR_FALSE;
switch(nbits) {
case 7:
DO_BIT(cursor, u8p, 7);
case 6:
DO_BIT(cursor, u8p, 6);
case 5:
DO_BIT(cursor, u8p, 5);
case 4:
DO_BIT(cursor, u8p, 4);
case 3:
DO_BIT(cursor, u8p, 3);
case 2:
DO_BIT(cursor, u8p, 2);
case 1:
DO_BIT(cursor, u8p, 1);
default:;
};
#undef DO_BIT
return PR_TRUE;
}
XPT_PUBLIC_API(int)
XPT_FlushBits(XPTCursor *cursor)
{
return 0;
#if 0
cursor->bits = 0;
cursor->offset++;
if (!CHECK_COUNT(cursor))
return -1;
return skipped == 8 ? 0 : skipped;
#endif
}

View File

@@ -0,0 +1,37 @@
#
# 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@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = libxpt
SIMPLE_PROGRAMS = PrimitiveTest SimpleTypeLib
CSRCS = PrimitiveTest.c SimpleTypeLib.c
LDFLAGS = \
-L$(DIST)/bin \
-lxpt \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,133 @@
/* -*- Mode: C; tab-width: 8; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* Test the xdr primitives from xpt_xdr.c */
#include "xpt_xdr.h"
#include <stdio.h>
#define PASS(msg) \
fprintf(stderr, "PASSED : %s\n", msg);
#define FAIL(msg) \
fprintf(stderr, "FAILURE: %s\n", msg);
#define TRY_(msg, cond, silent) \
if ((cond) && !silent) { \
PASS(msg); \
} else { \
FAIL(msg); \
return 1; \
}
#define TRY(msg, cond) TRY_(msg, cond, 0)
#define TRY_Q(msg, cond) TRY_(msg, cond, 1);
XPTString in_str = { 4, "bazz" };
struct TestData {
uint32 bit32;
uint16 bit16;
uint8 bit8[2];
char *cstr;
XPTString *str;
} input = { 0xdeadbeef, 0xcafe, {0xba, 0xbe}, "foobar", &in_str},
output = {0, 0, {0, 0}, NULL, NULL };
void
dump_struct(char *label, struct TestData *str)
{
fprintf(stderr, "%s: {%#08x, %#04x, {%#02x, %#02x}, %s, %d/%s}\n",
label, str->bit32, str->bit16, str->bit8[0], str->bit8[1],
str->cstr, str->str->length, str->str->bytes);
}
PRBool
XDR(XPTCursor *cursor, struct TestData *str)
{
TRY("Do32", XPT_Do32(cursor, &str->bit32));
TRY("Do16", XPT_Do16(cursor, &str->bit16));
TRY("Do8", XPT_Do8 (cursor, &str->bit8[0]));
TRY("Do8", XPT_Do8 (cursor, &str->bit8[1]));
TRY("DoCString", XPT_DoCString(cursor, &str->cstr));
TRY("DoString", XPT_DoString(cursor, &str->str));
return 0;
}
int
main(int argc, char **argv)
{
XPTState *state;
XPTCursor curs, *cursor = &curs;
char *header, *data, *whole;
uint32 hlen, dlen, i;
TRY("NewState (ENCODE)", (state = XPT_NewXDRState(XPT_ENCODE, NULL, 0)));
XPT_SetDataOffset(state, sizeof input);
TRY("MakeCursor", XPT_MakeCursor(state, XPT_HEADER, sizeof input, cursor));
dump_struct("before", &input);
if (XDR(cursor, &input))
return 1;
fprintf(stderr, "ENCODE successful\n");
XPT_GetXDRData(state, XPT_HEADER, &header, &hlen);
fprintf(stderr, "XDR header %d bytes at %p:",
hlen, header);
for (i = 0; i < hlen; i++)
fprintf(stderr, "%c%02x", i ? ',' : ' ', (uint8)header[i]);
fprintf(stderr, "\n");
XPT_GetXDRData(state, XPT_DATA, &data, &dlen);
fprintf(stderr, "XDR data %d bytes at %p:",
dlen, data);
for (i = 0; i < dlen; i++)
fprintf(stderr, "%c%02x/%c", i ? ',' : ' ', (uint8)data[i],
(uint8)data[i]);
fprintf(stderr, "\n");
whole = malloc(dlen + hlen);
if (!whole) {
fprintf(stderr, "malloc %d failed!\n", dlen + hlen);
return 1;
}
/* TRY_Q("malloc", (data2 = malloc(len))); */
memcpy(whole, header, hlen);
memcpy(whole + hlen, data, dlen);
XPT_DestroyXDRState(state);
TRY("NewState (DECODE)", (state = XPT_NewXDRState(XPT_DECODE, whole,
hlen + dlen)));
TRY("MakeCursor", XPT_MakeCursor(state, XPT_HEADER, sizeof input, cursor));
XPT_SetDataOffset(state, sizeof input);
if (XDR(cursor, &output))
return 1;
dump_struct("after", &output);
XPT_DestroyXDRState(state);
free(whole);
return 0;
}

View File

@@ -0,0 +1,149 @@
/* -*- Mode: C; tab-width: 8; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* Test the structure creation and serialization APIs from xpt_struct.c */
#include "xpt_xdr.h"
#include "xpt_struct.h"
#define PASS(msg) \
fprintf(stderr, "PASSED : %s\n", msg);
#define FAIL(msg) \
fprintf(stderr, "FAILURE: %s\n", msg);
#define TRY_(msg, cond, silent) \
if ((cond) && !silent) { \
PASS(msg); \
} else { \
FAIL(msg); \
return 1; \
}
#define TRY(msg, cond) TRY_(msg, cond, 0)
#define TRY_Q(msg, cond) TRY_(msg, cond, 1);
struct nsID iid = {
0x00112233,
0x4455,
0x6677,
{0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}
};
XPTTypeDescriptor td_void = { TD_VOID };
int
main(int argc, char **argv)
{
XPTHeader *header;
XPTAnnotation *ann;
XPTInterfaceDescriptor *id;
XPTMethodDescriptor *meth;
XPTState *state;
XPTCursor curs, *cursor = &curs;
char *data, *head;
FILE *out;
uint32 len, header_sz;
PRBool ok;
if (argc != 2) {
fprintf(stderr, "Usage: %s <filename.xpt>\n"
" Creates a simple typelib file.\n", argv[0]);
return 1;
}
/* construct a header */
header = XPT_NewHeader(1);
TRY("NewHeader", header);
ann = XPT_NewAnnotation(XPT_ANN_LAST | XPT_ANN_PRIVATE,
XPT_NewStringZ("SimpleTypeLib 1.0"),
XPT_NewStringZ("See You In Rome"));
TRY("NewAnnotation", ann);
header->annotations = ann;
header_sz = XPT_SizeOfHeaderBlock(header);
id = XPT_NewInterfaceDescriptor(0xdead, 2, 2);
TRY("NewInterfaceDescriptor", id);
ok = XPT_FillInterfaceDirectoryEntry(header->interface_directory, &iid,
"Interface", "NS", id);
TRY("FillInterfaceDirectoryEntry", ok);
/* void method1(void) */
meth = &id->method_descriptors[0];
ok = XPT_FillMethodDescriptor(meth, 0, "method1", 0);
TRY("FillMethodDescriptor", ok);
meth->result->flags = 0;
meth->result->type.prefix.flags = TD_VOID;
/* wstring method2(in uint32, in bool) */
meth = &id->method_descriptors[1];
ok = XPT_FillMethodDescriptor(meth, 0, "method2", 2);
TRY("FillMethodDescriptor", ok);
meth->result->flags = 0;
meth->result->type.prefix.flags = TD_PBSTR | XPT_TDP_POINTER;
meth->params[0].type.prefix.flags = TD_UINT32;
meth->params[0].flags = XPT_PD_IN;
meth->params[1].type.prefix.flags = TD_BOOL;
meth->params[1].flags = XPT_PD_IN;
/* const one = 1; */
id->const_descriptors[0].name = "one";
id->const_descriptors[0].type.prefix.flags = TD_UINT16;
id->const_descriptors[0].value.ui16 = 1;
/* const squeamish = "ossifrage"; */
id->const_descriptors[1].name = "squeamish";
id->const_descriptors[1].type.prefix.flags = TD_PBSTR | XPT_TDP_POINTER;
id->const_descriptors[1].value.string = XPT_NewStringZ("ossifrage");
/* serialize it */
state = XPT_NewXDRState(XPT_ENCODE, NULL, 0);
TRY("NewState (ENCODE)", state);
ok = XPT_MakeCursor(state, XPT_HEADER, header_sz, cursor);
TRY("MakeCursor", ok);
ok = XPT_DoHeader(cursor, &header);
TRY("DoHeader", ok);
out = fopen(argv[1], "w");
if (!out) {
perror("FAILED: fopen");
return 1;
}
XPT_GetXDRData(state, XPT_HEADER, &head, &len);
fwrite(head, len, 1, out);
XPT_GetXDRData(state, XPT_DATA, &data, &len);
fwrite(data, len, 1, out);
fclose(out);
XPT_DestroyXDRState(state);
/* XXX DestroyHeader */
return 0;
}

View File

@@ -0,0 +1,37 @@
#
# 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@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = libxpt
SIMPLE_PROGRAMS = xpt_dump
CSRCS = xpt_dump.c
LDFLAGS = \
-L$(DIST)/bin \
-lxpt \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,673 @@
/* -*- Mode: C; tab-width: 8; 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) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* A utility for dumping the contents of a typelib file (.xpt) to screen
*/
#include "xpt_xdr.h"
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include "prprf.h"
#define BASE_INDENT 3
static char *type_array[20] = {"int8", "int16", "int32", "int64",
"uint8", "uint16", "uint32", "uint64",
"float", "double", "boolean", "char",
"wchar_t", "void", "reserved", "reserved",
"reserved", "reserved", "Interface *",
"InterfaceIs *"};
static char *ptype_array[18] = {"int8 *", "int16 *", "int32 *", "int64 *",
"uint8 *", "uint16 *", "uint32 *", "uint64 *",
"float *", "double *", "boolean *", "char *",
"wchar_t *", "void *", "nsIID **", "bstr",
"string", "wstring"};
PRBool
XPT_DumpHeader(XPTHeader *header, const int indent, PRBool verbose_mode);
PRBool
XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode);
PRBool
XPT_DumpInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
const int indent, PRBool verbose_mode);
PRBool
XPT_DumpInterfaceDescriptor(XPTInterfaceDescriptor *id, const int indent,
PRBool verbose_mode);
PRBool
XPT_DumpMethodDescriptor(XPTMethodDescriptor *md, const int indent,
PRBool verbose_mode);
PRBool
XPT_GetStringForType(XPTTypeDescriptor *td, char **type_string);
PRBool
XPT_DumpXPTString(XPTString *str);
PRBool
XPT_DumpParamDescriptor(XPTParamDescriptor *pd, const int indent,
PRBool verbose_mode);
PRBool
XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, int indent,
PRBool verbose_mode);
PRBool
XPT_DumpConstDescriptor(XPTConstDescriptor *cd, const int indent,
PRBool verbose_mode);
static void
xpt_dump_usage(char *argv[]) {
fprintf(stdout, "Usage: %s [-v] <filename.xpt>\n"
" -v verbose mode\n", argv[0]);
}
int
main(int argc, char **argv)
{
PRBool verbose_mode = PR_FALSE;
XPTState *state;
XPTCursor curs, *cursor = &curs;
XPTHeader *header;
struct stat file_stat;
int flen;
char *whole;
FILE *in;
switch (argc) {
case 2:
if (argv[1][0] == '-') {
xpt_dump_usage(argv);
return 1;
}
if (stat(argv[1], &file_stat) != 0) {
perror("FAILED: fstat");
return 1;
}
flen = file_stat.st_size;
in = fopen(argv[1], "r");
break;
case 3:
verbose_mode = PR_TRUE;
if (argv[1][0] != '-' || argv[1][1] != 'v') {
xpt_dump_usage(argv);
return 1;
}
if (stat(argv[2], &file_stat) != 0) {
perror("FAILED: fstat");
return 1;
}
flen = file_stat.st_size;
in = fopen(argv[2], "r");
break;
default:
xpt_dump_usage(argv);
return 1;
}
if (!in) {
perror("FAILED: fopen");
return 1;
}
whole = malloc(flen);
if (!whole) {
perror("FAILED: malloc for whole");
return 1;
}
if (flen > 0) {
fread(whole, flen, 1, in);
state = XPT_NewXDRState(XPT_DECODE, whole, flen);
if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) {
fprintf(stdout, "MakeCursor failed\n");
return 1;
}
if (!XPT_DoHeader(cursor, &header)) {
fprintf(stdout, "DoHeader failed\n");
return 1;
}
if (!XPT_DumpHeader(header, BASE_INDENT, verbose_mode)) {
perror("FAILED: XPT_DumpHeader");
return 1;
}
XPT_DestroyXDRState(state);
free(whole);
}
fclose(in);
return 0;
}
PRBool
XPT_DumpHeader(XPTHeader *header, const int indent, PRBool verbose_mode)
{
int i;
fprintf(stdout, "Header:\n");
if (verbose_mode) {
fprintf(stdout, "%*sMagic beans: ", indent, " ");
for (i=0; i<16; i++) {
fprintf(stdout, "%02x", header->magic[i]);
}
fprintf(stdout, "\n");
if (strncmp(header->magic, XPT_MAGIC, 16) == 0)
fprintf(stdout, "%*s PASSED\n", indent, " ");
else
fprintf(stdout, "%*s FAILED\n", indent, " ");
}
fprintf(stdout, "%*sMajor version: %d\n", indent, " ",
header->major_version);
fprintf(stdout, "%*sMinor version: %d\n", indent, " ",
header->minor_version);
fprintf(stdout, "%*sNumber of interfaces: %d\n", indent, " ",
header->num_interfaces);
if (verbose_mode) {
fprintf(stdout, "%*sFile length: %d\n", indent, " ",
header->file_length);
fprintf(stdout, "%*sData pool offset: %d\n\n", indent, " ",
header->data_pool);
}
fprintf(stdout, "%*sAnnotations:\n", indent, " ");
if (!XPT_DumpAnnotations(header->annotations, indent*2, verbose_mode))
return PR_FALSE;
fprintf(stdout, "\nInterface Directory:\n");
for (i=0; i<header->num_interfaces; i++) {
if (verbose_mode) {
fprintf(stdout, "%*sInterface #%d:\n", indent, " ", i);
if (!XPT_DumpInterfaceDirectoryEntry(&header->interface_directory[i], indent*2, verbose_mode)) {
return PR_FALSE;
}
} else {
if (!XPT_DumpInterfaceDirectoryEntry(&header->interface_directory[i], indent, verbose_mode)) {
return PR_FALSE;
}
}
}
return PR_TRUE;
}
PRBool
XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode)
{
int i = -1;
XPTAnnotation *last;
int new_indent = indent + BASE_INDENT;
do {
i++;
if (XPT_ANN_IS_PRIVATE(ann->flags)) {
if (verbose_mode) {
fprintf(stdout, "%*sAnnotation #%d is private.\n",
indent, " ", i);
} else {
fprintf(stdout, "%*sAnnotation #%d:\n",
indent, " ", i);
}
fprintf(stdout, "%*sCreator: ", new_indent, " ");
if (!XPT_DumpXPTString(ann->creator))
return PR_FALSE;
fprintf(stdout, "\n");
fprintf(stdout, "%*sPrivate Data: ", new_indent, " ");
if (!XPT_DumpXPTString(ann->private_data))
return PR_FALSE;
fprintf(stdout, "\n");
} else {
fprintf(stdout, "%*sAnnotation #%d is empty.\n",
indent, " ", i);
}
last = ann;
ann = ann->next;
} while (!XPT_ANN_IS_LAST(last->flags));
if (verbose_mode) {
fprintf(stdout, "%*sAnnotation #%d is the last annotation.\n",
indent, " ", i);
}
return PR_TRUE;
}
static void
print_IID(struct nsID *iid, FILE *file)
{
fprintf(file, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
(PRUint32) iid->m0, (PRUint32) iid->m1,(PRUint32) iid->m2,
(PRUint32) iid->m3[0], (PRUint32) iid->m3[1],
(PRUint32) iid->m3[2], (PRUint32) iid->m3[3],
(PRUint32) iid->m3[4], (PRUint32) iid->m3[5],
(PRUint32) iid->m3[6], (PRUint32) iid->m3[7]);
}
PRBool
XPT_DumpInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
const int indent, PRBool verbose_mode)
{
int new_indent = indent + BASE_INDENT;
if (verbose_mode) {
fprintf(stdout, "%*sIID: ", indent, " ");
print_IID(&ide->iid, stdout);
fprintf(stdout, "\n");
fprintf(stdout, "%*sName: %s\n",
indent, " ", ide->name);
fprintf(stdout, "%*sNamespace: %s\n",
indent, " ", ide->name_space);
fprintf(stdout, "%*sAddress of interface descriptor: %p\n",
indent, " ", ide->interface_descriptor);
fprintf(stdout, "%*sDescriptor:\n", indent, " ");
if (!XPT_DumpInterfaceDescriptor(ide->interface_descriptor,
new_indent, verbose_mode)) {
return PR_FALSE;
}
} else {
fprintf(stdout, "%*s- %s::%s (", indent, " ",
ide->name_space ? ide->name_space : "", ide->name);
print_IID(&ide->iid, stdout);
fprintf(stdout, "):\n");
if (!XPT_DumpInterfaceDescriptor(ide->interface_descriptor,
new_indent, verbose_mode)) {
return PR_FALSE;
}
}
return PR_TRUE;
}
PRBool
XPT_DumpInterfaceDescriptor(XPTInterfaceDescriptor *id, const int indent,
PRBool verbose_mode)
{
int i;
int new_indent = indent + BASE_INDENT;
int more_indent = new_indent + BASE_INDENT;
if (!id) {
fprintf(stdout, "%*s[Unresolved]\n", indent, " ");
return PR_TRUE;
}
if (verbose_mode) {
fprintf(stdout, "%*sOffset of parent interface (in data pool): %p\n",
indent, " ", id->parent_interface);
fprintf(stdout, "%*s# of Method Descriptors: %d\n",
indent, " ", id->num_methods);
} else {
fprintf(stdout, "%*sMethods:\n", indent, " ");
}
if (id->num_methods == 0) {
fprintf(stdout, "%*sNo Methods\n", new_indent, " ");
} else {
for (i=0; i<id->num_methods; i++) {
if (verbose_mode) {
fprintf(stdout, "%*sMethod #%d:\n", new_indent, " ", i);
if (!XPT_DumpMethodDescriptor(&id->method_descriptors[i],
more_indent, verbose_mode))
return PR_FALSE;
} else {
if (!XPT_DumpMethodDescriptor(&id->method_descriptors[i],
new_indent, verbose_mode))
return PR_FALSE;
}
}
}
if (verbose_mode) {
fprintf(stdout, "%*s# of Constant Descriptors: %d\n",
indent, " ", id->num_constants);
for (i=0; i<id->num_constants; i++) {
fprintf(stdout, "%*sConstant #%d:\n", new_indent, " ", i);
if (!XPT_DumpConstDescriptor(&id->const_descriptors[i],
more_indent, verbose_mode))
return PR_FALSE;
}
} else {
fprintf(stdout, "%*sConstants:\n", indent, " ");
for (i=0; i<id->num_constants; i++) {
if (!XPT_DumpConstDescriptor(&id->const_descriptors[i],
new_indent, verbose_mode))
return PR_FALSE;
}
}
return PR_TRUE;
}
PRBool
XPT_DumpMethodDescriptor(XPTMethodDescriptor *md, const int indent,
PRBool verbose_mode)
{
int i;
int new_indent = indent + BASE_INDENT;
int more_indent = new_indent + BASE_INDENT;
if (verbose_mode) {
fprintf(stdout, "%*sName: %s\n", indent, " ", md->name);
fprintf(stdout, "%*sIs Getter? ", indent, " ");
if (XPT_MD_IS_GETTER(md->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sIs Setter? ", indent, " ");
if (XPT_MD_IS_SETTER(md->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sIs Varargs? ", indent, " ");
if (XPT_MD_IS_VARARGS(md->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sIs Constructor? ", indent, " ");
if (XPT_MD_IS_CTOR(md->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sIs Hidden? ", indent, " ");
if (XPT_MD_IS_HIDDEN(md->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*s# of arguments: %d\n", indent, " ", md->num_args);
fprintf(stdout, "%*sParameter Descriptors:\n", indent, " ");
for (i=0; i<md->num_args; i++) {
fprintf(stdout, "%*sParameter #%d:\n", new_indent, " ", i);
if (!XPT_DumpParamDescriptor(&md->params[i], more_indent,
verbose_mode))
return PR_FALSE;
}
fprintf(stdout, "%*sResult:\n", indent, " ");
if (!XPT_DumpParamDescriptor(md->result, new_indent, verbose_mode)) {
return PR_FALSE;
}
} else {
char *param_type;
XPTParamDescriptor *pd;
if (!XPT_GetStringForType(&md->result->type, &param_type)) {
return PR_FALSE;
}
fprintf(stdout, "%*s%s %s(", indent, " ", param_type, md->name);
for (i=0; i<md->num_args; i++) {
if (i!=0) {
fprintf(stdout, ", ");
}
pd = &md->params[i];
if (XPT_PD_IS_IN(pd->flags)) {
fprintf(stdout, "in");
if (XPT_PD_IS_OUT(pd->flags)) {
fprintf(stdout, "/out ");
if (XPT_PD_IS_RETVAL(pd->flags)) {
fprintf(stdout, "retval ");
}
} else {
fprintf(stdout, " ");
}
} else {
if (XPT_PD_IS_OUT(pd->flags)) {
fprintf(stdout, "out ");
if (XPT_PD_IS_RETVAL(pd->flags)) {
fprintf(stdout, "retval ");
}
}
}
if (!XPT_GetStringForType(&pd->type, &param_type)) {
return PR_FALSE;
}
fprintf(stdout, "%s", param_type);
}
fprintf(stdout, ");\n");
}
return PR_TRUE;
}
PRBool
XPT_GetStringForType(XPTTypeDescriptor *td, char **type_string)
{
int tag = XPT_TDP_TAG(td->prefix);
if (XPT_TDP_IS_POINTER(td->prefix.flags)) {
*type_string = ptype_array[tag];
} else {
*type_string = type_array[tag];
}
return PR_TRUE;
}
PRBool
XPT_DumpXPTString(XPTString *str)
{
int i;
for (i=0; i<str->length; i++) {
fprintf(stdout, "%c", str->bytes[i]);
}
return PR_TRUE;
}
PRBool
XPT_DumpParamDescriptor(XPTParamDescriptor *pd, const int indent,
PRBool verbose_mode)
{
int new_indent = indent + BASE_INDENT;
fprintf(stdout, "%*sIn Param? ", indent, " ");
if (XPT_PD_IS_IN(pd->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sOut Param? ", indent, " ");
if (XPT_PD_IS_OUT(pd->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sRetval? ", indent, " ");
if (XPT_PD_IS_RETVAL(pd->flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sType Descriptor:\n", indent, " ");
if (!XPT_DumpTypeDescriptor(&pd->type, new_indent, verbose_mode))
return PR_FALSE;
return PR_TRUE;
}
PRBool
XPT_DumpTypeDescriptor(XPTTypeDescriptor *td, int indent, PRBool verbose_mode)
{
int new_indent = indent + BASE_INDENT;
fprintf(stdout, "%*sIs Pointer? ", indent, " ");
if (XPT_TDP_IS_POINTER(td->prefix.flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sIs Unique Pointer? ", indent, " ");
if (XPT_TDP_IS_UNIQUE_POINTER(td->prefix.flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sIs Reference? ", indent, " ");
if (XPT_TDP_IS_REFERENCE(td->prefix.flags))
fprintf(stdout, "TRUE\n");
else
fprintf(stdout, "FALSE\n");
fprintf(stdout, "%*sTag: %d\n", indent, " ",
XPT_TDP_TAG(td->prefix));
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " ");
fprintf(stdout, "%*sIndex of IDE: %d\n", new_indent, " ",
td->type.interface);
}
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE) {
fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " ");
fprintf(stdout, "%*sIndex of Method Argument: %d\n", new_indent, " ",
td->type.argnum);
}
return PR_TRUE;
}
PRBool
XPT_DumpConstDescriptor(XPTConstDescriptor *cd, const int indent, PRBool verbose_mode)
{
int new_indent = indent + BASE_INDENT;
char *out, *const_type;
if (verbose_mode) {
fprintf(stdout, "%*sName: %s\n", indent, " ", cd->name);
fprintf(stdout, "%*sType Descriptor: \n", indent, " ");
if (!XPT_DumpTypeDescriptor(&cd->type, new_indent, verbose_mode))
return PR_FALSE;
fprintf(stdout, "%*sValue: ", indent, " ");
} else {
if (!XPT_GetStringForType(&cd->type, &const_type)) {
return PR_FALSE;
}
fprintf(stdout, "%*s%s %s = ", indent, " ", const_type, cd->name);
}
switch(XPT_TDP_TAG(cd->type.prefix)) {
case TD_INT8:
fprintf(stdout, "%d", cd->value.i8);
break;
case TD_INT16:
fprintf(stdout, "%d", cd->value.i16);
break;
case TD_INT32:
fprintf(stdout, "%d", cd->value.i32);
break;
case TD_INT64:
out = PR_smprintf("%lld", cd->value.i64);
fputs(out, stdout);
PR_smprintf_free(out);
break;
case TD_UINT8:
fprintf(stdout, "%d", cd->value.ui8);
break;
case TD_UINT16:
fprintf(stdout, "%d", cd->value.ui16);
break;
case TD_UINT32:
fprintf(stdout, "%d", cd->value.ui32);
break;
case TD_UINT64:
out = PR_smprintf("%lld", cd->value.ui64);
fputs(out, stdout);
PR_smprintf_free(out);
break;
case TD_FLOAT:
fprintf(stdout, "%f", cd->value.flt);
break;
case TD_DOUBLE:
fprintf(stdout, "%g", cd->value.dbl);
break;
case TD_BOOL:
if (cd->value.bul)
fprintf(stdout, "TRUE");
else
fprintf(stdout, "FALSE");
break;
case TD_CHAR:
fprintf(stdout, "%c", cd->value.ch);
break;
case TD_WCHAR:
fprintf(stdout, "%c", cd->value.wch & 0xff);
break;
case TD_VOID:
fprintf(stdout, "VOID");
break;
case TD_PNSIID:
if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
print_IID(cd->value.iid, stdout);
} else
return PR_FALSE;
break;
case TD_PBSTR:
if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
if (!XPT_DumpXPTString(cd->value.string))
return PR_FALSE;
} else
return PR_FALSE;
break;
case TD_PSTRING:
if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
fprintf(stdout, "%s", cd->value.str);
} else
return PR_FALSE;
break;
case TD_PWSTRING:
if (XPT_TDP_IS_POINTER(cd->type.prefix.flags)) {
PRUint16 *ch = cd->value.wstr;
while (*ch) {
fprintf(stdout, "%c", *ch & 0xff);
ch++;
}
} else
return PR_FALSE;
break;
default:
perror("Unrecognized type");
return PR_FALSE;
break;
}
if (verbose_mode) {
fprintf(stdout, "\n");
} else {
fprintf(stdout, ";\n");
}
return PR_TRUE;
}

View File

@@ -0,0 +1,27 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
//
// xpcom.Prefix
//
// Global prefix file for the xpcom project.
//
//
#include "MacPrefix.h"
#include "xpcomConfig.h"

View File

@@ -0,0 +1,102 @@
#ToString__4nsIDCFv # nsID::ToString() const
Parse__4nsIDFPc # nsID::Parse(char*)
#__vt__5IDKey # IDKey::__vt
#monitor__12nsRepository # nsRepository::monitor
#factories__12nsRepository # nsRepository::factories
#HashValue__5IDKeyCFv # IDKey::HashValue() const
#Equals__5IDKeyCFPC9nsHashKey # IDKey::Equals(const nsHashKey*) const
#Clone__5IDKeyCFv # IDKey::Clone() const
FreeLibraries__12nsRepositoryFv # nsRepository::FreeLibraries()
UnregisterFactory__12nsRepositoryFRC4nsIDPCc # nsRepository::UnregisterFactory(const nsID&,const char*)
UnregisterFactory__12nsRepositoryFRC4nsIDP10nsIFactory # nsRepository::UnregisterFactory(const nsID&,nsIFactory*)
RegisterFactory__12nsRepositoryFRC4nsIDPCcii # nsRepository::RegisterFactory(const nsID&,const char*,int,int)
RegisterFactory__12nsRepositoryFRC4nsIDP10nsIFactoryi # nsRepository::RegisterFactory(const nsID&,nsIFactory*,int)
#CreateInstance2__12nsRepositoryFRC4nsIDP11nsISupportsRC4nsIDPvPPv # nsRepository::CreateInstance2(const nsID&,nsISupports*,const nsID&,void*,void**)
CreateInstance__12nsRepositoryFRC4nsIDP11nsISupportsRC4nsIDPPv # nsRepository::CreateInstance(const nsID&,nsISupports*,const nsID&,void**)
#Initialize__12nsRepositoryFv # nsRepository::Initialize()
#checkInitialized__12nsRepositoryFv # nsRepository::checkInitialized()
#__dt__5IDKeyFv # IDKey::~IDKey()
FindFactory__12nsRepositoryFRC4nsIDPP10nsIFactory # nsRepository::FindFactory(const nsID&,nsIFactory**)
#__vt__9nsHashKey # nsHashKey::__vt
Enumerate__11nsHashtableFPFP9nsHashKeyPvPv_iPv # nsHashtable::Enumerate(int (*)(nsHashKey*, void*))
Clone__11nsHashtableFv # nsHashtable::Clone()
Reset__11nsHashtableFv # nsHashtable::Reset()
Remove__11nsHashtableFP9nsHashKey # nsHashtable::Remove(nsHashKey*)
Get__11nsHashtableFP9nsHashKey # nsHashtable::Get(nsHashKey*)
Put__11nsHashtableFP9nsHashKeyPv # nsHashtable::Put(nsHashKey*,void*)
__dt__11nsHashtableFv # nsHashtable::~nsHashtable()
__ct__11nsHashtableFUi # nsHashtable::nsHashtable(unsigned int)
__dt__9nsHashKeyFv # nsHashKey::~nsHashKey()
__ct__9nsHashKeyFv # nsHashKey::nsHashKey()
Warning__7nsDebugFPCcPCci # nsDebug::Warning(const char*,const char*,int)
Error__7nsDebugFPCcPCci # nsDebug::Error(const char*,const char*,int)
NotReached__7nsDebugFPCcPCci # nsDebug::NotReached(const char*,const char*,int)
NotYetImplemented__7nsDebugFPCcPCci # nsDebug::NotYetImplemented(const char*,const char*,int)
Assertion__7nsDebugFPCcPCcPCci # nsDebug::Assertion(const char*,const char*,const char*,int)
PostCondition__7nsDebugFPCcPCcPCci # nsDebug::PostCondition(const char*,const char*,const char*,int)
PreCondition__7nsDebugFPCcPCcPCci # nsDebug::PreCondition(const char*,const char*,const char*,int)
Create__8nsMallocFP11nsISupportsRC4nsIDPPv # nsMalloc::Create(nsISupports*,const nsID&,void**)
#Break__7nsDebugFPCci # nsDebug::Break(const char*,int)
Abort__7nsDebugFPCci # nsDebug::Abort(const char*,int)
#__vt__17SupportsArrayImpl # SupportsArrayImpl::__vt
#__vt__16nsISupportsArray # nsISupportsArray::__vt
#__vt__11nsISupports # nsISupports::__vt
#__eq__17SupportsArrayImplCFRC16nsISupportsArray # SupportsArrayImpl::operator ==(const nsISupportsArray&) const
#Count__17SupportsArrayImplCFv # SupportsArrayImpl::Count() const
#__vc__17SupportsArrayImplCFi # SupportsArrayImpl::operator [](int) const
#AppendElement__17SupportsArrayImplFP11nsISupports # SupportsArrayImpl::AppendElement(nsISupports*)
NS_NewISupportsArray__FPP16nsISupportsArray # NS_NewISupportsArray(nsISupportsArray**)
#EnumerateBackwards__17SupportsArrayImplFPFP11nsISupportsPv_iPv # SupportsArrayImpl::EnumerateBackwards(int (*)(nsISupports*, void*),void*)
#EnumerateForwards__17SupportsArrayImplFPFP11nsISupportsPv_iPv # SupportsArrayImpl::EnumerateForwards(int (*)(nsISupports*, void*),void*)
#Compact__17SupportsArrayImplFv # SupportsArrayImpl::Compact()
#Clear__17SupportsArrayImplFv # SupportsArrayImpl::Clear()
#RemoveLastElement__17SupportsArrayImplFPC11nsISupports # SupportsArrayImpl::RemoveLastElement(const nsISupports*)
#RemoveElement__17SupportsArrayImplFPC11nsISupportsi # SupportsArrayImpl::RemoveElement(const nsISupports*,int)
#RemoveElementAt__17SupportsArrayImplFi # SupportsArrayImpl::RemoveElementAt(int)
#ReplaceElementAt__17SupportsArrayImplFP11nsISupportsi # SupportsArrayImpl::ReplaceElementAt(nsISupports*,int)
#InsertElementAt__17SupportsArrayImplFP11nsISupportsi # SupportsArrayImpl::InsertElementAt(nsISupports*,int)
#LastIndexOf__17SupportsArrayImplCFPC11nsISupports # SupportsArrayImpl::LastIndexOf(const nsISupports*) const
#IndexOf__17SupportsArrayImplCFPC11nsISupportsi # SupportsArrayImpl::IndexOf(const nsISupports*,int) const
#ElementAt__17SupportsArrayImplCFi # SupportsArrayImpl::ElementAt(int) const
#Equals__17SupportsArrayImplCFPC16nsISupportsArray # SupportsArrayImpl::Equals(const nsISupportsArray*) const
#__as__17SupportsArrayImplFRC16nsISupportsArray # SupportsArrayImpl::operator =(const nsISupportsArray&)
#DeleteArray__17SupportsArrayImplFv # SupportsArrayImpl::DeleteArray()
#QueryInterface__17SupportsArrayImplFRC4nsIDPPv # SupportsArrayImpl::QueryInterface(const nsID&,void**)
#Release__17SupportsArrayImplFv # SupportsArrayImpl::Release()
#AddRef__17SupportsArrayImplFv # SupportsArrayImpl::AddRef()
#__dt__17SupportsArrayImplFv # SupportsArrayImpl::~SupportsArrayImpl()
#__ct__17SupportsArrayImplFv # SupportsArrayImpl::SupportsArrayImpl()
#PL_VectorAssertValid
PL_VectorRemove
PL_VectorInsert
PL_VectorAdd
PL_VectorSet
PL_VectorClone
PL_VectorCopy
PL_VectorCompact
PL_VectorIsValidIndex
PL_VectorSetSize
PL_VectorFinalize
PL_VectorInitialize
PL_VectorDestroy
PL_NewVector
# GetFactory call
NSGetFactory
nsRegistry_GetFactory
# nsServiceManager static method exports.
ReleaseService__16nsServiceManagerFRC4nsIDP11nsISupportsP19nsIShutdownListener
GetService__16nsServiceManagerFRC4nsIDRC4nsIDPP11nsISupportsP19nsIShutdownListener
# nsTraceRefcnt
Destroy__13nsTraceRefcntFPvPCci
Create__13nsTraceRefcntFPvPCcPCci
Release__13nsTraceRefcntFPvUlPCci
AddRef__13nsTraceRefcntFPvUlPCci
# nsCOMPtr
begin_assignment__13nsCOMPtr_baseFv
assign_with_QueryInterface__13nsCOMPtr_baseFP11nsISupportsRC4nsIDPUi
assign_with_AddRef__13nsCOMPtr_baseFP11nsISupports

View File

@@ -0,0 +1,14 @@
# target: xpcomDebug.shlb
mozilla/modules/plugin/src/nsMalloc.cpp
mozilla/xpcom/macbuild/xpcom.exp
mozilla/xpcom/macbuild/xpcomDebug.exp
mozilla/xpcom/src/nsDebug.cpp
mozilla/xpcom/src/nsHashtable.cpp
mozilla/xpcom/src/nsID.cpp
mozilla/xpcom/src/nsRepository.cpp
mozilla/xpcom/src/nsServiceManager.cpp
mozilla/xpcom/src/nsSupportsArray.cpp
mozilla/xpcom/src/nsTraceRefcnt.cpp
mozilla/xpcom/src/plvector.c
mozilla/xpcom/src/xcDll.cpp
mozilla/xpcom/src/xcDllStore.cpp

View File

@@ -0,0 +1,19 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
/* Nothing to do here. Add xpcom-specific defines here if necessary */

View File

@@ -0,0 +1,27 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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.
*/
//
// xpcomDebug.Prefix
//
// Global prefix file for the xpcom project.
//
//
#include "MacPrefix_debug.h"
#include "xpcomConfig.h"

View File

@@ -0,0 +1,2 @@
# These are now just additions for the debug build.
PL_VectorAssertValid

Binary file not shown.

View 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=..
IGNORE_MANIFEST=1
DIRS=public src tests tools
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,26 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
nsCOMPtr.h
nsCom.h
nsAgg.h
nsDebug.h
nsError.h
nsHashtable.h
nsID.h
nsIFactory.h
nsISupports.h
nsIPtr.h
nsIServiceManager.h
nsISupportsArray.h
nsRepository.h
nsIEnumerator.h
nsVector.h
nsMacRepository.h
nsTraceRefcnt.h
plvector.h
nsXPComFactory.h
nsXPComCIID.h
nsIEventQueueService.h
nsICollection.h

View File

@@ -0,0 +1,54 @@
#!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@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = xpcom
EXPORTS = \
nsCOMPtr.h \
nsCom.h \
nsAgg.h \
nsDebug.h \
nsError.h \
nsHashtable.h \
nsIAllocator.h \
nsICollection.h \
nsID.h \
nsIFactory.h \
nsISupports.h \
nsIPtr.h \
nsIServiceManager.h \
nsISupportsArray.h \
nsProxyEvent.h \
nsRepository.h \
nsIEnumerator.h \
nsTraceRefcnt.h \
nsVector.h \
plvector.h \
nsXPComFactory.h \
nsXPComCIID.h \
nsIEventQueueService.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,51 @@
#!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.
IGNORE_MANIFEST=1
DEPTH=..\..
EXPORTS = \
nsCOMPtr.h \
nsAgg.h \
nsCom.h \
nsDebug.h \
nsError.h \
nsHashtable.h \
nsICollection.h \
nsID.h \
nsIFactory.h \
nsISupports.h \
nsIPtr.h \
nsIServiceManager.h \
nsISupportsArray.h \
nsProxyEvent.h \
nsRepository.h \
nsIEnumerator.h \
nsTraceRefcnt.h \
nsVector.h \
plvector.h \
nsXPComFactory.h \
nsXPComCIID.h \
nsIEventQueueService.h \
nsIAllocator.h \
nsIRegistry.h \
$(NULL)
MODULE = xpcom
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,168 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* 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.
*/
#ifndef __mozIClassRegistry_h
#define __mozIClassRegistry_h
#include "nsRepository.h"
/*---------------------------- mozIClassRegistry -------------------------------
| This interface provides access to a mapping from mnemonic interface names |
| to shared libraries where implementations of those interfaces can be located.|
| |
| This interface is designed to provide two things: |
| 1. A means of less static binding between clients and the code that |
| implements the XPCOM interfaces those clients use. This accomplished |
| by the mapping from interface names to nsCID (and the shared libraries |
| that implement those classes). |
| 2. A means of dynamically changing the mapping from interface name to |
| implementation. The canonical example of this is to switch to a |
| "native" widget set versus an "XP" (implemented using gfx) set. |
| |
| The first goal is achieved by storing (in a "Netscape Registry" file, see |
| nsReg.h) information that maps interface/class "names" to information about |
| where to load implementations of those interfaces. That information |
| includes the interface ID, class ID (of the implementation class), and the |
| name of the shared library that contains the implementation. |
| |
| The class registry object will register those classes with the "repository" |
| (see nsRepository.h) the first time a request is made to create an |
| instance. Subsequent requests will simply be forwarded to the repository |
| after the appropriate interface and class IDs are determined. |
| |
| The second goal is accomplished by permitting the mnemonic interface |
| "names" to be "overloaded", that is, mapped to distinct implementations |
| by separate class registry objects. Further, class registries can be |
| cascaded: they can be chained together so that when a name is not |
| recognized by one registry, it can pass the request to the next registry in |
| the chain. Users can control resolution by making the request of a |
| registry further up/down the chain. |
| |
| For example, consider the case of "native" vs. "gfx" widgets. This might |
| be structured by a class registry arrangment like this: |
| |
| nativeWidgetRegistry baseWidgetRegistry |
| +----------+ +----------+ |
| | ----+---------------->| | |
| +----------+ +----------+ |
| |toolbar| -+-----+ |toolbar| -+-----+ |
| +----------+ | +----------+ | |
| |button | -+-----+ |button | -+-----+ |
| +----------+ | +----------+ | |
| V V |
| +-----------------+ +-----------------+ |
| | native.dll | | base.dll | |
| +-----------------+ +-----------------+ |
| |
| If a specialized implementation of widgets is present (e.g., native.dll) |
| then a corresponding class registry object is created and added to the |
| head of the registry chain. Object creation requests (normal ones) are |
| resolved to the native implementation. If such a library is not present, |
| then the resolution is to the base implementation. If objects of the |
| base implementation are required, then creation requests can be directed |
| directly to the baseWidgetRegistry object, rather than the head of the |
| registry chain. |
| |
| It is intended that there be a single instance of this interface, accessed |
| via the Service Manager (see nsServiceManager.h). |
------------------------------------------------------------------------------*/
struct mozIClassRegistry : public ISupports {
/*------------------------------ CreateInstance ----------------------------
| Create an instance of the requested class/interface. The interface |
| ID is required to specify how the result will be treated. The class |
| named by aName must support this interface. The result is placed in |
| ncomment aResult (NULL if the request fails). "start" specifies the |
| registry at which the search for an implementation of the named |
| interface should start. It defaults to 0 (indicating to start at the |
| head of the registry chain). |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateInstance( const char *anInterfaceName,
const nsIID &aIID,
void* *aResult,
const char *start = 0 ) = 0;
/*--------------------------- CreateEnumerator -----------------------------
| Creates an nsIEnumerator interface object that can be used to examine |
| the contents of the registry. "pattern" specifies either "*" or the |
| name of a specific interface that you want to query. "result" will |
| be set to point to a new object (which will be freed on the last call |
| to its Release() member). See nsIEnumerator.h for details on how to |
| use the returned interface pointer. |
--------------------------------------------------------------------------*/
NS_IMETHOD CreateEnumerator( const char *pattern,
nsIEnumerator* *result ) = 0;
}; // mozIClassRegistry
/*-------------------------- mozIClassRegistryEntry ----------------------------
| Objects of this class represent the individual elements that comprise a |
| mozIClassRegistry interface. You obtain such objects by applying the |
| CreateEnumerator member function to the class registry and then applying |
| the CurrentItem member function to the resulting nsIEnumerator interface. |
| |
| Each entry can be queried for the following information: |
| o sub-registry name |
| o interface name |
| o Class ID |
| o IIDs implemented |
| |
| The information obtained from the entry (specifically, the const char* |
| strings) remains valid for the life of the entry (i.e., until you |
| Release() it). |
| |
| Here is an example of code that uses this interface to dump the contents |
| of a mozIClassRegistry: |
| |
| mozIClassRegistry *reg = nsServiceManager::GetService( kIDRegistry ); |
| nsIEnumerator *enum; |
| reg->CreateEnumerator( "*", &enum ); |
| for ( enum->First(); !enum->IsDone(); enum->Next(); ) { |
| mozIClassRegistryEntry *entry; |
| enum->CurrentItem( &entry ); |
| const char *subreg; |
| const char *name; |
| nsCID cid; |
| int numIIDs; |
| entry->GetSubRegistryName( &subreg ); |
| entry->GetInterfaceName( &name ); |
| entry->GetClassID( &cid ); |
| entry->GetNumIIDs( &numIIDs ); |
| cout << subreg << "/" << name << " = " << cid.ToString() << endl; |
| for ( int i = 0; i < numIIDs; i++ ) { |
| nsIID iid; |
| entry->GetInterfaceID( i, &iid ); |
| cout << "/tIID[" << i << "] = " << iid.ToString() << endl; |
| } |
| entry->Release(); |
| } |
| enum->Release(); |
------------------------------------------------------------------------------*/
struct mozIClassRegistryEntry : public nsISupports {
NS_IMETHOD GetSubRegistryName( const char **result ) = 0;
NS_IMETHOD GetInterfaceName( const char **result ) = 0;
NS_IMETHOD GetClassID( nsCID *result ) = 0;
NS_IMETHOD GetNumIIDs( int *result ) = 0;
NS_IMETHOD GetInterfaceID( int n, nsIID *result ) = 0;
}; // mozIClassRegistryEntry
// {5D41A440-8E37-11d2-8059-00600811A9C3}
#define MOZ_ICLASSREGISTRY_IID { 0x5d41a440, 0x8e37, 0x11d2, { 0x80, 0x59, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
// {D1B54831-AC07-11d2-805E-00600811A9C3}
#define MOZ_ICLASSREGISTRYENTRY_IID { 0xd1b54831, 0xac07, 0x11d2, { 0x80, 0x5e, 0x0, 0x60, 0x8, 0x11, 0xa9, 0xc3 } }
#endif

Some files were not shown because too many files have changed in this diff Show More