diff options
Diffstat (limited to 'xpcom/typelib/xpt/xpt_struct.h')
-rw-r--r-- | xpcom/typelib/xpt/xpt_struct.h | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/xpcom/typelib/xpt/xpt_struct.h b/xpcom/typelib/xpt/xpt_struct.h new file mode 100644 index 000000000..b4da4a3fd --- /dev/null +++ b/xpcom/typelib/xpt/xpt_struct.h @@ -0,0 +1,366 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * 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" +#include <stdint.h> + +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; + +#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 { + uint32_t m0; + uint16_t m1; + uint16_t m2; + uint8_t m3[8]; +}; + +typedef struct nsID nsID; +#endif + +/* + * Every XPCOM typelib file begins with a header. + */ +struct XPTHeader { + // Some of these fields exists in the on-disk format but don't need to be + // stored in memory (other than very briefly, which can be done with local + // variables). + + //uint8_t magic[16]; + uint8_t major_version; + uint8_t minor_version; + uint16_t num_interfaces; + //uint32_t file_length; + XPTInterfaceDirectoryEntry *interface_directory; + //uint32_t data_pool; +}; + +#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 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 is zero we *know* + * that this library refused to read the file due to version incompatibility. + */ +#define XPT_MAJOR_INCOMPATIBLE_VERSION 0x02 + +/* + * 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; + + // This field exists in the on-disk format. But it isn't used so we don't + // allocate space for it in memory. + //char *name_space; + + XPTInterfaceDescriptor *interface_descriptor; +}; + +/* + * An InterfaceDescriptor describes a single XPCOM interface, including all of + * its methods. + */ +struct XPTInterfaceDescriptor { + /* This field ordering minimizes the size of this struct. + * The fields are serialized on disk in a different order. + * See DoInterfaceDescriptor(). + */ + XPTMethodDescriptor *method_descriptors; + XPTConstDescriptor *const_descriptors; + XPTTypeDescriptor *additional_types; + uint16_t parent_interface; + uint16_t num_methods; + uint16_t num_constants; + uint8_t 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. + */ + uint8_t num_additional_types; +}; + +#define XPT_ID_SCRIPTABLE 0x80 +#define XPT_ID_FUNCTION 0x40 +#define XPT_ID_BUILTINCLASS 0x20 +#define XPT_ID_MAIN_PROCESS_SCRIPTABLE_ONLY 0x10 +#define XPT_ID_FLAGMASK 0xf0 + +#define XPT_ID_IS_SCRIPTABLE(flags) (!!(flags & XPT_ID_SCRIPTABLE)) +#define XPT_ID_IS_FUNCTION(flags) (!!(flags & XPT_ID_FUNCTION)) +#define XPT_ID_IS_BUILTINCLASS(flags) (!!(flags & XPT_ID_BUILTINCLASS)) +#define XPT_ID_IS_MAIN_PROCESS_SCRIPTABLE_ONLY(flags) (!!(flags & XPT_ID_MAIN_PROCESS_SCRIPTABLE_ONLY)) + +/* + * 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 { + uint8_t flags; +}; + +/* flag bits */ + +#define XPT_TDP_FLAGMASK 0xe0 +#define XPT_TDP_TAGMASK (~XPT_TDP_FLAGMASK) +#define XPT_TDP_TAG(tdp) ((tdp).flags & XPT_TDP_TAGMASK) + +/* + * 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, + TD_JSVAL = 26 +}; + +struct XPTTypeDescriptor { + XPTTypeDescriptorPrefix prefix; + + // The memory layout here doesn't exactly match (for the appropriate types) + // the on-disk format. This is to save memory. + union { + // Used for TD_INTERFACE_IS_TYPE. + struct { + uint8_t argnum; + } interface_is; + + // Used for TD_PSTRING_SIZE_IS, TD_PWSTRING_SIZE_IS. + struct { + uint8_t argnum; + //uint8_t argnum2; // Present on disk, omitted here. + } pstring_is; + + // Used for TD_ARRAY. + struct { + uint8_t argnum; + //uint8_t argnum2; // Present on disk, omitted here. + uint8_t additional_type; // uint16_t on disk, uint8_t here; + // in practice it never exceeds 20. + } array; + + // Used for TD_INTERFACE_TYPE. + struct { + // We store the 16-bit iface value as two 8-bit values in order to + // avoid 16-bit alignment requirements for XPTTypeDescriptor, which + // reduces its size and also the size of XPTParamDescriptor. + uint8_t iface_hi8; + uint8_t iface_lo8; + } iface; + } u; +}; + +/* + * 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_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, + * int64_t, uint64_t, wchar_t, char + * + * 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_t, then value is a two-byte record consisting of a + * 16-bit signed integer. + */ +union XPTConstValue { + int8_t i8; + uint8_t ui8; + int16_t i16; + uint16_t ui16; + int32_t i32; + uint32_t ui32; + int64_t i64; + uint64_t ui64; + char ch; + uint16_t wch; +}; /* varies according to type */ + +struct XPTConstDescriptor { + char *name; + XPTTypeDescriptor type; + union XPTConstValue value; +}; + +/* + * A ParamDescriptor is a variable-size record used to describe either a + * single argument to a method or a method's result. + */ +struct XPTParamDescriptor { + uint8_t flags; + XPTTypeDescriptor type; +}; + +/* flag bits */ +#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_OPTIONAL 0x04 +#define XPT_PD_FLAGMASK 0xfc + +#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) +#define XPT_PD_IS_OPTIONAL(flags) (flags & XPT_PD_OPTIONAL) + +/* + * A MethodDescriptor is a variable-size record used to describe a single + * interface method. + */ +struct XPTMethodDescriptor { + char *name; + XPTParamDescriptor *params; + XPTParamDescriptor result; + uint8_t flags; + uint8_t num_args; +}; + +/* flag bits */ +#define XPT_MD_GETTER 0x80 +#define XPT_MD_SETTER 0x40 +#define XPT_MD_NOTXPCOM 0x20 +#define XPT_MD_HIDDEN 0x08 +#define XPT_MD_OPT_ARGC 0x04 +#define XPT_MD_CONTEXT 0x02 +#define XPT_MD_FLAGMASK 0xfe + +#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_HIDDEN(flags) (flags & XPT_MD_HIDDEN) +#define XPT_MD_WANTS_OPT_ARGC(flags) (flags & XPT_MD_OPT_ARGC) +#define XPT_MD_WANTS_CONTEXT(flags) (flags & XPT_MD_CONTEXT) + +/* + * 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. + * + * We don't actually store annotations; we just skip over them if they are + * present. + */ + +#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) + +} + +#endif /* __xpt_struct_h__ */ |