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:
shaver%netscape.com 1999-01-22 09:13:02 +00:00
parent 87e977ff11
commit 3ffc120748
8 changed files with 536 additions and 88 deletions

View File

@ -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__ */

View File

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

View File

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

View File

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

View File

@ -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__ */

View File

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

View File

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

View File

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