mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-05 08:09:15 +00:00
Added methods to create or fill headers, IDEs, interface descriptors,
method descriptors, param descriptors, const descriptors (partial) and annotations. Rejigged XPTAnnotation for proper struct nesting and linked-listed-ness. Implemented SizeOfHeader (partially). Fixed data_pool handling in XPT_DoHeader. Implemented XPT_SeekTo and XPT_DoIID.
This commit is contained in:
parent
87e977ff11
commit
3ffc120748
@ -65,6 +65,16 @@ struct nsID {
|
||||
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];
|
||||
|
||||
|
||||
/*
|
||||
* Every XPCOM typelib file begins with a header.
|
||||
*/
|
||||
@ -79,6 +89,13 @@ struct XPTHeader {
|
||||
XPTAnnotation *annotations;
|
||||
};
|
||||
|
||||
#define XPT_MAGIC "XPCOM\nTypeLib\r\n\032"
|
||||
#define XPT_MAJOR_VERSION 0x01
|
||||
#define XPT_MINOR_VERSION 0x00
|
||||
|
||||
XPTHeader *
|
||||
XPT_NewHeader(uint32 num_interfaces);
|
||||
|
||||
/*
|
||||
* A contiguous array of fixed-size InterfaceDirectoryEntry records begins at
|
||||
* the byte offset identified by the interface_directory field in the file
|
||||
@ -92,6 +109,11 @@ struct XPTInterfaceDirectoryEntry {
|
||||
XPTInterfaceDescriptor *interface_descriptor;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_FillInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
|
||||
nsID *iid, char *name, char *namespace,
|
||||
XPTInterfaceDescriptor *descriptor);
|
||||
|
||||
/*
|
||||
* An InterfaceDescriptor is a variable-size record used to describe a
|
||||
* single XPCOM interface, including all of its methods.
|
||||
@ -104,6 +126,13 @@ struct XPTInterfaceDescriptor {
|
||||
XPTConstDescriptor *const_descriptors;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_IndexForInterface(XPTInterfaceDirectoryEntry *ide_block,
|
||||
uint32 num_interfaces, nsID *iid, uint32 *indexp);
|
||||
|
||||
XPTInterfaceDescriptor *
|
||||
XPT_NewInterfaceDescriptor(uint32 parent_interface, uint32 num_methods,
|
||||
uint32 num_constants);
|
||||
/*
|
||||
* This is our special string struct with a length value associated with it,
|
||||
* which means that it can contains embedded NULs.
|
||||
@ -113,6 +142,9 @@ struct XPTString {
|
||||
char *bytes;
|
||||
};
|
||||
|
||||
XPTString *
|
||||
XPT_NewString(char *bytes, uint16 len);
|
||||
|
||||
/*
|
||||
* A TypeDescriptor is a variable-size record used to identify the type of a
|
||||
* method argument or return value.
|
||||
@ -194,13 +226,20 @@ struct XPTTypeDescriptorPrefix {
|
||||
#define TD_PWSTRING 17 /* wchar* (pointer to a NUL-terminated array) */
|
||||
|
||||
struct XPTTypeDescriptor {
|
||||
XPTTypeDescriptorPrefix *prefix;
|
||||
XPTTypeDescriptorPrefix prefix;
|
||||
union {
|
||||
uint32 interface;
|
||||
uint8 argnum;
|
||||
} type;
|
||||
};
|
||||
|
||||
#define XPT_COPY_TYPE(to, from) \
|
||||
(to).prefix.is_pointer = (from).prefix.is_pointer; \
|
||||
(to).prefix.is_unique_pointer = (from).prefix.is_unique_pointer; \
|
||||
(to).prefix.is_reference = (from).prefix.is_reference; \
|
||||
(to).prefix.tag = (from).prefix.tag; \
|
||||
(to).type.interface = (from).type.interface
|
||||
|
||||
/*
|
||||
* A ConstDescriptor is a variable-size record that records the name and
|
||||
* value of a scoped interface constant.
|
||||
@ -218,10 +257,7 @@ struct XPTTypeDescriptor {
|
||||
* record is of type String*, i.e. an offset within the data pool to a
|
||||
* String record containing the constant string.
|
||||
*/
|
||||
struct XPTConstDescriptor {
|
||||
char *name;
|
||||
XPTTypeDescriptor type;
|
||||
union {
|
||||
union XPTConstValue {
|
||||
int8 i8;
|
||||
uint8 ui8;
|
||||
int16 i16;
|
||||
@ -233,7 +269,12 @@ struct XPTConstDescriptor {
|
||||
uint16 wch;
|
||||
char ch;
|
||||
XPTString *string;
|
||||
} value; /* varies according to type */
|
||||
}; /* varies according to type */
|
||||
|
||||
struct XPTConstDescriptor {
|
||||
char *name;
|
||||
XPTTypeDescriptor type;
|
||||
union XPTConstValue value;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -245,6 +286,10 @@ struct XPTParamDescriptor {
|
||||
XPTTypeDescriptor type;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_FillParamDescriptor(XPTParamDescriptor *pd, PRBool in, PRBool out,
|
||||
PRBool retval, XPTTypeDescriptor type);
|
||||
|
||||
/*
|
||||
* A MethodDescriptor is a variable-size record used to describe a single
|
||||
* interface method.
|
||||
@ -255,9 +300,15 @@ struct XPTMethodDescriptor {
|
||||
char *name;
|
||||
uint8 num_args;
|
||||
XPTParamDescriptor *params;
|
||||
XPTParamDescriptor result;
|
||||
XPTParamDescriptor *result;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, PRBool is_getter,
|
||||
PRBool is_setter, PRBool is_varargs,
|
||||
PRBool is_constructor, PRBool is_hidden, char *name,
|
||||
uint8 num_args);
|
||||
|
||||
/*
|
||||
* Annotation records are variable-size records used to store secondary
|
||||
* information about the typelib, e.g. such as the name of the tool that
|
||||
@ -289,8 +340,13 @@ struct XPTPrivateAnnotation {
|
||||
};
|
||||
|
||||
struct XPTAnnotation {
|
||||
XPTAnnotationPrefix *prefix;
|
||||
XPTPrivateAnnotation *private;
|
||||
XPTAnnotation *next;
|
||||
XPTAnnotationPrefix prefix;
|
||||
XPTPrivateAnnotation private;
|
||||
};
|
||||
|
||||
XPTAnnotation *
|
||||
XPT_NewAnnotation(PRBool is_last, PRBool is_empty, XPTString *creator,
|
||||
XPTString *private_data);
|
||||
|
||||
#endif /* __xpt_struct_h__ */
|
||||
|
@ -109,6 +109,9 @@ XPT_NewXDRState(XPTMode mode, char *data, uint32 len);
|
||||
PRBool
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, uint32 len, XPTCursor *cursor);
|
||||
|
||||
PRBool
|
||||
XPT_SeekTo(XPTCursor *cursor, uint32 offset);
|
||||
|
||||
void
|
||||
XPT_DestroyXDRState(XPTState *state);
|
||||
|
||||
@ -164,7 +167,7 @@ XPT_SetDataOffset(XPTState *state, uint32 data_offset);
|
||||
if (mode == XPT_DECODE) { \
|
||||
*addrp = localp = PR_NEWZAP(XPTType); \
|
||||
if (!localp || \
|
||||
!XPT_SetAddrForOffset(new_curs, localp)) \
|
||||
!XPT_SetAddrForOffset(&new_curs, localp)) \
|
||||
return PR_FALSE; \
|
||||
} else { \
|
||||
localp = *addrp; \
|
||||
|
@ -20,6 +20,42 @@
|
||||
|
||||
#include "xpt_xdr.h"
|
||||
#include "xpt_struct.h"
|
||||
#include <string.h>
|
||||
|
||||
uint32
|
||||
XPT_SizeOfHeader(XPTHeader *header)
|
||||
{
|
||||
XPTAnnotation *ann;
|
||||
uint32 size = 16 /* magic */ +
|
||||
1 /* major */ + 1 /* minor */ +
|
||||
2 /* num_interfaces */ + 4 /* file_length */ +
|
||||
4 /* interface_directory */ + 4 /* data_pool */;
|
||||
|
||||
/* XXX annotations */
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
XPTHeader *
|
||||
XPT_NewHeader(uint32 num_interfaces)
|
||||
{
|
||||
XPTHeader *header = PR_NEWZAP(XPTHeader);
|
||||
if (!header)
|
||||
return NULL;
|
||||
memcpy(header->magic, XPT_MAGIC, 16);
|
||||
header->major_version = XPT_MAJOR_VERSION;
|
||||
header->minor_version = XPT_MINOR_VERSION;
|
||||
header->num_interfaces = num_interfaces;
|
||||
header->interface_directory = PR_CALLOC(num_interfaces *
|
||||
sizeof(XPTInterfaceDirectoryEntry));
|
||||
if (!header->interface_directory) {
|
||||
PR_DELETE(header);
|
||||
return NULL;
|
||||
}
|
||||
header->data_pool = 0; /* XXX do we even need this struct any more? */
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
@ -35,7 +71,8 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
header = *headerp;
|
||||
|
||||
if (mode == XPT_ENCODE) {
|
||||
ide_offset = XPT_SizeOfHeader(); /* IDEs appear after annotations */
|
||||
/* IDEs appear after header, including annotations */
|
||||
ide_offset = XPT_SizeOfHeader(*headerp);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
@ -45,45 +82,38 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
|
||||
if(!XPT_Do8(cursor, &header->major_version) ||
|
||||
!XPT_Do8(cursor, &header->minor_version) ||
|
||||
/* XXX check major for compat! */
|
||||
!XPT_Do16(cursor, &header->num_interfaces) ||
|
||||
!XPT_Do32(cursor, &header->file_length) ||
|
||||
!XPT_Do32(cursor, &ide_offset)) {
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sections a little hairy right now. We need to do
|
||||
* XPT_DataOffset before writing but after reading.
|
||||
*
|
||||
* if (mode == XPT_DECODE ||
|
||||
* XPT_DataOffset(cursor->state, &header->data_pool)) {
|
||||
* if(!XPT_Do32(cursor, &header->data_pool)) {
|
||||
* goto error;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* if (mode == XPT_ENCODE ||
|
||||
* XPT_DataOffset(cursor->state, &header->data_pool)) {
|
||||
* XPT_DoAnnotations(annotations);
|
||||
* }
|
||||
*/
|
||||
if (mode == XPT_ENCODE)
|
||||
XPT_DataOffset(cursor->state, &header->data_pool);
|
||||
if (!XPT_Do32(cursor, &header->data_pool))
|
||||
goto error;
|
||||
if (mode == XPT_DECODE)
|
||||
XPT_DataOffset(cursor->state, &header->data_pool);
|
||||
|
||||
if (mode == XPT_DECODE) {
|
||||
header->interface_directory =
|
||||
PR_CALLOC(header->num_interfaces *
|
||||
sizeof(XPTInterfaceDirectoryEntry));
|
||||
/* shouldn't be necessary now, but maybe later */
|
||||
XPT_SeekTo(cursor, ide_offset);
|
||||
if (!header->interface_directory)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* XXX handle annotations */
|
||||
|
||||
/* shouldn't be necessary now, but maybe later */
|
||||
XPT_SeekTo(cursor, ide_offset);
|
||||
|
||||
for (i = 0; i < header->num_interfaces; i++) {
|
||||
XPT_DoInterfaceDirectoryEntry(cursor,
|
||||
&header->interface_directory[i]);
|
||||
}
|
||||
|
||||
if (mode == XPT_DECODE)
|
||||
|
||||
for (i = 0; i < header->num_interfaces; i++) {
|
||||
if (!XPT_DoInterfaceDirectoryEntry(&cursor,
|
||||
&header->interface_directory[i]))
|
||||
@ -95,6 +125,18 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
XPT_ERROR_HANDLE(header);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
|
||||
nsID *iid, char *name, char *namespace,
|
||||
XPTInterfaceDescriptor *descriptor)
|
||||
{
|
||||
XPT_COPY_IID(ide->iid, *iid);
|
||||
ide->name = strdup(name);
|
||||
ide->namespace = strdup(namespace);
|
||||
ide->interface_descriptor = descriptor;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* InterfaceDirectoryEntry records go in the header */
|
||||
PRBool
|
||||
XPT_DoInterfaceDirectoryEntry(XPTCursor *cursor,
|
||||
@ -136,6 +178,47 @@ XPT_DoInterfaceDirectoryEntry(XPTCursor *cursor,
|
||||
XPT_ERROR_HANDLE(ide);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_IndexForInterface(XPTInterfaceDirectoryEntry *ide_block,
|
||||
uint32 num_interfaces, nsID *iid, uint32 *indexp)
|
||||
{
|
||||
*indexp = 0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
XPTInterfaceDescriptor *
|
||||
XPT_NewInterfaceDescriptor(uint32 parent_interface, uint32 num_methods,
|
||||
uint32 num_constants)
|
||||
{
|
||||
XPTInterfaceDescriptor *id = PR_NEWZAP(XPTInterfaceDescriptor);
|
||||
if (!id)
|
||||
return NULL;
|
||||
|
||||
if (num_methods) {
|
||||
id->method_descriptors = PR_CALLOC(num_methods *
|
||||
sizeof(XPTMethodDescriptor));
|
||||
if (!id->method_descriptors)
|
||||
goto free_id;
|
||||
id->num_methods = num_methods;
|
||||
}
|
||||
|
||||
if (num_constants) {
|
||||
id->const_descriptors = PR_CALLOC(num_constants *
|
||||
sizeof(XPTConstDescriptor));
|
||||
if (!id->const_descriptors)
|
||||
goto free_meth;
|
||||
id->num_constants = num_constants;
|
||||
}
|
||||
|
||||
return id;
|
||||
|
||||
free_meth:
|
||||
PR_FREEIF(id->method_descriptors);
|
||||
free_id:
|
||||
PR_DELETE(id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor **idp)
|
||||
{
|
||||
@ -182,6 +265,18 @@ XPT_DoInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor **idp)
|
||||
XPT_ERROR_HANDLE(id);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillConstDescriptor(XPTConstDescriptor *cd, char *name,
|
||||
XPTTypeDescriptor type, union XPTConstValue value)
|
||||
{
|
||||
cd->name = strdup(name);
|
||||
if (!cd->name)
|
||||
return PR_FALSE;
|
||||
XPT_COPY_TYPE(cd->type, type);
|
||||
/* XXX copy value */
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
{
|
||||
@ -199,7 +294,7 @@ XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch(cd->type.prefix->tag) {
|
||||
switch(cd->type.prefix.tag) {
|
||||
case TD_INT8:
|
||||
XPT_Do8(cursor, &cd->value.i8);
|
||||
break;
|
||||
@ -231,7 +326,7 @@ XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
XPT_Do16(cursor, &cd->value.wch);
|
||||
break;
|
||||
case TD_PBSTR:
|
||||
if (cd->type.prefix->is_pointer == 1) {
|
||||
if (cd->type.prefix.is_pointer == 1) {
|
||||
XPT_DoString(cursor, &cd->value.string);
|
||||
break;
|
||||
}
|
||||
@ -245,6 +340,36 @@ XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
XPT_ERROR_HANDLE(cd);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, PRBool is_getter,
|
||||
PRBool is_setter, PRBool is_varargs,
|
||||
PRBool is_constructor, PRBool is_hidden, char *name,
|
||||
uint8 num_args)
|
||||
{
|
||||
meth->is_getter = is_getter;
|
||||
meth->is_setter = is_setter;
|
||||
meth->is_constructor = is_constructor;
|
||||
meth->is_hidden = is_hidden;
|
||||
meth->reserved = 0;
|
||||
meth->name = strdup(name);
|
||||
if (!name)
|
||||
return PR_FALSE;
|
||||
meth->num_args = num_args;
|
||||
meth->params = PR_CALLOC(num_args * sizeof(XPTParamDescriptor));
|
||||
if (!meth->params)
|
||||
goto free_name;
|
||||
meth->result = PR_NEWZAP(XPTParamDescriptor);
|
||||
if (!meth->result)
|
||||
goto free_params;
|
||||
return PR_TRUE;
|
||||
|
||||
free_params:
|
||||
PR_DELETE(meth->params);
|
||||
free_name:
|
||||
PR_DELETE(meth->name);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor **mdp)
|
||||
{
|
||||
@ -286,6 +411,17 @@ XPT_DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor **mdp)
|
||||
XPT_ERROR_HANDLE(md);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillParamDescriptor(XPTParamDescriptor *pd, PRBool in, PRBool out,
|
||||
PRBool retval, XPTTypeDescriptor type)
|
||||
{
|
||||
pd->in = in;
|
||||
pd->out = out;
|
||||
pd->retval = retval;
|
||||
pd->reserved = 0;
|
||||
XPT_COPY_TYPE(pd->type, type);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoParamDescriptor(XPTCursor *cursor, XPTParamDescriptor **pdp)
|
||||
{
|
||||
@ -352,11 +488,11 @@ XPT_DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor **tdp)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (td->prefix->tag == TD_INTERFACE_TYPE) {
|
||||
if (td->prefix.tag == TD_INTERFACE_TYPE) {
|
||||
if (!XPT_Do32(cursor, &td->type.interface))
|
||||
goto error;
|
||||
} else {
|
||||
if (td->prefix->tag == TD_INTERFACE_IS_TYPE) {
|
||||
if (td->prefix.tag == TD_INTERFACE_IS_TYPE) {
|
||||
if (!XPT_Do8(cursor, &td->type.argnum))
|
||||
goto error;
|
||||
}
|
||||
@ -367,6 +503,22 @@ XPT_DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor **tdp)
|
||||
XPT_ERROR_HANDLE(td);
|
||||
}
|
||||
|
||||
XPTAnnotation *
|
||||
XPT_NewAnnotation(PRBool is_last, PRBool is_empty, XPTString *creator,
|
||||
XPTString *private_data)
|
||||
{
|
||||
XPTAnnotation *ann = PR_NEWZAP(XPTAnnotation);
|
||||
if (!ann)
|
||||
return NULL;
|
||||
ann->prefix.is_last = is_last;
|
||||
ann->prefix.tag = is_empty ? 0 : 1;
|
||||
if (!is_empty) {
|
||||
ann->private.creator = creator;
|
||||
ann->private.private_data = private_data;
|
||||
}
|
||||
return ann;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoAnnotationPrefix(XPTCursor *cursor, XPTAnnotationPrefix **app)
|
||||
{
|
||||
@ -427,7 +579,7 @@ XPT_DoAnnotation(XPTCursor *cursor, XPTAnnotation **ap)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (a->prefix->tag == PRIVATE_ANNOTATION) {
|
||||
if (a->prefix.tag == PRIVATE_ANNOTATION) {
|
||||
if (!XPT_DoPrivateAnnotation(cursor, &a->private)) {
|
||||
goto error;
|
||||
}
|
||||
@ -443,12 +595,6 @@ XPT_DoAnnotations(XPTCursor *cursor, XPTAnnotation **ap) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
XPT_SizeOfHeader(XPTHeader *headerp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
XPT_SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *idp)
|
||||
{
|
||||
|
@ -184,6 +184,14 @@ XPT_MakeCursor(XPTState *state, XPTPool pool, uint32 len, XPTCursor *cursor)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_SeekTo(XPTCursor *cursor, uint32 offset)
|
||||
{
|
||||
/* XXX do some real checking and update len and stuff */
|
||||
cursor->offset = offset;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoString(XPTCursor *cursor, XPTString **strp)
|
||||
{
|
||||
@ -339,7 +347,18 @@ XPT_CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, int len,
|
||||
PRBool
|
||||
XPT_DoIID(XPTCursor *cursor, nsID *iidp)
|
||||
{
|
||||
return PR_FALSE;
|
||||
int i;
|
||||
|
||||
if (!XPT_Do32(cursor, &iidp->m0) ||
|
||||
!XPT_Do16(cursor, &iidp->m1) ||
|
||||
!XPT_Do16(cursor, &iidp->m2))
|
||||
return PR_FALSE;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!XPT_Do8(cursor, &iidp->m3[i]))
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -65,6 +65,16 @@ struct nsID {
|
||||
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];
|
||||
|
||||
|
||||
/*
|
||||
* Every XPCOM typelib file begins with a header.
|
||||
*/
|
||||
@ -79,6 +89,13 @@ struct XPTHeader {
|
||||
XPTAnnotation *annotations;
|
||||
};
|
||||
|
||||
#define XPT_MAGIC "XPCOM\nTypeLib\r\n\032"
|
||||
#define XPT_MAJOR_VERSION 0x01
|
||||
#define XPT_MINOR_VERSION 0x00
|
||||
|
||||
XPTHeader *
|
||||
XPT_NewHeader(uint32 num_interfaces);
|
||||
|
||||
/*
|
||||
* A contiguous array of fixed-size InterfaceDirectoryEntry records begins at
|
||||
* the byte offset identified by the interface_directory field in the file
|
||||
@ -92,6 +109,11 @@ struct XPTInterfaceDirectoryEntry {
|
||||
XPTInterfaceDescriptor *interface_descriptor;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_FillInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
|
||||
nsID *iid, char *name, char *namespace,
|
||||
XPTInterfaceDescriptor *descriptor);
|
||||
|
||||
/*
|
||||
* An InterfaceDescriptor is a variable-size record used to describe a
|
||||
* single XPCOM interface, including all of its methods.
|
||||
@ -104,6 +126,13 @@ struct XPTInterfaceDescriptor {
|
||||
XPTConstDescriptor *const_descriptors;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_IndexForInterface(XPTInterfaceDirectoryEntry *ide_block,
|
||||
uint32 num_interfaces, nsID *iid, uint32 *indexp);
|
||||
|
||||
XPTInterfaceDescriptor *
|
||||
XPT_NewInterfaceDescriptor(uint32 parent_interface, uint32 num_methods,
|
||||
uint32 num_constants);
|
||||
/*
|
||||
* This is our special string struct with a length value associated with it,
|
||||
* which means that it can contains embedded NULs.
|
||||
@ -113,6 +142,9 @@ struct XPTString {
|
||||
char *bytes;
|
||||
};
|
||||
|
||||
XPTString *
|
||||
XPT_NewString(char *bytes, uint16 len);
|
||||
|
||||
/*
|
||||
* A TypeDescriptor is a variable-size record used to identify the type of a
|
||||
* method argument or return value.
|
||||
@ -194,13 +226,20 @@ struct XPTTypeDescriptorPrefix {
|
||||
#define TD_PWSTRING 17 /* wchar* (pointer to a NUL-terminated array) */
|
||||
|
||||
struct XPTTypeDescriptor {
|
||||
XPTTypeDescriptorPrefix *prefix;
|
||||
XPTTypeDescriptorPrefix prefix;
|
||||
union {
|
||||
uint32 interface;
|
||||
uint8 argnum;
|
||||
} type;
|
||||
};
|
||||
|
||||
#define XPT_COPY_TYPE(to, from) \
|
||||
(to).prefix.is_pointer = (from).prefix.is_pointer; \
|
||||
(to).prefix.is_unique_pointer = (from).prefix.is_unique_pointer; \
|
||||
(to).prefix.is_reference = (from).prefix.is_reference; \
|
||||
(to).prefix.tag = (from).prefix.tag; \
|
||||
(to).type.interface = (from).type.interface
|
||||
|
||||
/*
|
||||
* A ConstDescriptor is a variable-size record that records the name and
|
||||
* value of a scoped interface constant.
|
||||
@ -218,10 +257,7 @@ struct XPTTypeDescriptor {
|
||||
* record is of type String*, i.e. an offset within the data pool to a
|
||||
* String record containing the constant string.
|
||||
*/
|
||||
struct XPTConstDescriptor {
|
||||
char *name;
|
||||
XPTTypeDescriptor type;
|
||||
union {
|
||||
union XPTConstValue {
|
||||
int8 i8;
|
||||
uint8 ui8;
|
||||
int16 i16;
|
||||
@ -233,7 +269,12 @@ struct XPTConstDescriptor {
|
||||
uint16 wch;
|
||||
char ch;
|
||||
XPTString *string;
|
||||
} value; /* varies according to type */
|
||||
}; /* varies according to type */
|
||||
|
||||
struct XPTConstDescriptor {
|
||||
char *name;
|
||||
XPTTypeDescriptor type;
|
||||
union XPTConstValue value;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -245,6 +286,10 @@ struct XPTParamDescriptor {
|
||||
XPTTypeDescriptor type;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_FillParamDescriptor(XPTParamDescriptor *pd, PRBool in, PRBool out,
|
||||
PRBool retval, XPTTypeDescriptor type);
|
||||
|
||||
/*
|
||||
* A MethodDescriptor is a variable-size record used to describe a single
|
||||
* interface method.
|
||||
@ -255,9 +300,15 @@ struct XPTMethodDescriptor {
|
||||
char *name;
|
||||
uint8 num_args;
|
||||
XPTParamDescriptor *params;
|
||||
XPTParamDescriptor result;
|
||||
XPTParamDescriptor *result;
|
||||
};
|
||||
|
||||
PRBool
|
||||
XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, PRBool is_getter,
|
||||
PRBool is_setter, PRBool is_varargs,
|
||||
PRBool is_constructor, PRBool is_hidden, char *name,
|
||||
uint8 num_args);
|
||||
|
||||
/*
|
||||
* Annotation records are variable-size records used to store secondary
|
||||
* information about the typelib, e.g. such as the name of the tool that
|
||||
@ -289,8 +340,13 @@ struct XPTPrivateAnnotation {
|
||||
};
|
||||
|
||||
struct XPTAnnotation {
|
||||
XPTAnnotationPrefix *prefix;
|
||||
XPTPrivateAnnotation *private;
|
||||
XPTAnnotation *next;
|
||||
XPTAnnotationPrefix prefix;
|
||||
XPTPrivateAnnotation private;
|
||||
};
|
||||
|
||||
XPTAnnotation *
|
||||
XPT_NewAnnotation(PRBool is_last, PRBool is_empty, XPTString *creator,
|
||||
XPTString *private_data);
|
||||
|
||||
#endif /* __xpt_struct_h__ */
|
||||
|
@ -109,6 +109,9 @@ XPT_NewXDRState(XPTMode mode, char *data, uint32 len);
|
||||
PRBool
|
||||
XPT_MakeCursor(XPTState *state, XPTPool pool, uint32 len, XPTCursor *cursor);
|
||||
|
||||
PRBool
|
||||
XPT_SeekTo(XPTCursor *cursor, uint32 offset);
|
||||
|
||||
void
|
||||
XPT_DestroyXDRState(XPTState *state);
|
||||
|
||||
@ -164,7 +167,7 @@ XPT_SetDataOffset(XPTState *state, uint32 data_offset);
|
||||
if (mode == XPT_DECODE) { \
|
||||
*addrp = localp = PR_NEWZAP(XPTType); \
|
||||
if (!localp || \
|
||||
!XPT_SetAddrForOffset(new_curs, localp)) \
|
||||
!XPT_SetAddrForOffset(&new_curs, localp)) \
|
||||
return PR_FALSE; \
|
||||
} else { \
|
||||
localp = *addrp; \
|
||||
|
@ -20,6 +20,42 @@
|
||||
|
||||
#include "xpt_xdr.h"
|
||||
#include "xpt_struct.h"
|
||||
#include <string.h>
|
||||
|
||||
uint32
|
||||
XPT_SizeOfHeader(XPTHeader *header)
|
||||
{
|
||||
XPTAnnotation *ann;
|
||||
uint32 size = 16 /* magic */ +
|
||||
1 /* major */ + 1 /* minor */ +
|
||||
2 /* num_interfaces */ + 4 /* file_length */ +
|
||||
4 /* interface_directory */ + 4 /* data_pool */;
|
||||
|
||||
/* XXX annotations */
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
XPTHeader *
|
||||
XPT_NewHeader(uint32 num_interfaces)
|
||||
{
|
||||
XPTHeader *header = PR_NEWZAP(XPTHeader);
|
||||
if (!header)
|
||||
return NULL;
|
||||
memcpy(header->magic, XPT_MAGIC, 16);
|
||||
header->major_version = XPT_MAJOR_VERSION;
|
||||
header->minor_version = XPT_MINOR_VERSION;
|
||||
header->num_interfaces = num_interfaces;
|
||||
header->interface_directory = PR_CALLOC(num_interfaces *
|
||||
sizeof(XPTInterfaceDirectoryEntry));
|
||||
if (!header->interface_directory) {
|
||||
PR_DELETE(header);
|
||||
return NULL;
|
||||
}
|
||||
header->data_pool = 0; /* XXX do we even need this struct any more? */
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
@ -35,7 +71,8 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
header = *headerp;
|
||||
|
||||
if (mode == XPT_ENCODE) {
|
||||
ide_offset = XPT_SizeOfHeader(); /* IDEs appear after annotations */
|
||||
/* IDEs appear after header, including annotations */
|
||||
ide_offset = XPT_SizeOfHeader(*headerp);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
@ -45,45 +82,38 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
|
||||
if(!XPT_Do8(cursor, &header->major_version) ||
|
||||
!XPT_Do8(cursor, &header->minor_version) ||
|
||||
/* XXX check major for compat! */
|
||||
!XPT_Do16(cursor, &header->num_interfaces) ||
|
||||
!XPT_Do32(cursor, &header->file_length) ||
|
||||
!XPT_Do32(cursor, &ide_offset)) {
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sections a little hairy right now. We need to do
|
||||
* XPT_DataOffset before writing but after reading.
|
||||
*
|
||||
* if (mode == XPT_DECODE ||
|
||||
* XPT_DataOffset(cursor->state, &header->data_pool)) {
|
||||
* if(!XPT_Do32(cursor, &header->data_pool)) {
|
||||
* goto error;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* if (mode == XPT_ENCODE ||
|
||||
* XPT_DataOffset(cursor->state, &header->data_pool)) {
|
||||
* XPT_DoAnnotations(annotations);
|
||||
* }
|
||||
*/
|
||||
if (mode == XPT_ENCODE)
|
||||
XPT_DataOffset(cursor->state, &header->data_pool);
|
||||
if (!XPT_Do32(cursor, &header->data_pool))
|
||||
goto error;
|
||||
if (mode == XPT_DECODE)
|
||||
XPT_DataOffset(cursor->state, &header->data_pool);
|
||||
|
||||
if (mode == XPT_DECODE) {
|
||||
header->interface_directory =
|
||||
PR_CALLOC(header->num_interfaces *
|
||||
sizeof(XPTInterfaceDirectoryEntry));
|
||||
/* shouldn't be necessary now, but maybe later */
|
||||
XPT_SeekTo(cursor, ide_offset);
|
||||
if (!header->interface_directory)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* XXX handle annotations */
|
||||
|
||||
/* shouldn't be necessary now, but maybe later */
|
||||
XPT_SeekTo(cursor, ide_offset);
|
||||
|
||||
for (i = 0; i < header->num_interfaces; i++) {
|
||||
XPT_DoInterfaceDirectoryEntry(cursor,
|
||||
&header->interface_directory[i]);
|
||||
}
|
||||
|
||||
if (mode == XPT_DECODE)
|
||||
|
||||
for (i = 0; i < header->num_interfaces; i++) {
|
||||
if (!XPT_DoInterfaceDirectoryEntry(&cursor,
|
||||
&header->interface_directory[i]))
|
||||
@ -95,6 +125,18 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
|
||||
XPT_ERROR_HANDLE(header);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
|
||||
nsID *iid, char *name, char *namespace,
|
||||
XPTInterfaceDescriptor *descriptor)
|
||||
{
|
||||
XPT_COPY_IID(ide->iid, *iid);
|
||||
ide->name = strdup(name);
|
||||
ide->namespace = strdup(namespace);
|
||||
ide->interface_descriptor = descriptor;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* InterfaceDirectoryEntry records go in the header */
|
||||
PRBool
|
||||
XPT_DoInterfaceDirectoryEntry(XPTCursor *cursor,
|
||||
@ -136,6 +178,47 @@ XPT_DoInterfaceDirectoryEntry(XPTCursor *cursor,
|
||||
XPT_ERROR_HANDLE(ide);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_IndexForInterface(XPTInterfaceDirectoryEntry *ide_block,
|
||||
uint32 num_interfaces, nsID *iid, uint32 *indexp)
|
||||
{
|
||||
*indexp = 0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
XPTInterfaceDescriptor *
|
||||
XPT_NewInterfaceDescriptor(uint32 parent_interface, uint32 num_methods,
|
||||
uint32 num_constants)
|
||||
{
|
||||
XPTInterfaceDescriptor *id = PR_NEWZAP(XPTInterfaceDescriptor);
|
||||
if (!id)
|
||||
return NULL;
|
||||
|
||||
if (num_methods) {
|
||||
id->method_descriptors = PR_CALLOC(num_methods *
|
||||
sizeof(XPTMethodDescriptor));
|
||||
if (!id->method_descriptors)
|
||||
goto free_id;
|
||||
id->num_methods = num_methods;
|
||||
}
|
||||
|
||||
if (num_constants) {
|
||||
id->const_descriptors = PR_CALLOC(num_constants *
|
||||
sizeof(XPTConstDescriptor));
|
||||
if (!id->const_descriptors)
|
||||
goto free_meth;
|
||||
id->num_constants = num_constants;
|
||||
}
|
||||
|
||||
return id;
|
||||
|
||||
free_meth:
|
||||
PR_FREEIF(id->method_descriptors);
|
||||
free_id:
|
||||
PR_DELETE(id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor **idp)
|
||||
{
|
||||
@ -182,6 +265,18 @@ XPT_DoInterfaceDescriptor(XPTCursor *cursor, XPTInterfaceDescriptor **idp)
|
||||
XPT_ERROR_HANDLE(id);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillConstDescriptor(XPTConstDescriptor *cd, char *name,
|
||||
XPTTypeDescriptor type, union XPTConstValue value)
|
||||
{
|
||||
cd->name = strdup(name);
|
||||
if (!cd->name)
|
||||
return PR_FALSE;
|
||||
XPT_COPY_TYPE(cd->type, type);
|
||||
/* XXX copy value */
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
{
|
||||
@ -199,7 +294,7 @@ XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch(cd->type.prefix->tag) {
|
||||
switch(cd->type.prefix.tag) {
|
||||
case TD_INT8:
|
||||
XPT_Do8(cursor, &cd->value.i8);
|
||||
break;
|
||||
@ -231,7 +326,7 @@ XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
XPT_Do16(cursor, &cd->value.wch);
|
||||
break;
|
||||
case TD_PBSTR:
|
||||
if (cd->type.prefix->is_pointer == 1) {
|
||||
if (cd->type.prefix.is_pointer == 1) {
|
||||
XPT_DoString(cursor, &cd->value.string);
|
||||
break;
|
||||
}
|
||||
@ -245,6 +340,36 @@ XPT_DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor **cdp)
|
||||
XPT_ERROR_HANDLE(cd);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, PRBool is_getter,
|
||||
PRBool is_setter, PRBool is_varargs,
|
||||
PRBool is_constructor, PRBool is_hidden, char *name,
|
||||
uint8 num_args)
|
||||
{
|
||||
meth->is_getter = is_getter;
|
||||
meth->is_setter = is_setter;
|
||||
meth->is_constructor = is_constructor;
|
||||
meth->is_hidden = is_hidden;
|
||||
meth->reserved = 0;
|
||||
meth->name = strdup(name);
|
||||
if (!name)
|
||||
return PR_FALSE;
|
||||
meth->num_args = num_args;
|
||||
meth->params = PR_CALLOC(num_args * sizeof(XPTParamDescriptor));
|
||||
if (!meth->params)
|
||||
goto free_name;
|
||||
meth->result = PR_NEWZAP(XPTParamDescriptor);
|
||||
if (!meth->result)
|
||||
goto free_params;
|
||||
return PR_TRUE;
|
||||
|
||||
free_params:
|
||||
PR_DELETE(meth->params);
|
||||
free_name:
|
||||
PR_DELETE(meth->name);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor **mdp)
|
||||
{
|
||||
@ -286,6 +411,17 @@ XPT_DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor **mdp)
|
||||
XPT_ERROR_HANDLE(md);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_FillParamDescriptor(XPTParamDescriptor *pd, PRBool in, PRBool out,
|
||||
PRBool retval, XPTTypeDescriptor type)
|
||||
{
|
||||
pd->in = in;
|
||||
pd->out = out;
|
||||
pd->retval = retval;
|
||||
pd->reserved = 0;
|
||||
XPT_COPY_TYPE(pd->type, type);
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoParamDescriptor(XPTCursor *cursor, XPTParamDescriptor **pdp)
|
||||
{
|
||||
@ -352,11 +488,11 @@ XPT_DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor **tdp)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (td->prefix->tag == TD_INTERFACE_TYPE) {
|
||||
if (td->prefix.tag == TD_INTERFACE_TYPE) {
|
||||
if (!XPT_Do32(cursor, &td->type.interface))
|
||||
goto error;
|
||||
} else {
|
||||
if (td->prefix->tag == TD_INTERFACE_IS_TYPE) {
|
||||
if (td->prefix.tag == TD_INTERFACE_IS_TYPE) {
|
||||
if (!XPT_Do8(cursor, &td->type.argnum))
|
||||
goto error;
|
||||
}
|
||||
@ -367,6 +503,22 @@ XPT_DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor **tdp)
|
||||
XPT_ERROR_HANDLE(td);
|
||||
}
|
||||
|
||||
XPTAnnotation *
|
||||
XPT_NewAnnotation(PRBool is_last, PRBool is_empty, XPTString *creator,
|
||||
XPTString *private_data)
|
||||
{
|
||||
XPTAnnotation *ann = PR_NEWZAP(XPTAnnotation);
|
||||
if (!ann)
|
||||
return NULL;
|
||||
ann->prefix.is_last = is_last;
|
||||
ann->prefix.tag = is_empty ? 0 : 1;
|
||||
if (!is_empty) {
|
||||
ann->private.creator = creator;
|
||||
ann->private.private_data = private_data;
|
||||
}
|
||||
return ann;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoAnnotationPrefix(XPTCursor *cursor, XPTAnnotationPrefix **app)
|
||||
{
|
||||
@ -427,7 +579,7 @@ XPT_DoAnnotation(XPTCursor *cursor, XPTAnnotation **ap)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (a->prefix->tag == PRIVATE_ANNOTATION) {
|
||||
if (a->prefix.tag == PRIVATE_ANNOTATION) {
|
||||
if (!XPT_DoPrivateAnnotation(cursor, &a->private)) {
|
||||
goto error;
|
||||
}
|
||||
@ -443,12 +595,6 @@ XPT_DoAnnotations(XPTCursor *cursor, XPTAnnotation **ap) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
XPT_SizeOfHeader(XPTHeader *headerp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
XPT_SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *idp)
|
||||
{
|
||||
|
@ -184,6 +184,14 @@ XPT_MakeCursor(XPTState *state, XPTPool pool, uint32 len, XPTCursor *cursor)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_SeekTo(XPTCursor *cursor, uint32 offset)
|
||||
{
|
||||
/* XXX do some real checking and update len and stuff */
|
||||
cursor->offset = offset;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
XPT_DoString(XPTCursor *cursor, XPTString **strp)
|
||||
{
|
||||
@ -339,7 +347,18 @@ XPT_CheckForRepeat(XPTCursor *cursor, void **addrp, XPTPool pool, int len,
|
||||
PRBool
|
||||
XPT_DoIID(XPTCursor *cursor, nsID *iidp)
|
||||
{
|
||||
return PR_FALSE;
|
||||
int i;
|
||||
|
||||
if (!XPT_Do32(cursor, &iidp->m0) ||
|
||||
!XPT_Do16(cursor, &iidp->m1) ||
|
||||
!XPT_Do16(cursor, &iidp->m2))
|
||||
return PR_FALSE;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!XPT_Do8(cursor, &iidp->m3[i]))
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
Loading…
x
Reference in New Issue
Block a user