From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore | 1 + src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in | 50 ++ .../xpcom18a4/xpcom/typelib/xpt/public/.cvsignore | 1 + .../xpcom18a4/xpcom/typelib/xpt/public/Makefile.in | 51 ++ .../xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h | 145 ++++ .../xpcom/typelib/xpt/public/xpt_struct.h | 562 ++++++++++++ .../xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h | 240 ++++++ .../xpcom18a4/xpcom/typelib/xpt/src/.cvsignore | 1 + .../xpcom18a4/xpcom/typelib/xpt/src/Makefile.in | 76 ++ .../xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c | 358 ++++++++ .../xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c | 956 +++++++++++++++++++++ src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c | 665 ++++++++++++++ .../xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore | 3 + .../xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in | 59 ++ .../xpcom/typelib/xpt/tests/PrimitiveTest.c | 157 ++++ .../xpcom/typelib/xpt/tests/SimpleTypeLib.c | 192 +++++ .../xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore | 3 + .../xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in | 90 ++ .../xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c | 941 ++++++++++++++++++++ .../xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c | 883 +++++++++++++++++++ 20 files changed, 5434 insertions(+) create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/.cvsignore create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/public/.cvsignore create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/public/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_arena.h create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_struct.h create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/public/xpt_xdr.h create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/src/.cvsignore create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/src/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_arena.c create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_struct.c create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/src/xpt_xdr.c create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tests/.cvsignore create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tests/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tests/PrimitiveTest.c create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tests/SimpleTypeLib.c create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/.cvsignore create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_dump.c create mode 100644 src/libs/xpcom18a4/xpcom/typelib/xpt/tools/xpt_link.c (limited to 'src/libs/xpcom18a4/xpcom/typelib/xpt') 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 + +#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 +#include +#include +#ifdef VBOX_USE_IPRT_IN_XPCOM +# include +#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 +#include + +/***************************************************************************/ +/* 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 /* 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 +#include /* 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 + +#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 \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 +#ifdef XP_MAC +#include +#include +#include "FullPath.h" +#else +#ifdef XP_OS2_EMX +#include +#endif +#include +#endif +#include +#include +#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] \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; inum_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; inum_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; inum_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; inum_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, ¶m_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; inum_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, ¶m_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; ilength; 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 +#ifdef XP_MAC +#include +#else +#include +#endif +#include +#include +#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; jnum_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; iparent_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; jnum_methods; j++) { + /* Cycle through the params first. + */ + for (k=0; kmethod_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; iannotations = first_ann; + for (i=0; iinterface_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) { + 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; iiid = 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]); +} + -- cgit v1.2.3