summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/typelib/xpt
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in50
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in51
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h145
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h562
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h240
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in76
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c358
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c956
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c665
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore3
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in59
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c157
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c192
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore3
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in90
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c941
-rw-r--r--src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c883
20 files changed, 5434 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in
new file mode 100644
index 00000000..1447128f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in
@@ -0,0 +1,50 @@
+#
+# ***** 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):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of 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 *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+
+DIRS = public src tools
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in
new file mode 100644
index 00000000..3e452486
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in
@@ -0,0 +1,51 @@
+#
+# ***** 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):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of 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 *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+
+EXPORTS = xpt_arena.h xpt_struct.h xpt_xdr.h
+EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h
new file mode 100644
index 00000000..2b277467
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/*
+ * Simple arena allocator for xpt (which avoids using NSPR).
+ */
+
+#ifndef __xpt_arena_h__
+#define __xpt_arena_h__
+
+#include "prtypes.h"
+#include <stdlib.h>
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define XPT_NewArena VBoxNsxpXPT_NewArena
+#define XPT_ArenaMalloc VBoxNsxpXPT_ArenaMalloc
+#define XPT_DestroyArena VBoxNsxpXPT_DestroyArena
+#define XPT_ArenaFree VBoxNsxpXPT_ArenaFree
+#define XPT_DestroyArena VBoxNsxpXPT_DestroyArena
+#define XPT_DumpStats VBoxNsxpXPT_DumpStats
+#define XPT_NotifyDoneLoading VBoxNsxpXPT_NotifyDoneLoading
+#define XPT_ArenaStrDup VBoxNsxpXPT_ArenaStrDup
+#define XPT_AssertFailed VBoxNsxpXPT_AssertFailed
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+/*
+ * 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
+
+/*
+ * Simple Arena support. Use with caution!
+ */
+
+typedef struct XPTArena XPTArena;
+
+XPT_PUBLIC_API(XPTArena *)
+XPT_NewArena(PRUint32 block_size, size_t alignment, const char* name);
+
+XPT_PUBLIC_API(void)
+XPT_DestroyArena(XPTArena *arena);
+
+XPT_PUBLIC_API(void)
+XPT_DumpStats(XPTArena *arena);
+
+XPT_PUBLIC_API(void *)
+XPT_ArenaMalloc(XPTArena *arena, size_t size);
+
+XPT_PUBLIC_API(char *)
+XPT_ArenaStrDup(XPTArena *arena, const char * s);
+
+XPT_PUBLIC_API(void)
+XPT_NotifyDoneLoading(XPTArena *arena);
+
+XPT_PUBLIC_API(void)
+XPT_ArenaFree(XPTArena *arena, void* block);
+
+/* --------------------------------------------------------- */
+
+#define XPT_MALLOC(_arena, _bytes) \
+ XPT_ArenaMalloc((_arena), (_bytes))
+
+#ifdef DEBUG
+#define XPT_FREE(_arena, _ptr) \
+ XPT_ArenaFree((_arena), (_ptr))
+#else
+#define XPT_FREE(_arena, _ptr) \
+ ((void)0)
+#endif
+
+#define XPT_STRDUP(_arena, _s) \
+ XPT_ArenaStrDup((_arena), (_s))
+
+#define XPT_CALLOC(_arena, _size) XPT_MALLOC((_arena), (_size))
+#define XPT_NEW(_arena, _struct) ((_struct *) XPT_MALLOC((_arena), sizeof(_struct)))
+#define XPT_NEWZAP(_arena, _struct) XPT_NEW((_arena), _struct)
+#define XPT_DELETE(_arena, _ptr) do{XPT_FREE((_arena), (_ptr)); ((_ptr)) = NULL;}while(0)
+#define XPT_FREEIF(_arena, _ptr) do{if ((_ptr)) XPT_FREE((_arena), (_ptr));}while(0)
+
+/* --------------------------------------------------------- */
+
+#ifdef DEBUG
+XPT_PUBLIC_API(void)
+XPT_AssertFailed(const char *s, const char *file, PRUint32 lineno);
+#define XPT_ASSERT(_expr) \
+ ((_expr)?((void)0):XPT_AssertFailed(# _expr, __FILE__, __LINE__))
+#else
+#define XPT_ASSERT(_expr) ((void)0)
+#endif
+
+PR_END_EXTERN_C
+
+#endif /* __xpt_arena_h__ */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h
new file mode 100644
index 00000000..c7f36f2d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h
@@ -0,0 +1,562 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/*
+ * 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 "xpt_arena.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define XPT_NewHeader VBoxNsxpXPT_NewHeader
+#define XPT_NewStringZ VBoxNsxpXPT_NewStringZ
+#define XPT_NewAnnotation VBoxNsxpXPT_NewAnnotation
+#define XPT_SizeOfHeaderBlock VBoxNsxpXPT_SizeOfHeaderBlock
+#define XPT_NewInterfaceDescriptor VBoxNsxpXPT_NewInterfaceDescriptor
+#define XPT_FillInterfaceDirectoryEntry VBoxNsxpXPT_FillInterfaceDirectoryEntry
+#define XPT_FillMethodDescriptor VBoxNsxpXPT_FillMethodDescriptor
+#define XPT_FreeHeader VBoxNsxpXPT_FreeHeader
+#define XPT_ParseVersionString VBoxNsxpXPT_ParseVersionString
+#define XPT_DestroyInterfaceDirectoryEntry VBoxNsxpXPT_DestroyInterfaceDirectoryEntry
+#define XPT_FillParamDescriptor VBoxNsxpXPT_FillParamDescriptor
+#define XPT_FreeInterfaceDescriptor VBoxNsxpXPT_FreeInterfaceDescriptor
+#define XPT_InterfaceDescriptorAddConsts VBoxNsxpXPT_InterfaceDescriptorAddConsts
+#define XPT_InterfaceDescriptorAddMethods VBoxNsxpXPT_InterfaceDescriptorAddMethods
+#define XPT_InterfaceDescriptorAddTypes VBoxNsxpXPT_InterfaceDescriptorAddTypes
+#define XPT_GetInterfaceIndexByName VBoxNsxpXPT_GetInterfaceIndexByName
+#define XPT_NewString VBoxNsxpXPT_NewString
+#define XPT_SizeOfHeader VBoxNsxpXPT_SizeOfHeader
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+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 {
+ PRUint8 magic[16];
+ PRUint8 major_version;
+ PRUint8 minor_version;
+ PRUint16 num_interfaces;
+ PRUint32 file_length;
+ XPTInterfaceDirectoryEntry *interface_directory;
+ PRUint32 data_pool;
+ XPTAnnotation *annotations;
+};
+
+#define XPT_MAGIC "XPCOM\nTypeLib\r\n\032"
+/* For error messages. */
+#define XPT_MAGIC_STRING "XPCOM\\nTypeLib\\r\\n\\032"
+#define XPT_MAJOR_VERSION 0x01
+#define XPT_MINOR_VERSION 0x02
+
+/* Any file with a major version number of XPT_MAJOR_INCOMPATIBLE_VERSION
+ * or higher is to be considered incompatible by this version of xpt and
+ * we will refuse to read it. We will return a header with magic, major and
+ * minor versions set from the file. num_interfaces and file_length will be
+ * set to zero to confirm our inability to read the file; i.e. even if some
+ * client of this library gets out of sync with us regarding the agreed upon
+ * value for XPT_MAJOR_INCOMPATIBLE_VERSION, anytime num_interfaces and
+ * file_length are both zero we *know* that this library refused to read the
+ * file due to version imcompatibility.
+ */
+#define XPT_MAJOR_INCOMPATIBLE_VERSION 0x02
+
+/*
+ * The "[-t version number]" cmd line parameter to the XPIDL compiler and XPT
+ * linker specifies the major and minor version number of the output
+ * type library.
+ *
+ * The goal is for the compiler to check that the input IDL file only uses
+ * constructs that are supported in the version specified. The linker will
+ * check that all typelib files it reads are of the version specified or
+ * below.
+ *
+ * Both the compiler and the linker will report errors and abort if these
+ * checks fail.
+ *
+ * When you rev up major or minor versions of the type library in the future,
+ * think about the new stuff that you added to the type library and add checks
+ * to make sure that occurrences of that new "stuff" will get caught when [-t
+ * version number] is used with the compiler. Here's what you'll probably
+ * have to do each time you rev up major/minor versions:
+ *
+ * 1) Add the current version number string (before your change) to the
+ * XPT_TYPELIB_VERSIONS list.
+ *
+ * 2) Do your changes add new features to XPIDL? Ensure that those new
+ * features are rejected by the XPIDL compiler when any version number in
+ * the XPT_TYPELIB_VERSIONS list is specified on the command line. The
+ * one place that currently does this kind of error checking is the function
+ * verify_type_fits_version() in xpidl_util.c. It currently checks
+ * attribute types, parameter types, and return types. You'll probably have
+ * to add to it or generalize it further based on what kind of changes you
+ * are making.
+ *
+ * 3) You will probably NOT need to make any changes to the error checking
+ * in the linker.
+ */
+
+#define XPT_VERSION_UNKNOWN 0
+#define XPT_VERSION_UNSUPPORTED 1
+#define XPT_VERSION_OLD 2
+#define XPT_VERSION_CURRENT 3
+
+typedef struct {
+ const char* str;
+ PRUint8 major;
+ PRUint8 minor;
+ PRUint16 code;
+} XPT_TYPELIB_VERSIONS_STRUCT;
+
+/* Currently accepted list of versions for typelibs */
+#define XPT_TYPELIB_VERSIONS { \
+ {"1.0", 1, 0, XPT_VERSION_UNSUPPORTED}, \
+ {"1.1", 1, 1, XPT_VERSION_OLD}, \
+ {"1.2", 1, 2, XPT_VERSION_CURRENT} \
+}
+
+extern XPT_PUBLIC_API(PRUint16)
+XPT_ParseVersionString(const char* str, PRUint8* major, PRUint8* minor);
+
+extern XPT_PUBLIC_API(XPTHeader *)
+XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces,
+ PRUint8 major_version, PRUint8 minor_version);
+
+extern XPT_PUBLIC_API(void)
+XPT_FreeHeader(XPTArena *arena, XPTHeader* aHeader);
+
+/* size of header and annotations */
+extern XPT_PUBLIC_API(PRUint32)
+XPT_SizeOfHeader(XPTHeader *header);
+
+/* size of header and annotations and InterfaceDirectoryEntries */
+extern XPT_PUBLIC_API(PRUint32)
+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 */
+ PRUint32 offset; /* the offset for an ID still to be read */
+#endif
+};
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_FillInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry *ide,
+ nsID *iid, char *name, char *name_space,
+ XPTInterfaceDescriptor *descriptor);
+
+extern XPT_PUBLIC_API(void)
+XPT_DestroyInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry* ide);
+
+/*
+ * An InterfaceDescriptor is a variable-size record used to describe a
+ * single XPCOM interface, including all of its methods.
+ */
+struct XPTInterfaceDescriptor {
+ PRUint16 parent_interface;
+ PRUint16 num_methods;
+ XPTMethodDescriptor *method_descriptors;
+ PRUint16 num_constants;
+ XPTConstDescriptor *const_descriptors;
+ PRUint8 flags;
+
+ /* additional_types are used for arrays where we may need multiple
+ * XPTTypeDescriptors for a single XPTMethodDescriptor. Since we still
+ * want to have a simple array of XPTMethodDescriptor (each with a single
+ * embedded XPTTypeDescriptor), a XPTTypeDescriptor can have a reference
+ * to an 'additional_type'. That reference is an index in this
+ * "additional_types" array. So a given XPTMethodDescriptor might have
+ * a whole chain of these XPTTypeDescriptors to represent, say, a multi
+ * dimensional array.
+ *
+ * Note that in the typelib file these additional types are stored 'inline'
+ * in the MethodDescriptor. But, in the typelib MethodDescriptors can be
+ * of varying sizes, where in XPT's in memory mapping of the data we want
+ * them to be of fixed size. This additional_types scheme is here to allow
+ * for that.
+ */
+
+ XPTTypeDescriptor *additional_types;
+ PRUint16 num_additional_types;
+};
+
+#define XPT_ID_SCRIPTABLE 0x80
+#define XPT_ID_FUNCTION 0x40
+#define XPT_ID_FLAGMASK 0xc0
+#define XPT_ID_TAGMASK (~XPT_ID_FLAGMASK)
+#define XPT_ID_TAG(id) ((id).flags & XPT_ID_TAGMASK)
+
+#define XPT_ID_IS_SCRIPTABLE(flags) (flags & XPT_ID_SCRIPTABLE)
+#define XPT_ID_IS_FUNCTION(flags) (flags & XPT_ID_FUNCTION)
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
+ PRUint16 num_interfaces, char *name,
+ PRUint16 *indexp);
+
+extern XPT_PUBLIC_API(XPTInterfaceDescriptor *)
+XPT_NewInterfaceDescriptor(XPTArena *arena,
+ PRUint16 parent_interface, PRUint16 num_methods,
+ PRUint16 num_constants, PRUint8 flags);
+
+extern XPT_PUBLIC_API(void)
+XPT_FreeInterfaceDescriptor(XPTArena *arena, XPTInterfaceDescriptor* id);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddTypes(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddMethods(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddConsts(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num);
+
+/*
+ * This is our special string struct with a length value associated with it,
+ * which means that it can contains embedded NULs.
+ */
+struct XPTString {
+ PRUint16 length;
+ char *bytes;
+};
+
+extern XPT_PUBLIC_API(XPTString *)
+XPT_NewString(XPTArena *arena, PRUint16 length, char *bytes);
+
+extern XPT_PUBLIC_API(XPTString *)
+XPT_NewStringZ(XPTArena *arena, 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.
+ */
+
+/* why bother with a struct? - other code relies on this being a struct */
+struct XPTTypeDescriptorPrefix {
+ PRUint8 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)
+
+/*
+ * 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_DOMSTRING = 15,
+ TD_PSTRING = 16,
+ TD_PWSTRING = 17,
+ TD_INTERFACE_TYPE = 18,
+ TD_INTERFACE_IS_TYPE = 19,
+ TD_ARRAY = 20,
+ TD_PSTRING_SIZE_IS = 21,
+ TD_PWSTRING_SIZE_IS = 22,
+ TD_UTF8STRING = 23,
+ TD_CSTRING = 24,
+ TD_ASTRING = 25
+};
+
+struct XPTTypeDescriptor {
+ XPTTypeDescriptorPrefix prefix;
+ PRUint8 argnum; /* used for iid_is and size_is */
+ PRUint8 argnum2; /* used for length_is */
+ union {
+ PRUint16 iface; /* used for TD_INTERFACE_TYPE */
+ PRUint16 additional_type; /* used for TD_ARRAY */
+ } type;
+};
+
+#define XPT_COPY_TYPE(to, from) \
+ (to).prefix.flags = (from).prefix.flags; \
+ (to).argnum = (from).argnum; \
+ (to).argnum2 = (from).argnum2; \
+ (to).type.additional_type = (from).type.additional_type;
+
+/*
+ * 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 {
+ PRInt8 i8;
+ PRUint8 ui8;
+ PRInt16 i16;
+ PRUint16 ui16;
+ PRInt32 i32;
+ PRUint32 ui32;
+ PRInt64 i64;
+ PRUint64 ui64;
+ float flt;
+ double dbl;
+ PRBool bul;
+ char ch;
+ PRUint16 wch;
+ nsID *iid;
+ XPTString *string;
+ char *str;
+ PRUint16 *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 {
+ PRUint8 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_SHARED 0x10
+#define XPT_PD_DIPPER 0x08
+#define XPT_PD_FLAGMASK 0xf8
+
+#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_PD_IS_SHARED(flags) (flags & XPT_PD_SHARED)
+#define XPT_PD_IS_DIPPER(flags) (flags & XPT_PD_DIPPER)
+
+/* this is bogus
+#define XPT_PARAMDESCRIPTOR_SIZE (XPT_TYPEDESCRIPTOR_SIZE + 1)
+*/
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_FillParamDescriptor(XPTArena *arena,
+ XPTParamDescriptor *pd, PRUint8 flags,
+ XPTTypeDescriptor *type);
+
+/*
+ * A MethodDescriptor is a variable-size record used to describe a single
+ * interface method.
+ */
+struct XPTMethodDescriptor {
+ char *name;
+ XPTParamDescriptor *params;
+ XPTParamDescriptor *result;
+ PRUint8 flags;
+ PRUint8 num_args;
+};
+
+/* 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_NOTXPCOM 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_NOTXPCOM(flags) (flags & XPT_MD_NOTXPCOM)
+#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(XPTArena *arena,
+ XPTMethodDescriptor *meth, PRUint8 flags, char *name,
+ PRUint8 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;
+ PRUint8 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(XPTArena *arena, PRUint8 flags, XPTString *creator,
+ XPTString *private_data);
+
+PR_END_EXTERN_C
+
+#endif /* __xpt_struct_h__ */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h
new file mode 100644
index 00000000..89d1c3f6
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h
@@ -0,0 +1,240 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/*
+ * Basic APIs for streaming typelib structures to/from disk.
+ */
+
+#ifndef __xpt_xdr_h__
+#define __xpt_xdr_h__
+
+#include "xpt_struct.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define XPT_Do8 VBoxNsxpXPT_Do8
+#define XPT_Do16 VBoxNsxpXPT_Do16
+#define XPT_Do32 VBoxNsxpXPT_Do32
+#define XPT_Do64 VBoxNsxpXPT_Do64
+#define XPT_DoIID VBoxNsxpXPT_DoIID
+#define XPT_DoCString VBoxNsxpXPT_DoCString
+#define XPT_DoString VBoxNsxpXPT_DoString
+#define XPT_DoStringInline VBoxNsxpXPT_DoStringInline
+#define XPT_NewXDRState VBoxNsxpXPT_NewXDRState
+#define XPT_SetDataOffset VBoxNsxpXPT_SetDataOffset
+#define XPT_SeekTo VBoxNsxpXPT_SeekTo
+#define XPT_MakeCursor VBoxNsxpXPT_MakeCursor
+#define XPT_DestroyXDRState VBoxNsxpXPT_DestroyXDRState
+#define XPT_GetXDRData VBoxNsxpXPT_GetXDRData
+#define XPT_GetXDRDataLength VBoxNsxpXPT_GetXDRDataLength
+#define XPT_DoHeader VBoxNsxpXPT_DoHeader
+#define XPT_DoHeaderPrologue VBoxNsxpXPT_DoHeaderPrologue
+#define XPT_UpdateFileLength VBoxNsxpXPT_UpdateFileLength
+#define XPT_DataOffset VBoxNsxpXPT_DataOffset
+#define XPT_GetOffsetForAddr VBoxNsxpXPT_GetOffsetForAddr
+#define XPT_SetOffsetForAddr VBoxNsxpXPT_SetOffsetForAddr
+#define XPT_SetAddrForOffset VBoxNsxpXPT_SetAddrForOffset
+#define XPT_GetAddrForOffset VBoxNsxpXPT_GetAddrForOffset
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+PR_BEGIN_EXTERN_C
+
+typedef struct XPTState XPTState;
+typedef struct XPTDatapool XPTDatapool;
+typedef struct XPTCursor XPTCursor;
+
+/* Opaque type, for internal use */
+typedef struct XPTHashTable XPTHashTable;
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoString(XPTArena *arena, XPTCursor *cursor, XPTString **strp);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoStringInline(XPTArena *arena, XPTCursor *cursor, XPTString **strp);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoCString(XPTArena *arena, XPTCursor *cursor, char **strp);
+
+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, PRUint32 *u32p);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_Do16(XPTCursor *cursor, PRUint16 *u16p);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_Do8(XPTCursor *cursor, PRUint8 *u8p);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoHeaderPrologue(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp, PRUint32 * ide_offset);
+extern XPT_PUBLIC_API(PRBool)
+XPT_DoHeader(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp);
+
+typedef enum {
+ XPT_ENCODE,
+ XPT_DECODE
+} XPTMode;
+
+typedef enum {
+ XPT_HEADER = 0,
+ XPT_DATA = 1
+} XPTPool;
+
+struct XPTState {
+ XPTMode mode;
+ PRUint32 data_offset;
+ PRUint32 next_cursor[2];
+ XPTDatapool *pool;
+ XPTArena *arena;
+};
+
+struct XPTDatapool {
+ XPTHashTable *offset_map;
+ char *data;
+ PRUint32 count;
+ PRUint32 allocated;
+};
+
+struct XPTCursor {
+ XPTState *state;
+ XPTPool pool;
+ PRUint32 offset;
+ PRUint8 bits;
+};
+
+extern XPT_PUBLIC_API(XPTState *)
+XPT_NewXDRState(XPTMode mode, char *data, PRUint32 len);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_MakeCursor(XPTState *state, XPTPool pool, PRUint32 len, XPTCursor *cursor);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_SeekTo(XPTCursor *cursor, PRUint32 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);
+
+/* returns the length of the specified data block */
+extern XPT_PUBLIC_API(void)
+XPT_GetXDRDataLength(XPTState *state, XPTPool pool, PRUint32 *len);
+
+extern XPT_PUBLIC_API(void)
+XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, PRUint32 *len);
+
+/* set or get the data offset for the state, depending on mode */
+extern XPT_PUBLIC_API(void)
+XPT_DataOffset(XPTState *state, PRUint32 *data_offsetp);
+
+extern XPT_PUBLIC_API(void)
+XPT_SetDataOffset(XPTState *state, PRUint32 data_offset);
+
+extern XPT_PUBLIC_API(PRUint32)
+XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, PRUint32 offset);
+
+extern XPT_PUBLIC_API(PRBool)
+XPT_SetAddrForOffset(XPTCursor *cursor, PRUint32 offset, void *addr);
+
+extern XPT_PUBLIC_API(void *)
+XPT_GetAddrForOffset(XPTCursor *cursor, PRUint32 offset);
+
+/* all data structures are big-endian */
+
+#if defined IS_BIG_ENDIAN
+# ifdef VBOX
+# error "Misconfigured endian!"
+# endif
+# 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 : 0u, &new_curs, \
+ &already) || \
+ !(mode == XPT_DECODE || XPT_Do32(cursor, &new_curs.offset))) \
+ return PR_FALSE; \
+ if (already) \
+ return PR_TRUE; \
+
+#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(arena, free_it) \
+ error: \
+ if (cursor->state->mode == XPT_DECODE) \
+ XPT_FREEIF(arena, free_it); \
+ return PR_FALSE;
+
+
+PR_END_EXTERN_C
+
+#endif /* __xpt_xdr_h__ */
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in
new file mode 100644
index 00000000..e0578556
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in
@@ -0,0 +1,76 @@
+#
+# ***** 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):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of 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 *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+LIBRARY_NAME = xpt
+LIB_IS_C_ONLY = 1
+ifdef CROSS_COMPILE
+HOST_LIBRARY_NAME = hostxpt
+endif
+
+CSRCS = xpt_arena.c xpt_struct.c xpt_xdr.c
+HOST_CSRCS = $(CSRCS)
+
+# we don't want the shared lib, but we want to force the creation of a static lib.
+FORCE_STATIC_LIB = 1
+
+# Force use of PIC
+FORCE_USE_PIC = 1
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -DEXPORT_XPT_API
+HOST_CFLAGS += -DEXPORT_XPT_API
+
+# Build libxpt early so that it'll be available to xpidl, which also
+# must be built early.
+export::
+ @$(MAKE) libs
+
+ifdef CROSS_COMPILE
+ifdef HOST_NSPR_MDCPUCFG
+HOST_CFLAGS += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG)
+endif
+endif
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c
new file mode 100644
index 00000000..a0813b8f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c
@@ -0,0 +1,358 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/* Quick arena hack for xpt. */
+
+/* XXX This exists because we don't want to drag in NSPR. It *seemed*
+* to make more sense to write a quick and dirty arena than to clone
+* plarena (like js/src did). This is not optimal, but it works.
+* Half of the code here is instrumentation.
+*/
+
+#include "xpt_arena.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+# include <iprt/mem.h>
+#endif
+
+
+/*************************/
+/* logging stats support */
+
+#if 0 && defined(DEBUG_jband)
+#define XPT_ARENA_LOGGING 1
+#endif
+
+#ifdef XPT_ARENA_LOGGING
+
+#define LOG_MALLOC(_a, _req, _used) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ ++(_a)->LOG_MallocCallCount; \
+ (_a)->LOG_MallocTotalBytesRequested += (_req); \
+ (_a)->LOG_MallocTotalBytesUsed += (_used); \
+ } while(0)
+
+#define LOG_REAL_MALLOC(_a, _size) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ ++(_a)->LOG_RealMallocCallCount; \
+ (_a)->LOG_RealMallocTotalBytesRequested += (_size); \
+ } while(0)
+
+#define LOG_FREE(_a) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ ++(_a)->LOG_FreeCallCount; \
+ } while(0)
+
+#define LOG_DONE_LOADING(_a) \
+ do{ \
+ XPT_ASSERT((_a)); \
+ (_a)->LOG_LoadingFreeCallCount = (_a)->LOG_FreeCallCount; \
+ } while(0)
+
+#define PRINT_STATS(_a) xpt_DebugPrintArenaStats((_a))
+static void xpt_DebugPrintArenaStats(XPTArena *arena);
+
+#else /* !XPT_ARENA_LOGGING */
+
+#define LOG_MALLOC(_a, _req, _used) ((void)0)
+#define LOG_REAL_MALLOC(_a, _size) ((void)0)
+#define LOG_FREE(_a) ((void)0)
+
+#define LOG_DONE_LOADING(_a) ((void)0)
+#define PRINT_STATS(_a) ((void)0)
+
+#endif /* XPT_ARENA_LOGGING */
+
+/****************************************************/
+
+/* Block header for each block in the arena */
+typedef struct BLK_HDR BLK_HDR;
+struct BLK_HDR
+{
+ BLK_HDR *next;
+ size_t size;
+};
+
+#define XPT_MIN_BLOCK_SIZE 32
+
+/* XXX this is lame. Should clone the code to do this bitwise */
+#define ALIGN_RND(s,a) ((a)==1?(s):((((s)+(a)-1)/(a))*(a)))
+
+struct XPTArena
+{
+ BLK_HDR *first;
+ PRUint8 *next;
+ size_t space;
+ size_t alignment;
+ size_t block_size;
+ char *name;
+
+#ifdef XPT_ARENA_LOGGING
+ PRUint32 LOG_MallocCallCount;
+ PRUint32 LOG_MallocTotalBytesRequested;
+ PRUint32 LOG_MallocTotalBytesUsed;
+ PRUint32 LOG_FreeCallCount;
+ PRUint32 LOG_LoadingFreeCallCount;
+ PRUint32 LOG_RealMallocCallCount;
+ PRUint32 LOG_RealMallocTotalBytesRequested;
+#endif /* XPT_ARENA_LOGGING */
+};
+
+XPT_PUBLIC_API(XPTArena *)
+XPT_NewArena(PRUint32 block_size, size_t alignment, const char* name)
+{
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ XPTArena *arena = RTMemAllocZ(sizeof(XPTArena));
+#else
+ XPTArena *arena = calloc(1, sizeof(XPTArena));
+#endif
+ if (arena) {
+ XPT_ASSERT(alignment);
+ if (alignment > sizeof(double))
+ alignment = sizeof(double);
+ arena->alignment = alignment;
+
+ if (block_size < XPT_MIN_BLOCK_SIZE)
+ block_size = XPT_MIN_BLOCK_SIZE;
+ arena->block_size = ALIGN_RND(block_size, alignment);
+
+ /* must have room for at least one item! */
+ XPT_ASSERT(arena->block_size >=
+ ALIGN_RND(sizeof(BLK_HDR), alignment) +
+ ALIGN_RND(1, alignment));
+
+ if (name) {
+ arena->name = XPT_STRDUP(arena, name);
+#ifdef XPT_ARENA_LOGGING
+ /* fudge the stats since we are using space in the arena */
+ arena->LOG_MallocCallCount = 0;
+ arena->LOG_MallocTotalBytesRequested = 0;
+ arena->LOG_MallocTotalBytesUsed = 0;
+#endif /* XPT_ARENA_LOGGING */
+ }
+ }
+ return arena;
+}
+
+XPT_PUBLIC_API(void)
+XPT_DestroyArena(XPTArena *arena)
+{
+ BLK_HDR* cur;
+ BLK_HDR* next;
+
+ cur = arena->first;
+ while (cur) {
+ next = cur->next;
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(cur);
+#else
+ free(cur);
+#endif
+ cur = next;
+ }
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(arena);
+#else
+ free(arena);
+#endif
+}
+
+XPT_PUBLIC_API(void)
+XPT_DumpStats(XPTArena *arena)
+{
+ PRINT_STATS(arena);
+}
+
+
+/*
+* Our alignment rule is that we always round up the size of each allocation
+* so that the 'arena->next' pointer one will point to properly aligned space.
+*/
+
+XPT_PUBLIC_API(void *)
+XPT_ArenaMalloc(XPTArena *arena, size_t size)
+{
+ PRUint8 *cur;
+ size_t bytes;
+
+ if (!size)
+ return NULL;
+
+ if (!arena) {
+ XPT_ASSERT(0);
+ return NULL;
+ }
+
+ bytes = ALIGN_RND(size, arena->alignment);
+
+ LOG_MALLOC(arena, size, bytes);
+
+ if (bytes > arena->space) {
+ BLK_HDR* new_block;
+ size_t block_header_size = ALIGN_RND(sizeof(BLK_HDR), arena->alignment);
+ size_t new_space = arena->block_size;
+
+ if (bytes > new_space - block_header_size)
+ new_space += bytes;
+
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ new_block = (BLK_HDR*) RTMemAllocZ(new_space/arena->alignment * (size_t)arena->alignment);
+#else
+ new_block = (BLK_HDR*) calloc(new_space/arena->alignment,
+ arena->alignment);
+#endif
+ if (!new_block) {
+ arena->next = NULL;
+ arena->space = 0;
+ return NULL;
+ }
+
+ LOG_REAL_MALLOC(arena, new_space);
+
+ /* link block into the list of blocks for use when we destroy */
+ new_block->next = arena->first;
+ arena->first = new_block;
+
+ /* save other block header info */
+ new_block->size = new_space;
+
+ /* set info for current block */
+ arena->next = ((PRUint8*)new_block) + block_header_size;
+ arena->space = new_space - block_header_size;
+
+#ifdef DEBUG
+ /* mark block for corruption check */
+ memset(arena->next, 0xcd, arena->space);
+#endif
+ }
+
+#ifdef DEBUG
+ {
+ /* do corruption check */
+ size_t i;
+ for (i = 0; i < bytes; ++i) {
+ XPT_ASSERT(arena->next[i] == 0xcd);
+ }
+ /* we guarantee that the block will be filled with zeros */
+ memset(arena->next, 0, bytes);
+ }
+#endif
+
+ cur = arena->next;
+ arena->next += bytes;
+ arena->space -= bytes;
+
+ return cur;
+}
+
+
+XPT_PUBLIC_API(char *)
+XPT_ArenaStrDup(XPTArena *arena, const char * s)
+{
+ size_t len;
+ char* cur;
+
+ if (!s)
+ return NULL;
+
+ len = strlen(s)+1;
+ cur = XPT_ArenaMalloc(arena, len);
+ memcpy(cur, s, len);
+ return cur;
+}
+
+XPT_PUBLIC_API(void)
+XPT_NotifyDoneLoading(XPTArena *arena)
+{
+#ifdef XPT_ARENA_LOGGING
+ if (arena) {
+ LOG_DONE_LOADING(arena);
+ }
+#endif
+}
+
+XPT_PUBLIC_API(void)
+XPT_ArenaFree(XPTArena *arena, void *block)
+{
+ LOG_FREE(arena);
+}
+
+#ifdef XPT_ARENA_LOGGING
+static void xpt_DebugPrintArenaStats(XPTArena *arena)
+{
+ printf("()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()\n");
+ printf("Start xpt arena stats for \"%s\"\n",
+ arena->name ? arena->name : "unnamed arena");
+ printf("\n");
+ printf("%d times arena malloc called\n", (int) arena->LOG_MallocCallCount);
+ printf("%d total bytes requested from arena malloc\n", (int) arena->LOG_MallocTotalBytesRequested);
+ printf("%d average bytes requested per call to arena malloc\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesRequested/arena->LOG_MallocCallCount) : 0);
+ printf("%d average bytes used per call (accounts for alignment overhead)\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0);
+ printf("%d average bytes used per call (accounts for all overhead and waste)\n", (int)arena->LOG_MallocCallCount ? (arena->LOG_RealMallocTotalBytesRequested/arena->LOG_MallocCallCount) : 0);
+ printf("\n");
+ printf("%d during loading times arena free called\n", (int) arena->LOG_LoadingFreeCallCount);
+ printf("%d during loading approx total bytes not freed\n", (int) arena->LOG_LoadingFreeCallCount * (int) (arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0));
+ printf("\n");
+ printf("%d total times arena free called\n", (int) arena->LOG_FreeCallCount);
+ printf("%d approx total bytes not freed until arena destruction\n", (int) arena->LOG_FreeCallCount * (int) (arena->LOG_MallocCallCount ? (arena->LOG_MallocTotalBytesUsed/arena->LOG_MallocCallCount) : 0 ));
+ printf("\n");
+ printf("%d times arena called system malloc\n", (int) arena->LOG_RealMallocCallCount);
+ printf("%d total bytes arena requested from system\n", (int) arena->LOG_RealMallocTotalBytesRequested);
+ printf("%d byte block size specified at arena creation time\n", (int) arena->block_size);
+ printf("%d byte block alignment specified at arena creation time\n", (int) arena->alignment);
+ printf("\n");
+ printf("End xpt arena stats\n");
+ printf("()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()\n");
+}
+#endif
+
+/***************************************************************************/
+
+#ifdef DEBUG
+XPT_PUBLIC_API(void)
+XPT_AssertFailed(const char *s, const char *file, PRUint32 lineno)
+{
+ fprintf(stderr, "Assertion failed: %s, file %s, line %d\n",
+ s, file, lineno);
+ abort();
+}
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c
new file mode 100644
index 00000000..93435910
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c
@@ -0,0 +1,956 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/* Implementation of XDR routines for typelib structures. */
+
+#include "xpt_xdr.h"
+#include "xpt_struct.h"
+#include <string.h>
+#include <stdio.h>
+
+/***************************************************************************/
+/* Forward declarations. */
+
+static PRUint32
+SizeOfTypeDescriptor(XPTTypeDescriptor *td, XPTInterfaceDescriptor *id);
+
+static PRUint32
+SizeOfMethodDescriptor(XPTMethodDescriptor *md, XPTInterfaceDescriptor *id);
+
+static PRUint32
+SizeOfConstDescriptor(XPTConstDescriptor *cd, XPTInterfaceDescriptor *id);
+
+static PRUint32
+SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *id);
+
+static PRBool
+DoInterfaceDirectoryEntry(XPTArena *arena, XPTCursor *cursor,
+ XPTInterfaceDirectoryEntry *ide, PRUint16 entry_index);
+
+static PRBool
+DoConstDescriptor(XPTArena *arena, XPTCursor *cursor, XPTConstDescriptor *cd,
+ XPTInterfaceDescriptor *id);
+
+static PRBool
+DoMethodDescriptor(XPTArena *arena, XPTCursor *cursor, XPTMethodDescriptor *md,
+ XPTInterfaceDescriptor *id);
+
+static PRBool
+DoAnnotation(XPTArena *arena, XPTCursor *cursor, XPTAnnotation **annp);
+
+static PRBool
+DoInterfaceDescriptor(XPTArena *arena, XPTCursor *outer, XPTInterfaceDescriptor **idp);
+
+static PRBool
+DoTypeDescriptorPrefix(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp);
+
+static PRBool
+DoTypeDescriptor(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id);
+
+static PRBool
+DoParamDescriptor(XPTArena *arena, XPTCursor *cursor, XPTParamDescriptor *pd,
+ XPTInterfaceDescriptor *id);
+
+/***************************************************************************/
+
+XPT_PUBLIC_API(PRUint32)
+XPT_SizeOfHeader(XPTHeader *header)
+{
+ XPTAnnotation *ann, *last;
+ PRUint32 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(PRUint32)
+XPT_SizeOfHeaderBlock(XPTHeader *header)
+{
+ PRUint32 size = XPT_SizeOfHeader(header);
+
+ size += header->num_interfaces * sizeof (XPTInterfaceDirectoryEntry);
+
+ return size;
+}
+
+XPT_PUBLIC_API(XPTHeader *)
+XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces, PRUint8 major_version, PRUint8 minor_version)
+{
+ XPTHeader *header = XPT_NEWZAP(arena, XPTHeader);
+ if (!header)
+ return NULL;
+ memcpy(header->magic, XPT_MAGIC, 16);
+ header->major_version = major_version;
+ header->minor_version = minor_version;
+ header->num_interfaces = num_interfaces;
+ if (num_interfaces) {
+ header->interface_directory =
+ XPT_CALLOC(arena,
+ num_interfaces * sizeof(XPTInterfaceDirectoryEntry));
+ if (!header->interface_directory) {
+ XPT_DELETE(arena, header);
+ return NULL;
+ }
+ }
+ header->data_pool = 0; /* XXX do we even need this struct any more? */
+
+ return header;
+}
+
+XPT_PUBLIC_API(void)
+XPT_FreeHeader(XPTArena *arena, XPTHeader* aHeader)
+{
+ if (aHeader) {
+ XPTAnnotation* ann;
+ XPTInterfaceDirectoryEntry* entry = aHeader->interface_directory;
+ XPTInterfaceDirectoryEntry* end = entry + aHeader->num_interfaces;
+ for (; entry < end; entry++) {
+ XPT_DestroyInterfaceDirectoryEntry(arena, entry);
+ }
+
+ ann = aHeader->annotations;
+ while (ann) {
+ XPTAnnotation* next = ann->next;
+ if (XPT_ANN_IS_PRIVATE(ann->flags)) {
+ XPT_FREEIF(arena, ann->creator);
+ XPT_FREEIF(arena, ann->private_data);
+ }
+ XPT_DELETE(arena, ann);
+ ann = next;
+ }
+
+ XPT_FREEIF(arena, aHeader->interface_directory);
+ XPT_DELETE(arena, aHeader);
+ }
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoHeaderPrologue(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp, PRUint32 * ide_offset)
+{
+ XPTMode mode = cursor->state->mode;
+ unsigned int i;
+ XPTHeader * header;
+
+ if (mode == XPT_DECODE) {
+ header = XPT_NEWZAP(arena, XPTHeader);
+ if (!header)
+ return PR_FALSE;
+ *headerp = header;
+ } else {
+ header = *headerp;
+ }
+
+ if (mode == XPT_ENCODE) {
+ /* IDEs appear after header, including annotations */
+ if (ide_offset != NULL)
+ {
+ *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 < sizeof(header->magic); i++) {
+ if (!XPT_Do8(cursor, &header->magic[i]))
+ goto error;
+ }
+
+ if (mode == XPT_DECODE &&
+ strncmp((const char*)header->magic, XPT_MAGIC, 16) != 0)
+ {
+ /* Require that the header contain the proper magic */
+ fprintf(stderr,
+ "libxpt: bad magic header in input file; "
+ "found '%s', expected '%s'\n",
+ header->magic, XPT_MAGIC_STRING);
+ goto error;
+ }
+
+ if (!XPT_Do8(cursor, &header->major_version) ||
+ !XPT_Do8(cursor, &header->minor_version)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE &&
+ header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
+ /* This file is newer than we are and set to an incompatible version
+ * number. We must set the header state thusly and return.
+ */
+ header->num_interfaces = 0;
+ header->file_length = 0;
+ return PR_TRUE;
+ }
+
+ if (!XPT_Do16(cursor, &header->num_interfaces) ||
+ !XPT_Do32(cursor, &header->file_length) ||
+ (ide_offset != NULL && !XPT_Do32(cursor, ide_offset))) {
+ goto error;
+ }
+ return PR_TRUE;
+ /* XXX need to free child data sometimes! */
+ XPT_ERROR_HANDLE(arena, header);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoHeader(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp)
+{
+ const int HEADER_SIZE = 24;
+ XPTMode mode = cursor->state->mode;
+ XPTHeader * header;
+ PRUint32 ide_offset;
+ int i;
+ XPTAnnotation *ann, *next, **annp;
+
+ if (!XPT_DoHeaderPrologue(arena, cursor, headerp, &ide_offset))
+ return PR_FALSE;
+ header = *headerp;
+ /*
+ * Make sure the file length reported in the header is the same size as
+ * as our buffer unless it is zero (not set)
+ */
+ if (mode == XPT_DECODE && (header->file_length != 0 &&
+ cursor->state->pool->allocated < header->file_length)) {
+ fputs("libxpt: File length in header does not match actual length. File may be corrupt\n",
+ stderr);
+ 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->num_interfaces) {
+ header->interface_directory =
+ XPT_CALLOC(arena, header->num_interfaces *
+ sizeof(XPTInterfaceDirectoryEntry));
+ if (!header->interface_directory)
+ goto error;
+ }
+
+ /*
+ * Iterate through the annotations rather than recurring, to avoid blowing
+ * the stack on large xpt files.
+ */
+ ann = next = header->annotations;
+ annp = &header->annotations;
+ do {
+ ann = next;
+ if (!DoAnnotation(arena, cursor, &ann))
+ goto error;
+ if (mode == XPT_DECODE) {
+ /*
+ * Make sure that we store the address of the newly allocated
+ * annotation in the previous annotation's ``next'' slot, or
+ * header->annotations for the first one.
+ */
+ *annp = ann;
+ annp = &ann->next;
+ }
+ next = ann->next;
+ } while (!XPT_ANN_IS_LAST(ann->flags));
+
+ /* shouldn't be necessary now, but maybe later */
+ XPT_SeekTo(cursor, ide_offset);
+
+ for (i = 0; i < header->num_interfaces; i++) {
+ if (!DoInterfaceDirectoryEntry(arena, cursor,
+ &header->interface_directory[i],
+ (PRUint16)(i + 1)))
+ goto error;
+ }
+
+ return PR_TRUE;
+
+ /* XXX need to free child data sometimes! */
+ XPT_ERROR_HANDLE(arena, header);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_FillInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry *ide,
+ nsID *iid, char *name, char *name_space,
+ XPTInterfaceDescriptor *descriptor)
+{
+ XPT_COPY_IID(ide->iid, *iid);
+ ide->name = name ? XPT_STRDUP(arena, name) : NULL; /* what good is it w/o a name? */
+ ide->name_space = name_space ? XPT_STRDUP(arena, name_space) : NULL;
+ ide->interface_descriptor = descriptor;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(void)
+XPT_DestroyInterfaceDirectoryEntry(XPTArena *arena,
+ XPTInterfaceDirectoryEntry* ide)
+{
+ if (ide) {
+ if (ide->name) XPT_FREE(arena, ide->name);
+ if (ide->name_space) XPT_FREE(arena, ide->name_space);
+ XPT_FreeInterfaceDescriptor(arena, ide->interface_descriptor);
+ }
+}
+
+/* InterfaceDirectoryEntry records go in the header */
+PRBool
+DoInterfaceDirectoryEntry(XPTArena *arena, XPTCursor *cursor,
+ XPTInterfaceDirectoryEntry *ide, PRUint16 entry_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(arena, cursor, &(ide->name)) ||
+
+ /* write the name_space string in the data pool, and the offset in our
+ cursor space */
+ !XPT_DoCString(arena, cursor, &(ide->name_space)) ||
+
+ /* do InterfaceDescriptors -- later, only on encode (see below) */
+ !DoInterfaceDescriptor(arena, cursor, &ide->interface_descriptor)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE)
+ XPT_SetOffsetForAddr(cursor, ide, entry_index);
+
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, ide);
+}
+
+XPT_PUBLIC_API(XPTInterfaceDescriptor *)
+XPT_NewInterfaceDescriptor(XPTArena *arena,
+ PRUint16 parent_interface, PRUint16 num_methods,
+ PRUint16 num_constants, PRUint8 flags)
+{
+
+ XPTInterfaceDescriptor *id = XPT_NEWZAP(arena, XPTInterfaceDescriptor);
+ if (!id)
+ return NULL;
+
+ if (num_methods) {
+ id->method_descriptors = XPT_CALLOC(arena, num_methods *
+ sizeof(XPTMethodDescriptor));
+ if (!id->method_descriptors)
+ goto free_id;
+ id->num_methods = num_methods;
+ }
+
+ if (num_constants) {
+ id->const_descriptors = XPT_CALLOC(arena, num_constants *
+ sizeof(XPTConstDescriptor));
+ if (!id->const_descriptors)
+ goto free_meth;
+ id->num_constants = num_constants;
+ }
+
+ if (parent_interface) {
+ id->parent_interface = parent_interface;
+ } else {
+ id->parent_interface = 0;
+ }
+
+ id->flags = flags;
+
+ return id;
+
+ free_meth:
+ XPT_FREEIF(arena, id->method_descriptors);
+ free_id:
+ XPT_DELETE(arena, id);
+ return NULL;
+}
+
+XPT_PUBLIC_API(void)
+XPT_FreeInterfaceDescriptor(XPTArena *arena, XPTInterfaceDescriptor* id)
+{
+ if (id) {
+ XPTMethodDescriptor *md, *mdend;
+ XPTConstDescriptor *cd, *cdend;
+
+ /* Free up method descriptors */
+ md = id->method_descriptors;
+ mdend = md + id->num_methods;
+ for (; md < mdend; md++) {
+ XPT_FREEIF(arena, md->name);
+ XPT_FREEIF(arena, md->params);
+ XPT_FREEIF(arena, md->result);
+ }
+ XPT_FREEIF(arena, id->method_descriptors);
+
+ /* Free up const descriptors */
+ cd = id->const_descriptors;
+ cdend = cd + id->num_constants;
+ for (; cd < cdend; cd++) {
+ XPT_FREEIF(arena, cd->name);
+ }
+ XPT_FREEIF(arena, id->const_descriptors);
+
+ /* Free up type descriptors */
+ XPT_FREEIF(arena, id->additional_types);
+
+ XPT_DELETE(arena, id);
+ }
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddTypes(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num)
+{
+ XPTTypeDescriptor *old = id->additional_types;
+ XPTTypeDescriptor *new;
+ size_t old_size = id->num_additional_types * sizeof(XPTTypeDescriptor);
+ size_t new_size = (num * sizeof(XPTTypeDescriptor)) + old_size;
+
+ /* XXX should grow in chunks to minimize alloc overhead */
+ new = XPT_CALLOC(arena, new_size);
+ if (!new)
+ return PR_FALSE;
+ if (old) {
+ if (old_size)
+ memcpy(new, old, old_size);
+ XPT_FREE(arena, old);
+ }
+ id->additional_types = new;
+ id->num_additional_types += num;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddMethods(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num)
+{
+ XPTMethodDescriptor *old = id->method_descriptors;
+ XPTMethodDescriptor *new;
+ size_t old_size = id->num_methods * sizeof(XPTMethodDescriptor);
+ size_t new_size = (num * sizeof(XPTMethodDescriptor)) + old_size;
+
+ /* XXX should grow in chunks to minimize alloc overhead */
+ new = XPT_CALLOC(arena, new_size);
+ if (!new)
+ return PR_FALSE;
+ if (old) {
+ if (old_size)
+ memcpy(new, old, old_size);
+ XPT_FREE(arena, old);
+ }
+ id->method_descriptors = new;
+ id->num_methods += num;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_InterfaceDescriptorAddConsts(XPTArena *arena, XPTInterfaceDescriptor *id,
+ PRUint16 num)
+{
+ XPTConstDescriptor *old = id->const_descriptors;
+ XPTConstDescriptor *new;
+ size_t old_size = id->num_constants * sizeof(XPTConstDescriptor);
+ size_t new_size = (num * sizeof(XPTConstDescriptor)) + old_size;
+
+ /* XXX should grow in chunks to minimize alloc overhead */
+ new = XPT_CALLOC(arena, new_size);
+ if (!new)
+ return PR_FALSE;
+ if (old) {
+ if (old_size)
+ memcpy(new, old, old_size);
+ XPT_FREE(arena, old);
+ }
+ id->const_descriptors = new;
+ id->num_constants += num;
+ return PR_TRUE;
+}
+
+PRUint32
+SizeOfTypeDescriptor(XPTTypeDescriptor *td, XPTInterfaceDescriptor *id)
+{
+ PRUint32 size = 1; /* prefix */
+
+ switch (XPT_TDP_TAG(td->prefix)) {
+ case TD_INTERFACE_TYPE:
+ size += 2; /* interface_index */
+ break;
+ case TD_INTERFACE_IS_TYPE:
+ size += 1; /* argnum */
+ break;
+ case TD_ARRAY:
+ size += 2 + SizeOfTypeDescriptor(
+ &id->additional_types[td->type.additional_type], id);
+ break;
+ case TD_PSTRING_SIZE_IS:
+ size += 2; /* argnum + argnum2 */
+ break;
+ case TD_PWSTRING_SIZE_IS:
+ size += 2; /* argnum + argnum2 */
+ break;
+ default:
+ /* nothing special */
+ break;
+ }
+ return size;
+}
+
+PRUint32
+SizeOfMethodDescriptor(XPTMethodDescriptor *md, XPTInterfaceDescriptor *id)
+{
+ PRUint32 i, size = 1 /* flags */ + 4 /* name */ + 1 /* num_args */;
+
+ for (i = 0; i < md->num_args; i++)
+ size += 1 + SizeOfTypeDescriptor(&md->params[i].type, id);
+
+ size += 1 + SizeOfTypeDescriptor(&md->result->type, id);
+ return size;
+}
+
+PRUint32
+SizeOfConstDescriptor(XPTConstDescriptor *cd, XPTInterfaceDescriptor *id)
+{
+ PRUint32 size = 4 /* name */ + SizeOfTypeDescriptor(&cd->type, id);
+
+ 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_PSTRING:
+ 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;
+}
+
+PRUint32
+SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *id)
+{
+ PRUint32 size = 2 /* parent interface */ + 2 /* num_methods */
+ + 2 /* num_constants */ + 1 /* flags */, i;
+ for (i = 0; i < id->num_methods; i++)
+ size += SizeOfMethodDescriptor(&id->method_descriptors[i], id);
+ for (i = 0; i < id->num_constants; i++)
+ size += SizeOfConstDescriptor(&id->const_descriptors[i], id);
+ return size;
+}
+
+PRBool
+DoInterfaceDescriptor(XPTArena *arena, XPTCursor *outer,
+ XPTInterfaceDescriptor **idp)
+{
+ XPTMode mode = outer->state->mode;
+ XPTInterfaceDescriptor *id;
+ XPTCursor curs, *cursor = &curs;
+ PRUint32 i, id_sz = 0;
+
+ if (mode == XPT_DECODE) {
+ id = XPT_NEWZAP(arena, XPTInterfaceDescriptor);
+ if (!id)
+ return PR_FALSE;
+ *idp = id;
+ } else {
+ id = *idp;
+ if (!id) {
+ id_sz = 0;
+ return XPT_Do32(outer, &id_sz);
+ }
+ id_sz = 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) {
+ XPT_DELETE(arena, *idp);
+ return PR_TRUE;
+ }
+ if(!XPT_Do16(cursor, &id->parent_interface) ||
+ !XPT_Do16(cursor, &id->num_methods)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE && id->num_methods) {
+ id->method_descriptors = XPT_CALLOC(arena, id->num_methods *
+ sizeof(XPTMethodDescriptor));
+ if (!id->method_descriptors)
+ goto error;
+ }
+
+ for (i = 0; i < id->num_methods; i++) {
+ if (!DoMethodDescriptor(arena, cursor, &id->method_descriptors[i], id))
+ goto error;
+ }
+
+ if (!XPT_Do16(cursor, &id->num_constants)) {
+ goto error;
+ }
+
+ if (mode == XPT_DECODE && id->num_constants) {
+ id->const_descriptors = XPT_CALLOC(arena, id->num_constants *
+ sizeof(XPTConstDescriptor));
+ if (!id->const_descriptors)
+ goto error;
+ }
+
+ for (i = 0; i < id->num_constants; i++) {
+ if (!DoConstDescriptor(arena, cursor, &id->const_descriptors[i], id)) {
+ goto error;
+ }
+ }
+
+ if (!XPT_Do8(cursor, &id->flags)) {
+ goto error;
+ }
+
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, id);
+}
+
+PRBool
+DoConstDescriptor(XPTArena *arena, XPTCursor *cursor, XPTConstDescriptor *cd,
+ XPTInterfaceDescriptor *id)
+{
+ PRBool ok = PR_FALSE;
+
+ if (!XPT_DoCString(arena, cursor, &cd->name) ||
+ !DoTypeDescriptor(arena, cursor, &cd->type, id)) {
+
+ return PR_FALSE;
+ }
+
+ switch(XPT_TDP_TAG(cd->type.prefix)) {
+ case TD_INT8:
+ ok = XPT_Do8(cursor, (PRUint8*) &cd->value.i8);
+ break;
+ case TD_INT16:
+ ok = XPT_Do16(cursor, (PRUint16*) &cd->value.i16);
+ break;
+ case TD_INT32:
+ ok = XPT_Do32(cursor, (PRUint32*) &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, (PRInt64 *)&cd->value.ui64);
+ break;
+ case TD_CHAR:
+ ok = XPT_Do8(cursor, (PRUint8*) &cd->value.ch);
+ break;
+ case TD_WCHAR:
+ ok = XPT_Do16(cursor, &cd->value.wch);
+ break;
+ /* fall-through */
+ default:
+ fprintf(stderr, "illegal type!\n");
+ break;
+ }
+
+ return ok;
+
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_FillMethodDescriptor(XPTArena *arena, XPTMethodDescriptor *meth,
+ PRUint8 flags, char *name, PRUint8 num_args)
+{
+ meth->flags = flags & XPT_MD_FLAGMASK;
+ meth->name = XPT_STRDUP(arena, name);
+ if (!meth->name)
+ return PR_FALSE;
+ meth->num_args = num_args;
+ if (num_args) {
+ meth->params = XPT_CALLOC(arena, num_args * sizeof(XPTParamDescriptor));
+ if (!meth->params)
+ goto free_name;
+ } else {
+ meth->params = NULL;
+ }
+ meth->result = XPT_NEWZAP(arena, XPTParamDescriptor);
+ if (!meth->result)
+ goto free_params;
+ return PR_TRUE;
+
+ free_params:
+ XPT_DELETE(arena, meth->params);
+ free_name:
+ XPT_DELETE(arena, meth->name);
+ return PR_FALSE;
+}
+
+PRBool
+DoMethodDescriptor(XPTArena *arena, XPTCursor *cursor, XPTMethodDescriptor *md,
+ XPTInterfaceDescriptor *id)
+{
+ XPTMode mode = cursor->state->mode;
+ int i;
+
+ if (!XPT_Do8(cursor, &md->flags) ||
+ !XPT_DoCString(arena, cursor, &md->name) ||
+ !XPT_Do8(cursor, &md->num_args))
+ return PR_FALSE;
+
+ if (mode == XPT_DECODE && md->num_args) {
+ md->params = XPT_CALLOC(arena, md->num_args * sizeof(XPTParamDescriptor));
+ if (!md->params)
+ return PR_FALSE;
+ }
+
+ for(i = 0; i < md->num_args; i++) {
+ if (!DoParamDescriptor(arena, cursor, &md->params[i], id))
+ goto error;
+ }
+
+ if (mode == XPT_DECODE) {
+ md->result = XPT_NEWZAP(arena, XPTParamDescriptor);
+ if (!md->result)
+ return PR_FALSE;
+ }
+
+ if (!md->result ||
+ !DoParamDescriptor(arena, cursor, md->result, id))
+ goto error;
+
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, md->params);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_FillParamDescriptor(XPTArena *arena, XPTParamDescriptor *pd, PRUint8 flags,
+ XPTTypeDescriptor *type)
+{
+ pd->flags = flags & XPT_PD_FLAGMASK;
+ XPT_COPY_TYPE(pd->type, *type);
+ return PR_TRUE;
+}
+
+PRBool
+DoParamDescriptor(XPTArena *arena, XPTCursor *cursor, XPTParamDescriptor *pd,
+ XPTInterfaceDescriptor *id)
+{
+ if (!XPT_Do8(cursor, &pd->flags) ||
+ !DoTypeDescriptor(arena, cursor, &pd->type, id))
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
+PRBool
+DoTypeDescriptorPrefix(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp)
+{
+ return XPT_Do8(cursor, &tdp->flags);
+}
+
+PRBool
+DoTypeDescriptor(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id)
+{
+ if (!DoTypeDescriptorPrefix(arena, cursor, &td->prefix)) {
+ goto error;
+ }
+
+ switch (XPT_TDP_TAG(td->prefix)) {
+ case TD_INTERFACE_TYPE:
+ if (!XPT_Do16(cursor, &td->type.iface))
+ goto error;
+ break;
+ case TD_INTERFACE_IS_TYPE:
+ if (!XPT_Do8(cursor, &td->argnum))
+ goto error;
+ break;
+ case TD_ARRAY:
+ if (!XPT_Do8(cursor, &td->argnum) ||
+ !XPT_Do8(cursor, &td->argnum2))
+ goto error;
+
+ if (cursor->state->mode == XPT_DECODE) {
+ if(!XPT_InterfaceDescriptorAddTypes(arena, id, 1))
+ goto error;
+ td->type.additional_type = id->num_additional_types - 1;
+ }
+
+ if (!DoTypeDescriptor(arena, cursor,
+ &id->additional_types[td->type.additional_type],
+ id))
+ goto error;
+ break;
+ case TD_PSTRING_SIZE_IS:
+ case TD_PWSTRING_SIZE_IS:
+ if (!XPT_Do8(cursor, &td->argnum) ||
+ !XPT_Do8(cursor, &td->argnum2))
+ goto error;
+ break;
+
+ default:
+ /* nothing special */
+ break;
+ }
+ return PR_TRUE;
+
+ XPT_ERROR_HANDLE(arena, td);
+}
+
+XPT_PUBLIC_API(XPTAnnotation *)
+XPT_NewAnnotation(XPTArena *arena, PRUint8 flags, XPTString *creator,
+ XPTString *private_data)
+{
+ XPTAnnotation *ann = XPT_NEWZAP(arena, 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(XPTArena *arena, XPTCursor *cursor, XPTAnnotation **annp)
+{
+ XPTMode mode = cursor->state->mode;
+ XPTAnnotation *ann;
+
+ if (mode == XPT_DECODE) {
+ ann = XPT_NEWZAP(arena, 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(arena, cursor, &ann->creator) ||
+ !XPT_DoStringInline(arena, cursor, &ann->private_data))
+ goto error_2;
+ }
+
+ return PR_TRUE;
+
+ error_2:
+ if (ann && XPT_ANN_IS_PRIVATE(ann->flags)) {
+ XPT_FREEIF(arena, ann->creator);
+ XPT_FREEIF(arena, ann->private_data);
+ }
+ XPT_ERROR_HANDLE(arena, ann);
+}
+
+PRBool
+XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
+ PRUint16 num_interfaces, char *name,
+ PRUint16 *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;
+}
+
+static XPT_TYPELIB_VERSIONS_STRUCT versions[] = XPT_TYPELIB_VERSIONS;
+#define XPT_TYPELIB_VERSIONS_COUNT (sizeof(versions) / sizeof(versions[0]))
+
+XPT_PUBLIC_API(PRUint16)
+XPT_ParseVersionString(const char* str, PRUint8* major, PRUint8* minor)
+{
+ int i;
+ for (i = 0; i < XPT_TYPELIB_VERSIONS_COUNT; i++) {
+ if (!strcmp(versions[i].str, str)) {
+ *major = versions[i].major;
+ *minor = versions[i].minor;
+ return versions[i].code;
+ }
+ }
+ return XPT_VERSION_UNKNOWN;
+}
+
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c
new file mode 100644
index 00000000..cd9261d0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c
@@ -0,0 +1,665 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/* Implementation of XDR primitives. */
+
+#include "xpt_xdr.h"
+#include "nspr.h"
+#include <string.h> /* strchr */
+
+static PRBool
+CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, PRUint32 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 \
+ : (XPT_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)])
+
+#if defined(DEBUG_shaver) || defined(DEBUG_jband) || defined(DEBUG_mccabe)
+#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->arena, \
+ (cursor)->state->pool, \
+ (cursor)->state->pool->allocated, \
+ 0, CURS_POOL_OFFSET(cursor) + (space)) \
+ /* 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 \
+ : (XPT_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
+
+/*
+ * quick and dirty hardcoded hashtable, to avoid dependence on nspr or glib.
+ * XXXmccabe it might turn out that we could use a simpler data structure here.
+ */
+typedef struct XPTHashRecord {
+ void *key;
+ void *value;
+ struct XPTHashRecord *next;
+} XPTHashRecord;
+
+#define XPT_HASHSIZE 512
+
+struct XPTHashTable { /* it's already typedef'ed from before. */
+ XPTHashRecord *buckets[XPT_HASHSIZE];
+ XPTArena *arena;
+};
+
+static XPTHashTable *
+XPT_NewHashTable(XPTArena *arena) {
+ XPTHashTable *table;
+ table = XPT_NEWZAP(arena, XPTHashTable);
+ if (table)
+ table->arena = arena;
+ return table;
+}
+
+static void trimrecord(XPTArena* arena, XPTHashRecord *record) {
+ if (record == NULL)
+ return;
+ trimrecord(arena, record->next);
+ XPT_DELETE(arena, record);
+}
+
+static void
+XPT_HashTableDestroy(XPTHashTable *table) {
+ int i;
+ for (i = 0; i < XPT_HASHSIZE; i++)
+ trimrecord(table->arena, table->buckets[i]);
+ XPT_FREE(table->arena, table);
+}
+
+static void *
+XPT_HashTableAdd(XPTHashTable *table, void *key, void *value) {
+ XPTHashRecord **bucketloc = table->buckets +
+ (((PRUint32)(uintptr_t)key) % XPT_HASHSIZE);
+ XPTHashRecord *bucket;
+
+ while (*bucketloc != NULL)
+ bucketloc = &((*bucketloc)->next);
+
+ bucket = XPT_NEW(table->arena, XPTHashRecord);
+ bucket->key = key;
+ bucket->value = value;
+ bucket->next = NULL;
+ *bucketloc = bucket;
+ return value;
+}
+
+static void *
+XPT_HashTableLookup(XPTHashTable *table, void *key) {
+ XPTHashRecord *bucket = table->buckets[(PRUint32)(uintptr_t)key % XPT_HASHSIZE];
+ while (bucket != NULL) {
+ if (bucket->key == key)
+ return bucket->value;
+ bucket = bucket->next;
+ }
+ return NULL;
+}
+
+XPT_PUBLIC_API(XPTState *)
+XPT_NewXDRState(XPTMode mode, char *data, PRUint32 len)
+{
+ XPTState *state;
+ XPTArena *arena;
+
+ arena = XPT_NewArena(512, sizeof(double), "an XDRState");
+ if (!arena)
+ return NULL;
+
+ state = XPT_NEWZAP(arena, XPTState);
+ if (!state)
+ goto err_free_arena;
+
+ state->arena = arena;
+ state->mode = mode;
+ state->pool = XPT_NEW(arena, 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 = XPT_NewHashTable(arena);
+
+ 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 = XPT_MALLOC(arena, XPT_GROW_CHUNK);
+ if (!state->pool->data)
+ goto err_free_hash;
+ state->pool->allocated = XPT_GROW_CHUNK;
+ }
+
+ return state;
+
+ err_free_hash:
+ XPT_HashTableDestroy(state->pool->offset_map);
+ err_free_pool:
+ XPT_DELETE(arena, state->pool);
+ err_free_state:
+ XPT_DELETE(arena, state);
+ err_free_arena:
+ if (arena)
+ XPT_DestroyArena(arena);
+ return NULL;
+}
+
+XPT_PUBLIC_API(void)
+XPT_DestroyXDRState(XPTState *state)
+{
+ XPTArena *arena = state->arena;
+
+ if (state->pool->offset_map)
+ XPT_HashTableDestroy(state->pool->offset_map);
+ if (state->mode == XPT_ENCODE)
+ XPT_DELETE(arena, state->pool->data);
+ XPT_DELETE(arena, state->pool);
+ XPT_DELETE(arena, state);
+ if (arena)
+ XPT_DestroyArena(arena);
+}
+
+XPT_PUBLIC_API(void)
+XPT_GetXDRDataLength(XPTState *state, XPTPool pool, PRUint32 *len)
+{
+ *len = state->next_cursor[pool] - 1;
+}
+
+XPT_PUBLIC_API(void)
+XPT_GetXDRData(XPTState *state, XPTPool pool, char **data, PRUint32 *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, PRUint32 *data_offsetp)
+{
+ if (state->mode == XPT_DECODE)
+ XPT_SetDataOffset(state, *data_offsetp);
+ else
+ *data_offsetp = state->data_offset;
+}
+
+/* if 'exact' is set use that, else grow by the next chunk but
+ * be sure to grow no less that 'at_least' so that we can't get
+ * behind on required space.
+ */
+static PRBool
+GrowPool(XPTArena *arena, XPTDatapool *pool, PRUint32 old_size,
+ PRUint32 exact, PRUint32 at_least)
+{
+ PRUint32 total_size;
+ char *newdata;
+
+ if (exact) {
+ XPT_ASSERT(exact > pool->allocated);
+ total_size = exact;
+ } else {
+ total_size = pool->allocated + XPT_GROW_CHUNK;
+ if (at_least > total_size)
+ total_size = at_least;
+ }
+
+ newdata = XPT_MALLOC(arena, total_size);
+ if (!newdata)
+ return PR_FALSE;
+ if (pool->data) {
+ if (old_size)
+ memcpy(newdata, pool->data, old_size);
+ XPT_FREE(arena, pool->data);
+ }
+ pool->data = newdata;
+ pool->allocated = total_size;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(void)
+XPT_SetDataOffset(XPTState *state, PRUint32 data_offset)
+{
+ state->data_offset = data_offset;
+ /* make sure we've allocated enough space for the header */
+ if (state->mode == XPT_ENCODE &&
+ data_offset > state->pool->allocated) {
+ (void)GrowPool(state->arena, state->pool, state->pool->allocated,
+ data_offset, 0);
+ }
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_MakeCursor(XPTState *state, XPTPool pool, PRUint32 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, PRUint32 offset)
+{
+ /* XXX do some real checking and update len and stuff */
+ cursor->offset = offset;
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(XPTString *)
+XPT_NewString(XPTArena *arena, PRUint16 length, char *bytes)
+{
+ XPTString *str = XPT_NEW(arena, XPTString);
+ if (!str)
+ return NULL;
+ str->length = length;
+ /* Alloc one extra to store the trailing nul. */
+ str->bytes = XPT_MALLOC(arena, length + 1u);
+ if (!str->bytes) {
+ XPT_DELETE(arena, str);
+ return NULL;
+ }
+ memcpy(str->bytes, bytes, length);
+ /* nul-terminate it. */
+ str->bytes[length] = '\0';
+ return str;
+}
+
+XPT_PUBLIC_API(XPTString *)
+XPT_NewStringZ(XPTArena *arena, char *bytes)
+{
+ PRUint32 length = strlen(bytes);
+ if (length > 0xffff)
+ return NULL; /* too long */
+ return XPT_NewString(arena, (PRUint16)length, bytes);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoStringInline(XPTArena *arena, XPTCursor *cursor, XPTString **strp)
+{
+ XPTString *str = *strp;
+ XPTMode mode = cursor->state->mode;
+ int i;
+
+ if (mode == XPT_DECODE) {
+ str = XPT_NEWZAP(arena, XPTString);
+ if (!str)
+ return PR_FALSE;
+ *strp = str;
+ }
+
+ if (!XPT_Do16(cursor, &str->length))
+ goto error;
+
+ if (mode == XPT_DECODE)
+ if (!(str->bytes = XPT_MALLOC(arena, str->length + 1u)))
+ goto error;
+
+ for (i = 0; i < str->length; i++)
+ if (!XPT_Do8(cursor, (PRUint8 *)&str->bytes[i]))
+ goto error_2;
+
+ if (mode == XPT_DECODE)
+ str->bytes[str->length] = 0;
+
+ return PR_TRUE;
+ error_2:
+ XPT_DELETE(arena, str->bytes);
+ error:
+ XPT_DELETE(arena, str);
+ return PR_FALSE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoString(XPTArena *arena, 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(arena, &my_cursor, strp);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_DoCString(XPTArena *arena, XPTCursor *cursor, char **identp)
+{
+ XPTCursor my_cursor;
+ char *ident = *identp;
+ PRUint32 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;
+ XPT_ASSERT(len > 0);
+
+ ident = XPT_MALLOC(arena, len + 1u);
+ if (!ident)
+ return PR_FALSE;
+
+ memcpy(ident, start, (size_t)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, (PRUint8 *)ident++))
+ return PR_FALSE;
+ if (!XPT_Do8(&my_cursor, (PRUint8 *)ident)) /* write trailing zero */
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
+/* XXXjband it bothers me that this is one hashtable instead of two.
+ */
+XPT_PUBLIC_API(PRUint32)
+XPT_GetOffsetForAddr(XPTCursor *cursor, void *addr)
+{
+ return (PRUint32)(uintptr_t)XPT_HashTableLookup(cursor->state->pool->offset_map, addr);
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_SetOffsetForAddr(XPTCursor *cursor, void *addr, PRUint32 offset)
+{
+ return XPT_HashTableAdd(cursor->state->pool->offset_map,
+ addr, (void *)(uintptr_t)offset) != NULL;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_SetAddrForOffset(XPTCursor *cursor, PRUint32 offset, void *addr)
+{
+ return XPT_HashTableAdd(cursor->state->pool->offset_map,
+ (void *)(uintptr_t)offset, addr) != NULL;
+}
+
+XPT_PUBLIC_API(void *)
+XPT_GetAddrForOffset(XPTCursor *cursor, PRUint32 offset)
+{
+ return XPT_HashTableLookup(cursor->state->pool->offset_map, (void *)(uintptr_t)offset);
+}
+
+/* Used by XPT_PREAMBLE_NO_ALLOC. */
+static PRBool
+CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, PRUint32 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, (PRUint8 *)&iidp->m3[i]))
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
+XPT_PUBLIC_API(PRBool)
+XPT_Do64(XPTCursor *cursor, PRInt64 *u64p)
+{
+ return XPT_Do32(cursor, (PRUint32 *)u64p) &&
+ XPT_Do32(cursor, ((PRUint32 *)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, PRUint32 *u32p)
+{
+ union {
+ PRUint8 b8[4];
+ PRUint32 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, PRUint16 *u16p)
+{
+ union {
+ PRUint8 b8[2];
+ PRUint16 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, PRUint8 *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;
+}
+
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore
new file mode 100644
index 00000000..ebc62d94
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+PrimitiveTest
+SimpleTypeLib
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in
new file mode 100644
index 00000000..afdc31b3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in
@@ -0,0 +1,59 @@
+#
+# ***** 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):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of 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 *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+CPP_PROG_LINK = 1
+
+SIMPLE_PROGRAMS = PrimitiveTest$(BIN_SUFFIX) SimpleTypeLib$(BIN_SUFFIX)
+
+CSRCS = PrimitiveTest.c SimpleTypeLib.c
+
+LIBS = \
+ $(XPCOM_LIBS) \
+ $(NSPR_LIBS) \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -DEXPORT_XPT_API
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c
new file mode 100644
index 00000000..aad33ccc
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c
@@ -0,0 +1,157 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/* Test the xdr primitives from xpt_xdr.c */
+
+#include "xpt_xdr.h"
+#include <stdio.h>
+#include <string.h> /* for memcpy */
+
+#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 {
+ PRUint32 bit32;
+ PRUint16 bit16;
+ PRUint8 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(XPTArena *arena, 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(arena, cursor, &str->cstr));
+ TRY("DoString", XPT_DoString(arena, cursor, &str->str));
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ XPTArena *arena;
+ XPTState *state;
+ XPTCursor curs, *cursor = &curs;
+ char *header, *data, *whole;
+ PRUint32 hlen, dlen, i;
+
+ TRY("XPT_NewArena", (arena = XPT_NewArena(1024, sizeof(double), "main")));
+
+ 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(arena, 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(arena, cursor, &output))
+ return 1;
+
+ dump_struct("after", &output);
+ XPT_DestroyXDRState(state);
+ XPT_DestroyArena(arena);
+ free(whole);
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c
new file mode 100644
index 00000000..305b8520
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c
@@ -0,0 +1,192 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/* Test the structure creation and serialization APIs from xpt_struct.c */
+#include <stdio.h>
+
+#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;
+
+int
+main(int argc, char **argv)
+{
+ XPTArena *arena;
+ XPTHeader *header;
+ XPTAnnotation *ann;
+ XPTInterfaceDescriptor *id;
+ XPTMethodDescriptor *meth;
+
+ XPTState *state;
+ XPTCursor curs, *cursor = &curs;
+ char *data, *head;
+ FILE *out;
+ PRUint32 len, header_sz;
+
+ PRBool ok;
+
+ td_void.prefix.flags = TD_VOID;
+
+#ifdef XP_MAC
+ if (argc == 0) {
+ static char* args[] = { "SimpleTypeLib", "simple.xpt", NULL };
+ argc = 2;
+ argv = args;
+ }
+#endif
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <filename.xpt>\n"
+ " Creates a simple typelib file.\n", argv[0]);
+
+ return 1;
+ }
+
+ arena = XPT_NewArena(1024, sizeof(double), "main");
+ TRY("XPT_NewArena", arena);
+
+ /* construct a header */
+ header = XPT_NewHeader(arena, 1, XPT_MAJOR_VERSION, XPT_MINOR_VERSION);
+ TRY("NewHeader", header);
+
+
+ ann = XPT_NewAnnotation(arena, XPT_ANN_LAST | XPT_ANN_PRIVATE,
+ XPT_NewStringZ(arena, "SimpleTypeLib 1.0"),
+ XPT_NewStringZ(arena, "See You In Rome"));
+ TRY("NewAnnotation", ann);
+ header->annotations = ann;
+
+ header_sz = XPT_SizeOfHeaderBlock(header);
+
+ id = XPT_NewInterfaceDescriptor(arena, 0, 2, 2, 0);
+ TRY("NewInterfaceDescriptor", id);
+
+ ok = XPT_FillInterfaceDirectoryEntry(arena, header->interface_directory, &iid,
+ "Interface", "NS", id);
+ TRY("FillInterfaceDirectoryEntry", ok);
+
+ /* void method1(void) */
+ meth = &id->method_descriptors[0];
+ ok = XPT_FillMethodDescriptor(arena, 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(arena, meth, 0, "method2", 2);
+ TRY("FillMethodDescriptor", ok);
+
+ meth->result->flags = 0;
+ meth->result->type.prefix.flags = TD_PSTRING | 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;
+
+#if 0
+ /* 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(arena, "ossifrage");
+#endif
+
+ /* 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(arena, cursor, &header);
+ TRY("DoHeader", ok);
+
+ out = fopen(argv[1], "wb");
+ 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);
+
+ if (ferror(out) != 0 || fclose(out) != 0) {
+ fprintf(stderr, "\nError writing file: %s\n\n", argv[1]);
+ } else {
+ fprintf(stderr, "\nFile written: %s\n\n", argv[1]);
+ }
+ XPT_DestroyXDRState(state);
+
+ XPT_FreeHeader(arena, header);
+ XPT_DestroyArena(arena);
+
+ return 0;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore
new file mode 100644
index 00000000..985cc7a7
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+xpt_dump
+xpt_link
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in
new file mode 100644
index 00000000..bedece8e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in
@@ -0,0 +1,90 @@
+#
+# ***** 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):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of 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 *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom
+INTERNAL_TOOLS = 1
+
+SIMPLE_PROGRAMS = xpt_dump$(BIN_SUFFIX) xpt_link$(BIN_SUFFIX)
+
+CSRCS = xpt_dump.c xpt_link.c
+
+SDK_BINARY = \
+ $(SIMPLE_PROGRAMS) \
+ $(NULL)
+
+ifdef CROSS_COMPILE
+HOST_SIMPLE_PROGRAMS = $(addprefix host_, $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=$(HOST_BIN_SUFFIX)))
+HOST_CSRCS = $(CSRCS)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+# Compile directly against the static lib, so we can use the tools
+# during the build without the shared library path being set.
+ifeq ($(OS_ARCH),WINNT)
+DEFINES += -DEXPORT_XPT_API
+endif
+
+LIBS = $(DIST)/lib/$(LIB_PREFIX)xpt.$(LIB_SUFFIX)
+
+# Tell the $(SIMPLE_PROGRAMS) target that we need to be recompiled
+# when libxpt changes.
+EXTRA_DEPS = $(wildcard $(DIST)/lib/$(LIB_PREFIX)xpt.*)
+
+ifdef CROSS_COMPILE
+HOST_LIBS = $(DIST)/host/lib/libhostxpt.$(LIB_SUFFIX)
+HOST_EXTRA_DEPS = $(wildcard $(DIST)/host/lib/libhostxpt.*)
+
+ifdef HOST_NSPR_MDCPUCFG
+HOST_CFLAGS += -DMDCPUCFG=$(HOST_NSPR_MDCPUCFG)
+endif
+endif
+
+
+# Build xpt_link and xpt_dump early. (libs creates .deps used by libs.)
+export::
+ @$(MAKE) libs
+
+
+
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c
new file mode 100644
index 00000000..8926b9c9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c
@@ -0,0 +1,941 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/*
+ * A utility for dumping the contents of a typelib file (.xpt) to screen
+ */
+
+#include "xpt_xdr.h"
+#include <stdio.h>
+#ifdef XP_MAC
+#include <stat.h>
+#include <StandardFile.h>
+#include "FullPath.h"
+#else
+#ifdef XP_OS2_EMX
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include "prprf.h"
+
+#define BASE_INDENT 3
+
+static char *type_array[32] =
+ {"int8", "int16", "int32", "int64",
+ "uint8", "uint16", "uint32", "uint64",
+ "float", "double", "boolean", "char",
+ "wchar_t", "void", "reserved", "reserved",
+ "reserved", "reserved", "reserved", "reserved",
+ "reserved", "reserved", "reserved", "reserved",
+ "reserved", "reserved", "reserved", "reserved",
+ "reserved", "reserved", "reserved", "reserved"};
+
+static char *ptype_array[32] =
+ {"int8 *", "int16 *", "int32 *", "int64 *",
+ "uint8 *", "uint16 *", "uint32 *", "uint64 *",
+ "float *", "double *", "boolean *", "char *",
+ "wchar_t *", "void *", "nsIID *", "DOMString *",
+ "string", "wstring", "Interface *", "InterfaceIs *",
+ "array", "string_s", "wstring_s", "UTF8String *",
+ "CString *", "AString *", "reserved", "reserved",
+ "reserved", "reserved", "reserved", "reserved"};
+
+static char *rtype_array[32] =
+ {"int8 &", "int16 &", "int32 &", "int64 &",
+ "uint8 &", "uint16 &", "uint32 &", "uint64 &",
+ "float &", "double &", "boolean &", "char &",
+ "wchar_t &", "void &", "nsIID &", "DOMString &",
+ "string &", "wstring &", "Interface &", "InterfaceIs &",
+ "array &", "string_s &", "wstring_s &", "UTF8String &",
+ "CString &", "AString &", "reserved", "reserved",
+ "reserved", "reserved", "reserved", "reserved"};
+
+PRBool param_problems = PR_FALSE;
+
+PRBool
+XPT_DumpHeader(XPTCursor *cursor, XPTHeader *header,
+ const int indent, PRBool verbose_mode);
+
+PRBool
+XPT_DumpAnnotations(XPTAnnotation *ann, const int indent, PRBool verbose_mode);
+
+PRBool
+XPT_DumpInterfaceDirectoryEntry(XPTCursor *cursor,
+ XPTInterfaceDirectoryEntry *ide,
+ XPTHeader *header, const int indent,
+ PRBool verbose_mode);
+
+PRBool
+XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id,
+ XPTHeader *header, const int indent,
+ PRBool verbose_mode);
+
+PRBool
+XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
+ XPTInterfaceDescriptor *id,
+ const int indent, PRBool verbose_mode);
+PRBool
+XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id,
+ char **type_string);
+
+PRBool
+XPT_DumpXPTString(XPTString *str);
+
+PRBool
+XPT_DumpParamDescriptor(XPTHeader *header, XPTParamDescriptor *pd,
+ XPTInterfaceDescriptor *id,
+ const int indent, PRBool verbose_mode,
+ PRBool is_result);
+
+PRBool
+XPT_DumpTypeDescriptor(XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id,
+ int indent, PRBool verbose_mode);
+
+PRBool
+XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd,
+ XPTInterfaceDescriptor *id,
+ 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]);
+}
+
+#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
+
+#define main xptdump_main
+int xptdump_main(int argc, char *argv[]);
+
+#define get_file_length mac_get_file_length
+extern size_t mac_get_file_length(const char* filename);
+
+#else /* !(XP_MAC && XPIDL_PLUGIN) */
+
+static size_t get_file_length(const char* filename)
+{
+ struct stat file_stat;
+ if (stat(filename, &file_stat) != 0) {
+ perror("FAILED: get_file_length");
+ exit(1);
+ }
+ return file_stat.st_size;
+}
+
+#endif /* !(XP_MAC && XPIDL_PLUGIN) */
+
+int
+main(int argc, char **argv)
+{
+ PRBool verbose_mode = PR_FALSE;
+ XPTArena *arena;
+ XPTState *state;
+ XPTCursor curs, *cursor = &curs;
+ XPTHeader *header;
+ size_t flen;
+ char *name;
+ char *whole;
+ FILE *in;
+ int result = 1;
+
+ switch (argc) {
+ case 2:
+ if (argv[1][0] == '-') {
+ xpt_dump_usage(argv);
+ return 1;
+ }
+ name = argv[1];
+ flen = get_file_length(name);
+ in = fopen(name, "rb");
+ break;
+ case 3:
+ verbose_mode = PR_TRUE;
+ if (argv[1][0] != '-' || argv[1][1] != 'v') {
+ xpt_dump_usage(argv);
+ return 1;
+ }
+ name = argv[2];
+ flen = get_file_length(name);
+ in = fopen(name, "rb");
+ break;
+ default:
+ xpt_dump_usage(argv);
+ return 1;
+ }
+
+ if (!in) {
+ perror("FAILED: fopen");
+ return 1;
+ }
+
+ arena = XPT_NewArena(1024, sizeof(double), "main xpt_dump arena");
+ if (!arena) {
+ perror("XPT_NewArena failed");
+ return 1;
+ }
+
+ /* after arena creation all exits via 'goto out' */
+
+ whole = XPT_MALLOC(arena, flen);
+ if (!whole) {
+ perror("FAILED: XPT_MALLOC for whole");
+ goto out;
+ }
+
+ if (flen > 0) {
+ size_t rv = fread(whole, 1, flen, in);
+ if (rv < flen) {
+ fprintf(stderr, "short read (%zd vs %zd)! ouch!\n", rv, flen);
+ goto out;
+ }
+ if (ferror(in) != 0 || fclose(in) != 0)
+ perror("FAILED: Unable to read typelib file.\n");
+
+ state = XPT_NewXDRState(XPT_DECODE, whole, flen);
+ if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) {
+ fprintf(stdout, "XPT_MakeCursor failed for %s\n", name);
+ goto out;
+ }
+ if (!XPT_DoHeader(arena, cursor, &header)) {
+ fprintf(stdout,
+ "DoHeader failed for %s. Is %s a valid .xpt file?\n",
+ name, name);
+ goto out;
+ }
+
+ if (!XPT_DumpHeader(cursor, header, BASE_INDENT, verbose_mode)) {
+ perror("FAILED: XPT_DumpHeader");
+ goto out;
+ }
+
+ if (param_problems) {
+ fprintf(stdout, "\nWARNING: ParamDescriptors are present with "
+ "bad in/out/retval flag information.\n"
+ "These have been marked with 'XXX'.\n"
+ "Remember, retval params should always be marked as out!\n");
+ }
+
+ XPT_DestroyXDRState(state);
+ XPT_FREE(arena, whole);
+
+ } else {
+ fclose(in);
+ perror("FAILED: file length <= 0");
+ goto out;
+ }
+
+ result = 0;
+
+out:
+ XPT_DestroyArena(arena);
+ return result;
+}
+
+PRBool
+XPT_DumpHeader(XPTCursor *cursor, 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((const char*)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(cursor,
+ &header->interface_directory[i],
+ header, indent*2,
+ verbose_mode)) {
+ return PR_FALSE;
+ }
+ } else {
+ if (!XPT_DumpInterfaceDirectoryEntry(cursor,
+ &header->interface_directory[i],
+ header, 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(XPTCursor *cursor,
+ XPTInterfaceDirectoryEntry *ide,
+ XPTHeader *header, 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 ? ide->name_space : "none");
+ fprintf(stdout, "%*sAddress of interface descriptor: %p\n",
+ indent, " ", ide->interface_descriptor);
+
+ fprintf(stdout, "%*sDescriptor:\n", indent, " ");
+
+ if (!XPT_DumpInterfaceDescriptor(cursor, ide->interface_descriptor,
+ header, 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(cursor, ide->interface_descriptor,
+ header, new_indent, verbose_mode)) {
+ return PR_FALSE;
+ }
+ }
+
+ return PR_TRUE;
+}
+
+PRBool
+XPT_DumpInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor *id,
+ XPTHeader *header, const int indent,
+ PRBool verbose_mode)
+{
+ XPTInterfaceDirectoryEntry *parent_ide;
+ 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 (id->parent_interface) {
+
+ parent_ide = &header->interface_directory[id->parent_interface - 1];
+
+ fprintf(stdout, "%*sParent: %s::%s\n", indent, " ",
+ parent_ide->name_space ?
+ parent_ide->name_space : "",
+ parent_ide->name);
+ }
+
+ fprintf(stdout, "%*sFlags:\n", indent, " ");
+
+ fprintf(stdout, "%*sScriptable: %s\n", new_indent, " ",
+ XPT_ID_IS_SCRIPTABLE(id->flags) ? "TRUE" : "FALSE");
+
+ fprintf(stdout, "%*sFunction: %s\n", new_indent, " ",
+ XPT_ID_IS_FUNCTION(id->flags) ? "TRUE" : "FALSE");
+
+ if (verbose_mode) {
+ if (id->parent_interface) {
+ fprintf(stdout,
+ "%*sIndex of parent interface (in data pool): %d\n",
+ indent, " ", id->parent_interface);
+
+ }
+ } else {
+ }
+
+ if (id->num_methods > 0) {
+ if (verbose_mode) {
+ fprintf(stdout,
+ "%*s# of Method Descriptors: %d\n",
+ indent, " ", id->num_methods);
+ } else {
+ fprintf(stdout, "%*sMethods:\n", indent, " ");
+ }
+
+ for (i=0; i<id->num_methods; i++) {
+ if (verbose_mode) {
+ fprintf(stdout, "%*sMethod #%d:\n", new_indent, " ", i);
+ if (!XPT_DumpMethodDescriptor(header,
+ &id->method_descriptors[i], id,
+ more_indent, verbose_mode)) {
+ return PR_FALSE;
+ }
+ } else {
+ if (!XPT_DumpMethodDescriptor(header,
+ &id->method_descriptors[i], id,
+ new_indent, verbose_mode)) {
+ return PR_FALSE;
+ }
+ }
+ }
+ } else {
+ fprintf(stdout, "%*sMethods:\n", indent, " ");
+ fprintf(stdout, "%*sNo Methods\n", new_indent, " ");
+ }
+
+ if (id->num_constants > 0) {
+ if (verbose_mode) {
+ fprintf(stdout,
+ "%*s# of Constant Descriptors: %d\n",
+ indent, " ", id->num_constants);
+ } else {
+ fprintf(stdout, "%*sConstants:\n", indent, " ");
+ }
+
+ for (i=0; i<id->num_constants; i++) {
+ if (verbose_mode) {
+ fprintf(stdout, "%*sConstant #%d:\n", new_indent, " ", i);
+ if (!XPT_DumpConstDescriptor(header,
+ &id->const_descriptors[i], id,
+ more_indent, verbose_mode))
+ return PR_FALSE;
+ } else {
+ if (!XPT_DumpConstDescriptor(header,
+ &id->const_descriptors[i], id,
+ new_indent, verbose_mode)) {
+ return PR_FALSE;
+ }
+ }
+ }
+ } else {
+ fprintf(stdout, "%*sConstants:\n", indent, " ");
+ fprintf(stdout, "%*sNo Constants\n", new_indent, " ");
+ }
+
+ return PR_TRUE;
+}
+
+PRBool
+XPT_DumpMethodDescriptor(XPTHeader *header, XPTMethodDescriptor *md,
+ XPTInterfaceDescriptor *id,
+ 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 NotXPCOM? ", indent, " ");
+ if (XPT_MD_IS_NOTXPCOM(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(header, &md->params[i], id,
+ more_indent, verbose_mode, PR_FALSE))
+ return PR_FALSE;
+ }
+
+ fprintf(stdout, "%*sResult:\n", indent, " ");
+ if (!XPT_DumpParamDescriptor(header, md->result, id, new_indent,
+ verbose_mode, PR_TRUE)) {
+ return PR_FALSE;
+ }
+ } else {
+ char *param_type;
+ XPTParamDescriptor *pd;
+
+ if (!XPT_GetStringForType(header, &md->result->type, id, &param_type)) {
+ return PR_FALSE;
+ }
+ fprintf(stdout, "%*s%c%c%c%c%c %s %s(", indent - 6, " ",
+ XPT_MD_IS_GETTER(md->flags) ? 'G' : ' ',
+ XPT_MD_IS_SETTER(md->flags) ? 'S' : ' ',
+ XPT_MD_IS_HIDDEN(md->flags) ? 'H' : ' ',
+ XPT_MD_IS_NOTXPCOM(md->flags) ? 'N' : ' ',
+ XPT_MD_IS_CTOR(md->flags) ? 'C' : ' ',
+ 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 ");
+ }
+ if (XPT_PD_IS_SHARED(pd->flags)) {
+ fprintf(stdout, "shared ");
+ }
+ } else {
+ fprintf(stdout, " ");
+ if (XPT_PD_IS_DIPPER(pd->flags)) {
+ fprintf(stdout, "dipper ");
+ }
+ if (XPT_PD_IS_RETVAL(pd->flags)) {
+ fprintf(stdout, "retval ");
+ }
+ }
+ } else {
+ if (XPT_PD_IS_OUT(pd->flags)) {
+ fprintf(stdout, "out ");
+ if (XPT_PD_IS_RETVAL(pd->flags)) {
+ fprintf(stdout, "retval ");
+ }
+ if (XPT_PD_IS_SHARED(pd->flags)) {
+ fprintf(stdout, "shared ");
+ }
+ } else {
+ param_problems = PR_TRUE;
+ fprintf(stdout, "XXX ");
+ }
+ }
+ if (!XPT_GetStringForType(header, &pd->type, id, &param_type)) {
+ return PR_FALSE;
+ }
+ fprintf(stdout, "%s", param_type);
+ }
+ fprintf(stdout, ");\n");
+ }
+ return PR_TRUE;
+}
+
+PRBool
+XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id,
+ char **type_string)
+{
+ static char buf[128]; /* ugly non-reentrant use of static buffer! */
+ PRBool isArray = PR_FALSE;
+
+ int tag = XPT_TDP_TAG(td->prefix);
+
+ if (tag == TD_ARRAY) {
+ isArray = PR_TRUE;
+ td = &id->additional_types[td->type.additional_type];
+ tag = XPT_TDP_TAG(td->prefix);
+ }
+
+ if (tag == TD_INTERFACE_TYPE) {
+ int idx = td->type.iface;
+ if (!idx || idx > header->num_interfaces)
+ *type_string = "UNKNOWN_INTERFACE";
+ else
+ *type_string = header->interface_directory[idx-1].name;
+ } else if (XPT_TDP_IS_POINTER(td->prefix.flags)) {
+ if (XPT_TDP_IS_REFERENCE(td->prefix.flags))
+ *type_string = rtype_array[tag];
+ else
+ *type_string = ptype_array[tag];
+ } else {
+ *type_string = type_array[tag];
+ }
+
+ if(isArray) {
+ sprintf(buf, "%s []", *type_string);
+ *type_string = buf;
+ }
+
+ 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(XPTHeader *header, XPTParamDescriptor *pd,
+ XPTInterfaceDescriptor *id,
+ const int indent, PRBool verbose_mode,
+ PRBool is_result)
+{
+ int new_indent = indent + BASE_INDENT;
+
+ if (!XPT_PD_IS_IN(pd->flags) &&
+ !XPT_PD_IS_OUT(pd->flags) &&
+ (XPT_PD_IS_RETVAL(pd->flags) ||
+ XPT_PD_IS_SHARED(pd->flags))) {
+ param_problems = PR_TRUE;
+ fprintf(stdout, "XXX\n");
+ } else {
+ if (!XPT_PD_IS_IN(pd->flags) && !XPT_PD_IS_OUT(pd->flags)) {
+ if (is_result) {
+ if (XPT_TDP_TAG(pd->type.prefix) != TD_UINT32 &&
+ XPT_TDP_TAG(pd->type.prefix) != TD_VOID) {
+ param_problems = PR_TRUE;
+ fprintf(stdout, "XXX\n");
+ }
+ } else {
+ param_problems = PR_TRUE;
+ fprintf(stdout, "XXX\n");
+ }
+ }
+ }
+
+ 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, "%*sShared? ", indent, " ");
+ if (XPT_PD_IS_SHARED(pd->flags))
+ fprintf(stdout, "TRUE\n");
+ else
+ fprintf(stdout, "FALSE\n");
+
+ fprintf(stdout, "%*sDipper? ", indent, " ");
+ if (XPT_PD_IS_DIPPER(pd->flags))
+ fprintf(stdout, "TRUE\n");
+ else
+ fprintf(stdout, "FALSE\n");
+
+
+ fprintf(stdout, "%*sType Descriptor:\n", indent, " ");
+ if (!XPT_DumpTypeDescriptor(&pd->type, id, new_indent, verbose_mode))
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
+PRBool
+XPT_DumpTypeDescriptor(XPTTypeDescriptor *td,
+ XPTInterfaceDescriptor *id,
+ int indent, PRBool verbose_mode)
+{
+ int new_indent;
+
+ if (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
+ fprintf(stdout, "%*sArray (size in arg %d and length in arg %d) of...\n",
+ indent, " ", td->argnum, td->argnum2);
+ td = &id->additional_types[td->type.additional_type];
+ indent += BASE_INDENT;
+ }
+
+ 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_PSTRING_SIZE_IS ||
+ XPT_TDP_TAG(td->prefix) == TD_PWSTRING_SIZE_IS) {
+ fprintf(stdout, "%*s - size in arg %d and length in arg %d\n",
+ indent, " ", td->argnum, td->argnum2);
+ }
+
+ 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.iface);
+ }
+
+ 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->argnum);
+ }
+
+ return PR_TRUE;
+}
+
+PRBool
+XPT_DumpConstDescriptor(XPTHeader *header, XPTConstDescriptor *cd,
+ XPTInterfaceDescriptor *id,
+ const int indent, PRBool verbose_mode)
+{
+ int new_indent = indent + BASE_INDENT;
+ char *const_type;
+/* char *out; */
+ PRUint32 uintout;
+ PRInt32 intout;
+
+ if (verbose_mode) {
+ fprintf(stdout, "%*sName: %s\n", indent, " ", cd->name);
+ fprintf(stdout, "%*sType Descriptor: \n", indent, " ");
+ if (!XPT_DumpTypeDescriptor(&cd->type, id, new_indent, verbose_mode))
+ return PR_FALSE;
+ fprintf(stdout, "%*sValue: ", indent, " ");
+ } else {
+ if (!XPT_GetStringForType(header, &cd->type, id, &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_INT64:
+ /* XXX punt for now to remove NSPR linkage...
+ * borrow from mozilla/nsprpub/pr/src/io/prprf.c::cvt_ll? */
+
+/* out = PR_smprintf("%lld", cd->value.i64); */
+/* fputs(out, stdout); */
+/* PR_smprintf_free(out); */
+ LL_L2I(intout, cd->value.i64);
+ fprintf(stdout, "%d", intout);
+ break;
+ case TD_INT32:
+ fprintf(stdout, "%d", cd->value.i32);
+ break;
+ case TD_UINT8:
+ fprintf(stdout, "%u", cd->value.ui8);
+ break;
+ case TD_UINT16:
+ fprintf(stdout, "%u", cd->value.ui16);
+ break;
+ case TD_UINT64:
+/* out = PR_smprintf("%lld", cd->value.ui64); */
+/* fputs(out, stdout); */
+/* PR_smprintf_free(out); */
+ /* XXX punt for now to remove NSPR linkage. */
+ LL_L2UI(uintout, cd->value.ui64);
+ fprintf(stdout, "%u", uintout);
+ break;
+ case TD_UINT32:
+ fprintf(stdout, "%u", cd->value.ui32);
+ 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_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;
+}
diff --git a/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c
new file mode 100644
index 00000000..872b96fd
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c
@@ -0,0 +1,883 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** 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):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+/*
+ * A utility for linking multiple typelib files.
+ */
+
+#include "xpt_xdr.h"
+#include <stdio.h>
+#ifdef XP_MAC
+#include <stat.h>
+#else
+#include <sys/stat.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include "prlong.h"
+
+#ifndef NULL
+#define NULL (void *) 0
+#endif
+
+/* Forward declarations. */
+typedef struct fixElement fixElement;
+static int compare_IDEs_by_IID(const void *ap, const void *bp);
+static int compare_IDE_with_zero(const void *ap);
+static int compare_IDEs_by_name(const void *ap, const void *bp);
+static int compare_IDEs_by_name_space(const void *ap, const void *bp);
+static int compare_strings(const void *ap, const void *bp);
+static int compare_pointers(const void *ap, const void *bp);
+static int compare_fixElements_by_IID(const void *ap, const void *bp);
+static int compare_fixElements_by_name(const void *ap, const void *bp);
+static int compare_IIDs(const void *ap, const void *bp);
+PRBool shrink_IDE_array(XPTInterfaceDirectoryEntry *ide,
+ int element_to_delete, int num_interfaces);
+PRBool update_fix_array(XPTArena *arena, fixElement *fix, int element_to_delete,
+ int num_interfaces, int replacement);
+static int get_new_index(const fixElement *fix, int num_elements,
+ int target_file, int target_interface);
+PRBool copy_IDE(XPTInterfaceDirectoryEntry *from,
+ XPTInterfaceDirectoryEntry *to);
+PRBool copy_fixElement(fixElement *from, fixElement *to);
+static void print_IID(struct nsID *iid, FILE *file);
+static void xpt_link_usage(char *argv[]);
+
+struct fixElement {
+ nsID iid;
+ char* name;
+ int file_num;
+ int interface_num;
+ PRBool is_deleted;
+ /* These next two variables will point you to the substitute interface
+ * if this one has been deleted.
+ */
+ int maps_to_file_num;
+ int maps_to_interface_num;
+};
+
+/* Global variables. */
+PRUint16 trueNumberOfInterfaces = 0;
+PRUint16 totalNumberOfInterfaces = 0;
+PRUint16 oldTotalNumberOfInterfaces = 0;
+
+/* The following globals are explained in xpt_struct.h */
+PRUint8 major_version = XPT_MAJOR_VERSION;
+PRUint8 minor_version = XPT_MINOR_VERSION;
+
+#if defined(XP_MAC) && defined(XPIDL_PLUGIN)
+
+#define main xptlink_main
+int xptlink_main(int argc, char *argv[]);
+extern size_t mac_get_file_length(const char* filename);
+#define get_file_length mac_get_file_length
+
+#else
+
+static size_t get_file_length(const char* filename)
+{
+ struct stat file_stat;
+ if (stat(filename, &file_stat) != 0) {
+ perror("FAILED: get_file_length");
+ exit(1);
+ }
+ return file_stat.st_size;
+}
+
+#endif /* XP_MAC && XPIDL_PLUGIN */
+
+int
+main(int argc, char **argv)
+{
+ XPTArena *arena;
+ XPTState *state;
+ XPTCursor curs, *cursor = &curs;
+ XPTHeader *header;
+ XPTInterfaceDirectoryEntry *IDE_array = NULL;
+ XPTInterfaceDescriptor *id;
+ XPTTypeDescriptor *td;
+ XPTAnnotation *ann, *first_ann;
+ PRUint32 header_sz, len;
+ PRUint32 oldOffset;
+ PRUint32 newOffset;
+ size_t flen = 0;
+ char *head, *data, *whole;
+ const char *outFileName;
+ FILE *in, *out;
+ fixElement *fix_array = NULL;
+ int i,j;
+ int k = 0;
+
+ if (argc < 3) {
+ xpt_link_usage(argv);
+ return 1;
+ }
+
+ arena = XPT_NewArena(1024 * 10, sizeof(double), "main xpt_link arena");
+ if (!arena) {
+ perror("FAILED: XPT_NewArena");
+ return 1;
+ }
+
+ first_ann = XPT_NewAnnotation(arena, XPT_ANN_LAST, NULL, NULL);
+
+ /* Check if the "-t version numnber" cmd line arg is present */
+ i = 1;
+ if (argv[i][0] == '-' && argv[i][1] == 't') {
+ /* Parse for "-t version number" */
+
+ /* If -t is the last argument on the command line, we have a problem */
+ if (i + 1 == argc) {
+ fprintf(stderr, "ERROR: missing version number after -t\n");
+ xpt_link_usage(argv);
+ return 1;
+ }
+
+ /*
+ * Assume that the argument after "-t" is the version number string
+ * and search for it in our internal list of acceptable version
+ * numbers.
+ */
+
+ switch (XPT_ParseVersionString(argv[++i], &major_version,
+ &minor_version)) {
+ case XPT_VERSION_CURRENT:
+ case XPT_VERSION_OLD:
+ break;
+ case XPT_VERSION_UNSUPPORTED:
+ fprintf(stderr, "ERROR: version \"%s\" not supported.\n",
+ argv[i]);
+ xpt_link_usage(argv);
+ return 1;
+ case XPT_VERSION_UNKNOWN:
+ default:
+ fprintf(stderr, "ERROR: version \"%s\" not recognised.\n",
+ argv[i]);
+ xpt_link_usage(argv);
+ return 1;
+ }
+
+ /* Hang onto the output file name. It's needed later. */
+ outFileName = argv[++i];
+
+ /* Increment i to the cmd line arg after outFileName */
+ i++;
+ }
+ else {
+ outFileName = argv[1];
+ i = 2;
+ }
+
+ for ( /* use i from earlier */ ; i < argc; i++) {
+ char *name = argv[i];
+
+ flen = get_file_length(name);
+ if (!flen) {
+ fprintf(stderr, "ERROR: file %s is zero length\n", name);
+ return 1;
+ }
+
+ in = fopen(name, "rb");
+ if (!in) {
+ perror("FAILED: fopen");
+ return 1;
+ }
+
+ whole = XPT_MALLOC(arena, flen);
+ if (!whole) {
+ perror("FAILED: XPT_MALLOC for whole");
+ return 1;
+ }
+
+ if (flen > 0) {
+ size_t rv = fread(whole, 1, flen, in);
+ if (rv < flen) {
+ fprintf(stderr, "short read (%zd vs %zd)! ouch!\n", rv, flen);
+ return 1;
+ }
+ if (ferror(in) != 0 || fclose(in) != 0) {
+ perror("FAILED: Unable to read typelib file.\n");
+ return 1;
+ }
+
+ state = XPT_NewXDRState(XPT_DECODE, whole, flen);
+ if (!XPT_MakeCursor(state, XPT_HEADER, 0, cursor)) {
+ fprintf(stdout, "XPT_MakeCursor failed for %s\n", name);
+ return 1;
+ }
+ if (!XPT_DoHeader(arena, cursor, &header)) {
+ fprintf(stdout,
+ "DoHeader failed for %s. Is %s a valid .xpt file?\n",
+ name, name);
+ return 1;
+ }
+
+ /*
+ * Make sure that the version of the typelib file is less than or
+ * equal to the version specified in the -t cmd line arg.
+ */
+
+ if (header &&
+ (header->major_version > major_version ||
+ (header->major_version == major_version &&
+ header->minor_version > minor_version))) {
+ fprintf(stderr, "FAILED: %s's version, %d.%d, is newer than "
+ "the version (%d.%d) specified in the -t "
+ "command line argument.\n",
+ name, header->major_version, header->minor_version,
+ major_version, minor_version);
+ return 1;
+ }
+
+ oldTotalNumberOfInterfaces = totalNumberOfInterfaces;
+ totalNumberOfInterfaces += header->num_interfaces;
+ if (header->num_interfaces > 0) {
+ XPTInterfaceDirectoryEntry *newIDE;
+ fixElement *newFix;
+
+ newIDE = (XPTInterfaceDirectoryEntry *)
+ XPT_MALLOC(arena, totalNumberOfInterfaces *
+ sizeof(XPTInterfaceDirectoryEntry));
+ if (!newIDE) {
+ perror("FAILED: XPT_MALLOC of IDE_array");
+ return 1;
+ }
+
+ if (IDE_array) {
+ if (oldTotalNumberOfInterfaces)
+ memcpy(newIDE, IDE_array,
+ oldTotalNumberOfInterfaces *
+ sizeof(XPTInterfaceDirectoryEntry));
+ XPT_FREE(arena, IDE_array);
+ }
+ IDE_array = newIDE;
+
+
+ newFix = (fixElement *)
+ XPT_MALLOC(arena,
+ totalNumberOfInterfaces * sizeof(fixElement));
+ if (!newFix) {
+ perror("FAILED: XPT_MALLOC of fix_array");
+ return 1;
+ }
+
+ if (fix_array) {
+ if (oldTotalNumberOfInterfaces)
+ memcpy(newFix, fix_array,
+ oldTotalNumberOfInterfaces *
+ sizeof(fixElement));
+ XPT_FREE(arena, fix_array);
+ }
+ fix_array = newFix;
+
+ for (j=0; j<header->num_interfaces; j++) {
+ if (!copy_IDE(&header->interface_directory[j],
+ &IDE_array[k])) {
+ perror("FAILED: 1st copying of IDE");
+ return 1;
+ }
+ fix_array[k].iid = IDE_array[k].iid;
+ fix_array[k].name = IDE_array[k].name;
+ fix_array[k].file_num = i-2;
+ fix_array[k].interface_num = j+1;
+ fix_array[k].is_deleted = PR_FALSE;
+ fix_array[k].maps_to_file_num = i-2;
+ fix_array[k].maps_to_interface_num = j+1;
+
+ k++;
+ }
+ }
+
+ /* Copy the annotations if they are not 'empty'
+ */
+ if (header->annotations != NULL &&
+ header->annotations->flags != XPT_ANN_LAST) {
+ ann = first_ann;
+ while (ann->next != NULL) {
+ ann = ann->next;
+ }
+ ann->next = header->annotations;
+ }
+
+ XPT_FREEIF(arena, header);
+ if (state)
+ XPT_DestroyXDRState(state);
+ XPT_FREE(arena, whole);
+ flen = 0;
+
+ } else {
+ fclose(in);
+ perror("FAILED: file length <= 0");
+ return 1;
+ }
+ }
+
+ /* Make sure the last annotation is the only one marked as XP_ANN_LAST.
+ */
+ ann = first_ann;
+ while (ann->next != NULL) {
+ ann->flags &= ~XPT_ANN_LAST;
+ ann = ann->next;
+ }
+ ann->flags |= XPT_ANN_LAST;
+
+ /* Sort both IDE_array and fix_array by name so we can check for
+ * name_space::name collisions.
+ */
+ qsort(IDE_array,
+ totalNumberOfInterfaces,
+ sizeof(XPTInterfaceDirectoryEntry),
+ compare_IDEs_by_name);
+
+ qsort(fix_array,
+ totalNumberOfInterfaces,
+ sizeof(fixElement),
+ compare_fixElements_by_name);
+
+ /* trueNumberOfInterfaces == number of interfaces left after deletions
+ * are made. Initialize it here to be the same as the total number of
+ * interfaces we'ce encountered thus far.
+ */
+ trueNumberOfInterfaces = totalNumberOfInterfaces;
+
+ /* Iterate through the sorted interfaces. Start at one so we don't
+ * accidentally walk off the end of the array.
+ */
+ i = 1;
+ while (i != trueNumberOfInterfaces) {
+
+ /* Check for name_space::name collision.
+ */
+ if (compare_strings(IDE_array[i-1].name,
+ IDE_array[i].name) == 0 &&
+ compare_strings(IDE_array[i-1].name_space,
+ IDE_array[i].name_space) == 0) {
+
+ /* If one of the interfaces is unresolved, delete that one
+ * preferentailly.
+ */
+ if (!IDE_array[i-1].interface_descriptor) {
+ /* Shrink the IDE_array to delete the duplicate interface.
+ */
+ if (!shrink_IDE_array(IDE_array,
+ i-1,
+ trueNumberOfInterfaces)) {
+ perror("FAILED: shrink_IDE_array");
+ return 1;
+ }
+ /* Update the fix array. This involves moving the deleted
+ * entry to the end of the array (rather than deleting it)
+ * and mapping it to the "replacement" element so we can
+ * update interface indices appropriately later.
+ */
+ update_fix_array(arena, fix_array, i-1,
+ totalNumberOfInterfaces, i);
+ /* Decrement the true number of interfaces since we just
+ * deleted one. There's more than one way to get out of
+ * this loop.
+ */
+ trueNumberOfInterfaces--;
+ } else {
+ if (!IDE_array[i].interface_descriptor ||
+ (compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0))
+ {
+ /* Shrink the IDE_array to delete the duplicate interface.
+ */
+ if (!shrink_IDE_array(IDE_array,
+ i,
+ trueNumberOfInterfaces)) {
+ perror("FAILED: shrink_IDE_array");
+ return 1;
+ }
+ /* Update the fix array. This involves moving the deleted
+ * entry to the end of the array (rather than deleting it)
+ * and mapping it to the "replacement" element so we can
+ * update interface indices appropriately later.
+ */
+ update_fix_array(arena, fix_array, i,
+ totalNumberOfInterfaces, i-1);
+ /* Decrement the true number of interfaces since we just
+ * deleted one. There's more than one way to get out of
+ * this loop.
+ */
+ trueNumberOfInterfaces--;
+ } else {
+ /* Found interfaces with duplicate names but different
+ * iids! */
+ char *ns = IDE_array[i].name_space;
+ fprintf(stderr,
+ "ERROR: found duplicate definitions of interface "
+ "%s%s%s with iids \n",
+ ns ? ns : "", ns ? "::" : "", IDE_array[i].name);
+ print_IID(&IDE_array[i].iid, stderr);
+ fprintf(stderr, " and ");
+ print_IID(&IDE_array[i-1].iid, stderr);
+ fprintf(stderr, "\n");
+ return 1;
+ }
+ }
+ } else {
+ /* Only increment if there was no name_space::name collision.
+ */
+ i++;
+ }
+ }
+
+ /* Sort the IDE_array (put them in their final order) so that updating
+ * of indices will be meaningful.
+ */
+ qsort(IDE_array,
+ trueNumberOfInterfaces,
+ sizeof(XPTInterfaceDirectoryEntry),
+ compare_IDEs_by_IID);
+
+ /* Sort the fix_array to match the IDE_array.
+ */
+ qsort(fix_array,
+ trueNumberOfInterfaces,
+ sizeof(fixElement),
+ compare_fixElements_by_IID);
+
+ /* Iterate through the remaining interfaces (those not deleted)
+ * looking for references to interfaces (such as id->parent_interface)
+ * which need an updated index number.
+ */
+ for (i=0; i<trueNumberOfInterfaces; i++) {
+
+ /* Define id to save some keystrokes.
+ */
+ id = IDE_array[i].interface_descriptor;
+
+ /* Check for unresolved interface.
+ */
+ if (id) {
+
+ /* Fix parent_interface first.
+ */
+ if (id->parent_interface && id->parent_interface != 0) {
+ id->parent_interface =
+ get_new_index(fix_array, totalNumberOfInterfaces,
+ fix_array[i].file_num, id->parent_interface);
+ }
+ /* Iterate through the method descriptors looking for params of
+ * type TD_INTERFACE_TYPE.
+ */
+ for (j=0; j<id->num_methods; j++) {
+ /* Cycle through the params first.
+ */
+ for (k=0; k<id->method_descriptors[j].num_args; k++) {
+ /* Define td to save some keystrokes.
+ */
+ td = &id->method_descriptors[j].params[k].type;
+
+ while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
+ td = &id->additional_types[td->type.additional_type];
+ }
+
+ if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
+ td->type.iface =
+ get_new_index(fix_array,
+ totalNumberOfInterfaces,
+ fix_array[i].file_num,
+ td->type.iface);
+ }
+ }
+
+ /* Check the result param too. Define td again to save
+ * some keystrokes.
+ */
+ td = &id->method_descriptors[j].result->type;
+ if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
+ td->type.iface =
+ get_new_index(fix_array, totalNumberOfInterfaces,
+ fix_array[i].file_num,
+ td->type.iface);
+ }
+ }
+ }
+ }
+
+ /* Iterate through the array quickly looking for duplicate IIDS.
+ * This shouldn't happen, i.e. is a failure condition, so bail
+ * if we find a duplicate. If we have more than one entry, start
+ * at one so we don't accidentally grep the ether.
+ */
+ if (trueNumberOfInterfaces>1) {
+ for (i=1; i<trueNumberOfInterfaces; i++) {
+ /* Only complain if the IIDs are identical and nonzero. */
+ if (compare_IIDs(&IDE_array[i-1].iid, &IDE_array[i].iid) == 0 &&
+ compare_IDE_with_zero(&IDE_array[i]) != 0) {
+ fprintf(stderr, "FATAL ERROR:\n"
+ "Duplicate IID detected (");
+ print_IID(&IDE_array[i-1].iid, stderr);
+ fprintf(stderr, ") in\n"
+ "interface %s::%s from %s\n"
+ "and\n"
+ "interface %s::%s from %s\n",
+ IDE_array[i-1].name_space ?
+ IDE_array[i-1].name_space : "",
+ IDE_array[i-1].name,
+ argv[fix_array[i-1].file_num+2],
+ IDE_array[i].name_space ?
+ IDE_array[i].name_space : "",
+ IDE_array[i].name,
+ argv[fix_array[i].file_num+2]);
+ return 1;
+ }
+ }
+ }
+
+ header = XPT_NewHeader(arena, (PRUint16)trueNumberOfInterfaces,
+ major_version, minor_version);
+
+ header->annotations = first_ann;
+ for (i=0; i<trueNumberOfInterfaces; i++) {
+ if (!copy_IDE(&IDE_array[i], &header->interface_directory[i])) {
+ perror("FAILED: 2nd copying of IDE");
+ return 1;
+ }
+ }
+
+ header_sz = XPT_SizeOfHeaderBlock(header);
+
+ state = XPT_NewXDRState(XPT_ENCODE, NULL, 0);
+ if (!state) {
+ perror("FAILED: error creating XDRState");
+ return 1;
+ }
+
+ XPT_SetDataOffset(state, header_sz);
+
+ if (!XPT_MakeCursor(state, XPT_HEADER, header_sz, cursor)) {
+ perror("FAILED: error making cursor");
+ return 1;
+ }
+ oldOffset = cursor->offset;
+ if (!XPT_DoHeader(arena, cursor, &header)) {
+ perror("FAILED: error doing Header");
+ return 1;
+ }
+ newOffset = cursor->offset;
+ XPT_GetXDRDataLength(state, XPT_HEADER, &len);
+ header->file_length = len;
+ XPT_GetXDRDataLength(state, XPT_DATA, &len);
+ header->file_length += len;
+ XPT_SeekTo(cursor, oldOffset);
+ if (!XPT_DoHeaderPrologue(arena, cursor, &header, NULL)) {
+ perror("FAILED: error doing Header");
+ return 1;
+ }
+ XPT_SeekTo(cursor, newOffset);
+ out = fopen(outFileName, "wb");
+ 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);
+
+ if (ferror(out) != 0 || fclose(out) != 0) {
+ fprintf(stderr, "Error writing file: %s\n", argv[1]);
+ } else {
+/* fprintf(stderr, "File written: %s\n", argv[1]); */
+ }
+
+ if (state)
+ XPT_DestroyXDRState(state);
+
+ XPT_DestroyArena(arena);
+
+ return 0;
+}
+
+static int
+compare_IDEs_by_IID(const void *ap,
+ const void *bp)
+{
+ const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
+
+ int answer = compare_IIDs(&ide1->iid, &ide2->iid);
+ if(!answer)
+ answer = compare_strings(ide1->name, ide2->name);
+
+ return answer;
+}
+
+/* For detecting unresolved interfaces. */
+const nsID iid_zero = { 0x0, 0x0, 0x0,
+ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
+
+static int
+compare_IDE_with_zero(const void *ap)
+{
+ const XPTInterfaceDirectoryEntry *ide1 = ap;
+
+ return compare_IIDs(&ide1->iid, &iid_zero);
+}
+
+static int
+compare_fixElements_by_IID(const void *ap,
+ const void *bp)
+{
+ const fixElement *fix1 = ap, *fix2 = bp;
+
+ int answer = compare_IIDs(&fix1->iid, &fix2->iid);
+ if(!answer)
+ answer = compare_strings(fix1->name, fix2->name);
+
+ return answer;
+}
+
+static int
+compare_IDEs_by_name(const void *ap,
+ const void *bp)
+{
+ const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
+
+ int answer = compare_strings(ide1->name, ide2->name);
+ if(!answer)
+ answer = compare_pointers(ide1->name, ide2->name);
+
+ return answer;
+}
+
+static int
+compare_IDEs_by_name_space(const void *ap,
+ const void *bp)
+{
+ const XPTInterfaceDirectoryEntry *ide1 = ap, *ide2 = bp;
+
+ return compare_strings(ide1->name_space, ide2->name_space);
+}
+
+static int
+compare_strings(const void *ap, const void *bp)
+{
+ const char *string1 = ap, *string2 = bp;
+
+ if (!string1 && !string2)
+ return 0;
+ if (!string1)
+ return -1;
+ if (!string2)
+ return 1;
+
+ return strcmp(string1, string2);
+}
+
+static int
+compare_pointers(const void *ap, const void *bp)
+{
+ if (ap == bp) {
+#ifdef DEBUG_jband
+ perror("name addresses were equal!");
+#endif
+ return 0;
+ }
+ if (ap > bp)
+ return 1;
+ return -1;
+}
+
+static int
+compare_fixElements_by_name(const void *ap,
+ const void *bp)
+{
+ const fixElement *fix1 = ap, *fix2 = bp;
+
+ int answer= compare_strings(fix1->name, fix2->name);
+ if(!answer)
+ answer = compare_pointers(fix1->name, fix2->name);
+
+ return answer;
+}
+
+static int
+compare_IIDs(const void *ap, const void *bp)
+{
+ const nsID *a = ap, *b = bp;
+ int i;
+#define COMPARE(field) if (a->field > b->field) return 1; \
+ if (b->field > a->field) return -1;
+ COMPARE(m0);
+ COMPARE(m1);
+ COMPARE(m2);
+ for (i = 0; i < 8; i++) {
+ COMPARE(m3[i]);
+ }
+ return 0;
+#undef COMPARE
+}
+
+PRBool
+shrink_IDE_array(XPTInterfaceDirectoryEntry *ide, int element_to_delete,
+ int num_interfaces)
+{
+ int i;
+
+ if (element_to_delete >= num_interfaces) {
+ return PR_FALSE;
+ }
+
+ for (i=element_to_delete+1; i<num_interfaces; i++) {
+ if (!copy_IDE(&ide[i], &ide[i-1])) {
+ return PR_FALSE;
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/* update_fix_array marks a fixElement as deleted, updates its mapping
+ * to point to the "replacement" element, and moves it to the end of
+ * the array.
+ */
+PRBool
+update_fix_array(XPTArena *arena, fixElement *fix, int element_to_delete,
+ int num_interfaces, int replacement)
+{
+ fixElement *deleted;
+ int i;
+
+ if (element_to_delete >= num_interfaces) {
+ return PR_FALSE;
+ }
+
+ deleted = XPT_CALLOC(arena, sizeof(fixElement));
+ if (!copy_fixElement(&fix[element_to_delete], deleted)) {
+ return PR_FALSE;
+ }
+ deleted->is_deleted = PR_TRUE;
+ deleted->maps_to_file_num = fix[replacement].file_num;
+ deleted->maps_to_interface_num = fix[replacement].interface_num;
+
+ for (i=element_to_delete+1; i<num_interfaces; i++) {
+ if (!copy_fixElement(&fix[i], &fix[i-1])) {
+ return PR_FALSE;
+ }
+ }
+
+ if (!copy_fixElement(deleted, &fix[num_interfaces-1])) {
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+}
+
+/* get_new_index returns the new interface index by walking the fix_array
+ * until the file_num and interface_num match the target values. If a match
+ * is found, it checks to see if that element has been deleted. If it has
+ * been deleted, it follows that elements mapping until it gets to the
+ * proper interface (recursion). FYI, Indices are one-based; zero
+ * represents the special case (no parent interface).
+ */
+static int
+get_new_index(const fixElement *fix, int num_elements,
+ int target_file, int target_interface)
+{
+ int i;
+
+ for (i=0; i<num_elements; i++) {
+ if (fix[i].file_num == target_file &&
+ fix[i].interface_num == target_interface) {
+ if (fix[i].is_deleted) {
+ return get_new_index(fix, num_elements,
+ fix[i].maps_to_file_num,
+ fix[i].maps_to_interface_num);
+ }
+ return i+1;
+ }
+ }
+
+ return 0;
+}
+
+PRBool
+copy_IDE(XPTInterfaceDirectoryEntry *from, XPTInterfaceDirectoryEntry *to)
+{
+ if (!from || !to) {
+ return PR_FALSE;
+ }
+
+ to->iid = from->iid;
+ to->name = from->name;
+ to->name_space = from->name_space;
+ to->interface_descriptor = from->interface_descriptor;
+ return PR_TRUE;
+}
+
+PRBool
+copy_fixElement(fixElement *from, fixElement *to)
+{
+ if (!from || !to) {
+ return PR_FALSE;
+ }
+
+ to->iid = from->iid;
+ to->name = from->name;
+ to->file_num = from->file_num;
+ to->interface_num = from->interface_num;
+ to->is_deleted = from->is_deleted;
+ to->maps_to_file_num = from->maps_to_file_num;
+ to->maps_to_interface_num = from->maps_to_interface_num;
+
+ 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]);
+}
+
+static void
+xpt_link_usage(char *argv[])
+{
+ fprintf(stdout, "Usage: %s [-t version number] outfile file1.xpt file2.xpt ...\n"
+ " Links multiple typelib files into one outfile\n"
+ " -t create a typelib of an older version number\n", argv[0]);
+}
+