Only alloc space for interface records if we actually have interfaces; fixes a calloc(1,0) bug that was breaking the AIX build. (Thanks to Jim Dunn <jdunn@netscape.com> for finding this, and to Mike Shaver <shaver@netscape.com> for contributing the patch.

The xpcom tree remains closed, but this patch gets in for m6 by special dispensation.

A=leaf,dp
This commit is contained in:
mccabe%netscape.com 1999-05-18 02:10:05 +00:00
Родитель c7ac90f4c8
Коммит 7eb824fa0e
2 изменённых файлов: 9 добавлений и 793 удалений

Просмотреть файл

@ -1,786 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* Implementation of XDR routines for typelib structures. */
#include "xpt_xdr.h"
#include "xpt_struct.h"
#include <string.h>
#ifdef XP_MAC
static char *strdup(const char *c)
{
char *newStr = malloc(strlen(c) + 1);
if (newStr)
{
strcpy(newStr, c);
}
return newStr;
}
#endif
static PRBool
DoInterfaceDirectoryEntry(XPTCursor *cursor,
XPTInterfaceDirectoryEntry *ide, PRUint16 index);
#if 0
/* currently unused */
static PRBool
DoInterfaceDirectoryEntryIndex(XPTCursor *cursor,
XPTInterfaceDirectoryEntry **idep);
#endif
static PRBool
DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor *cd);
static PRBool
DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor *md);
static PRBool
DoAnnotation(XPTCursor *cursor, XPTAnnotation **annp);
static PRBool
DoInterfaceDescriptor(XPTCursor *outer, XPTInterfaceDescriptor **idp);
static PRBool
DoTypeDescriptorPrefix(XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp);
static PRBool
DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor *td);
static PRBool
DoParamDescriptor(XPTCursor *cursor, XPTParamDescriptor *pd);
#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)
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(PRUint16 num_interfaces)
{
XPTHeader *header = XPT_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 = XPT_CALLOC(num_interfaces *
sizeof(XPTInterfaceDirectoryEntry));
if (!header->interface_directory) {
XPT_DELETE(header);
return NULL;
}
header->data_pool = 0; /* XXX do we even need this struct any more? */
return header;
}
XPT_PUBLIC_API(PRBool)
XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
{
XPTMode mode = cursor->state->mode;
XPTHeader *header;
PRUint32 ide_offset;
int i;
if (mode == XPT_DECODE) {
header = XPT_NEWZAP(XPTHeader);
if (!header)
return PR_FALSE;
*headerp = header;
} else {
header = *headerp;
}
if (mode == XPT_ENCODE) {
/* IDEs appear after header, including annotations */
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 < 16; i++) {
if (!XPT_Do8(cursor, &header->magic[i]))
goto error;
}
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;
}
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 =
XPT_CALLOC(header->num_interfaces *
sizeof(XPTInterfaceDirectoryEntry));
if (!header->interface_directory)
goto error;
}
if (!DoAnnotation(cursor, &header->annotations))
goto error;
/* shouldn't be necessary now, but maybe later */
XPT_SeekTo(cursor, ide_offset);
for (i = 0; i < header->num_interfaces; i++) {
if (!DoInterfaceDirectoryEntry(cursor,
&header->interface_directory[i],
(PRUint16)(i + 1)))
goto error;
}
return PR_TRUE;
/* XXX need to free child data sometimes! */
XPT_ERROR_HANDLE(header);
}
XPT_PUBLIC_API(PRBool)
XPT_FillInterfaceDirectoryEntry(XPTInterfaceDirectoryEntry *ide,
nsID *iid, char *name, char *name_space,
XPTInterfaceDescriptor *descriptor)
{
XPT_COPY_IID(ide->iid, *iid);
ide->name = name ? strdup(name) : NULL; /* what good is it w/o a name? */
ide->name_space = name_space ? strdup(name_space) : NULL;
ide->interface_descriptor = descriptor;
return PR_TRUE;
}
/* InterfaceDirectoryEntry records go in the header */
PRBool
DoInterfaceDirectoryEntry(XPTCursor *cursor,
XPTInterfaceDirectoryEntry *ide, PRUint16 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(cursor, &(ide->name)) ||
/* write the name_space string in the data pool, and the offset in our
cursor space */
!XPT_DoCString(cursor, &(ide->name_space)) ||
/* do InterfaceDescriptors -- later, only on encode (see below) */
!DoInterfaceDescriptor(cursor, &ide->interface_descriptor)) {
goto error;
}
if (mode == XPT_DECODE)
XPT_SetOffsetForAddr(cursor, ide, index);
#if 0 /* not yet -- we eagerly load for now */
/* write the InterfaceDescriptor in the data pool, and the offset
in our cursor space, but only if we're encoding. */
if (mode == XPT_ENCODE) {
if (!DoInterfaceDescriptor(cursor,
&ide->interface_descriptor)) {
goto error;
}
}
#endif
return PR_TRUE;
XPT_ERROR_HANDLE(ide);
}
#if 0
/*
* Decode: Get the interface directory entry for the on-disk index.
* Encode: Write the index.
*/
PRBool
DoInterfaceDirectoryEntryIndex(XPTCursor *cursor,
XPTInterfaceDirectoryEntry **idep)
{
XPTMode mode = cursor->state->mode;
PRUint16 index;
if (mode == XPT_ENCODE) {
/* XXX index zero is legal, so how do I detect an error? */
if (*idep) {
index = (PRUint16) XPT_GetOffsetForAddr(cursor, *idep);
if (!index)
return PR_FALSE;
} else {
index = 0; /* no interface */
}
}
if (!XPT_Do16(cursor, &index))
return PR_FALSE;
if (mode == XPT_DECODE) {
if (index) {
*idep = XPT_GetAddrForOffset(cursor, index);
if (!*idep)
return PR_FALSE;
} else {
*idep = NULL;
}
}
return PR_TRUE;
}
#endif
XPT_PUBLIC_API(XPTInterfaceDescriptor *)
XPT_NewInterfaceDescriptor(PRUint16 parent_interface, PRUint16 num_methods,
PRUint16 num_constants, PRUint8 flags)
{
XPTInterfaceDescriptor *id = XPT_NEWZAP(XPTInterfaceDescriptor);
if (!id)
return NULL;
if (num_methods) {
id->method_descriptors = XPT_CALLOC(num_methods *
sizeof(XPTMethodDescriptor));
if (!id->method_descriptors)
goto free_id;
id->num_methods = num_methods;
}
if (num_constants) {
id->const_descriptors = XPT_CALLOC(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(id->method_descriptors);
free_id:
XPT_DELETE(id);
return NULL;
}
XPT_PUBLIC_API(PRBool)
XPT_InterfaceDescriptorAddMethods(XPTInterfaceDescriptor *id, PRUint16 num)
{
XPTMethodDescriptor *old = id->method_descriptors, *new;
/* XXX should grow in chunks to minimize realloc overhead */
new = XPT_REALLOC(old,
(id->num_methods + num) * sizeof(XPTMethodDescriptor));
if (!new)
return PR_FALSE;
memset(new + id->num_methods, 0, sizeof(XPTMethodDescriptor) * num);
id->method_descriptors = new;
id->num_methods += num;
return PR_TRUE;
}
XPT_PUBLIC_API(PRBool)
XPT_InterfaceDescriptorAddConsts(XPTInterfaceDescriptor *id, PRUint16 num)
{
XPTConstDescriptor *old = id->const_descriptors, *new;
/* XXX should grow in chunks to minimize realloc overhead */
new = XPT_REALLOC(old,
(id->num_constants + num) * sizeof(XPTConstDescriptor));
if (!new)
return PR_FALSE;
memset(new + id->num_constants, 0, sizeof(XPTConstDescriptor) * num);
id->const_descriptors = new;
id->num_constants += num;
return PR_TRUE;
}
XPT_PUBLIC_API(PRUint32)
XPT_SizeOfTypeDescriptor(XPTTypeDescriptor *td)
{
PRUint32 size = 1; /* prefix */
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE)
size += 2; /* interface_index */
else if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE)
size += 1; /* arg_num */
return size;
}
XPT_PUBLIC_API(PRUint32)
XPT_SizeOfMethodDescriptor(XPTMethodDescriptor *md)
{
PRUint32 i, size = 1 /* flags */ + 4 /* name */ + 1 /* num_args */;
for (i = 0; i < md->num_args; i++)
size += 1 + XPT_SizeOfTypeDescriptor(&md->params[i].type);
size += 1 + XPT_SizeOfTypeDescriptor(&md->result->type);
return size;
}
XPT_PUBLIC_API(PRUint32)
XPT_SizeOfConstDescriptor(XPTConstDescriptor *cd)
{
PRUint32 size = 4 /* name */ + XPT_SizeOfTypeDescriptor(&cd->type);
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_PBSTR: /* XXX check for pointer! */
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;
}
XPT_PUBLIC_API(PRUint32)
XPT_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 += XPT_SizeOfMethodDescriptor(&id->method_descriptors[i]);
for (i = 0; i < id->num_constants; i++)
size += XPT_SizeOfConstDescriptor(&id->const_descriptors[i]);
return size;
}
PRBool
DoInterfaceDescriptor(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(XPTInterfaceDescriptor);
if (!id)
return PR_FALSE;
*idp = id;
} else {
id = *idp;
if (!id) {
id_sz = 0;
return XPT_Do32(outer, &id_sz);
}
id_sz = XPT_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) {
*idp = NULL;
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(id->num_methods *
sizeof(XPTMethodDescriptor));
if (!id->method_descriptors)
goto error;
}
for (i = 0; i < id->num_methods; i++) {
if (!DoMethodDescriptor(cursor, &id->method_descriptors[i]))
goto error;
}
if (!XPT_Do16(cursor, &id->num_constants)) {
goto error;
}
if (mode == XPT_DECODE && id->num_constants) {
id->const_descriptors = XPT_CALLOC(id->num_constants *
sizeof(XPTConstDescriptor));
if (!id->const_descriptors)
goto error;
}
for (i = 0; i < id->num_constants; i++) {
if (!DoConstDescriptor(cursor, &id->const_descriptors[i])) {
goto error;
}
}
if (!XPT_Do8(cursor, &id->flags)) {
goto error;
}
return PR_TRUE;
XPT_ERROR_HANDLE(id);
}
XPT_PUBLIC_API(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
DoConstDescriptor(XPTCursor *cursor, XPTConstDescriptor *cd)
{
PRBool ok = PR_FALSE;
if (!XPT_DoCString(cursor, &cd->name) ||
!DoTypeDescriptor(cursor, &cd->type)) {
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, &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;
case TD_PBSTR:
if (cd->type.prefix.flags & XPT_TDP_POINTER) {
ok = XPT_DoString(cursor, &cd->value.string);
break;
}
/* fall-through */
default:
fprintf(stderr, "illegal type!\n");
break;
}
return ok;
}
XPT_PUBLIC_API(PRBool)
XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, PRUint8 flags, char *name,
PRUint8 num_args)
{
meth->flags = flags & XPT_MD_FLAGMASK;
meth->name = strdup(name);
if (!name)
return PR_FALSE;
meth->num_args = num_args;
if (meth->num_args) {
meth->params = XPT_CALLOC(num_args * sizeof(XPTParamDescriptor));
if (!meth->params)
goto free_name;
} else {
meth->params = NULL;
}
meth->result = XPT_NEWZAP(XPTParamDescriptor);
if (!meth->result)
goto free_params;
return PR_TRUE;
free_params:
XPT_DELETE(meth->params);
free_name:
XPT_DELETE(meth->name);
return PR_FALSE;
}
PRBool
DoMethodDescriptor(XPTCursor *cursor, XPTMethodDescriptor *md)
{
XPTMode mode = cursor->state->mode;
int i;
if (!XPT_Do8(cursor, &md->flags) ||
!XPT_DoCString(cursor, &md->name) ||
!XPT_Do8(cursor, &md->num_args))
return PR_FALSE;
if (mode == XPT_DECODE && md->num_args) {
md->params = XPT_CALLOC(md->num_args * sizeof(XPTParamDescriptor));
if (!md->params)
return PR_FALSE;
}
for(i = 0; i < md->num_args; i++) {
if (!DoParamDescriptor(cursor, &md->params[i]))
goto error;
}
if (mode == XPT_DECODE) {
md->result = XPT_NEWZAP(XPTParamDescriptor);
if (!md->result)
return PR_FALSE;
}
if (!md->result ||
!DoParamDescriptor(cursor, md->result))
goto error;
return PR_TRUE;
XPT_ERROR_HANDLE(md->params);
}
XPT_PUBLIC_API(PRBool)
XPT_FillParamDescriptor(XPTParamDescriptor *pd, PRUint8 flags,
XPTTypeDescriptor *type)
{
pd->flags = flags & XPT_PD_FLAGMASK;
XPT_COPY_TYPE(pd->type, *type);
return PR_TRUE;
}
PRBool
DoParamDescriptor(XPTCursor *cursor, XPTParamDescriptor *pd)
{
if (!XPT_Do8(cursor, &pd->flags) ||
!DoTypeDescriptor(cursor, &pd->type))
return PR_FALSE;
return PR_TRUE;
}
/* XXX when we lose the useless TDP wrapper struct, #define this to Do8 */
PRBool
DoTypeDescriptorPrefix(XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp)
{
return XPT_Do8(cursor, &tdp->flags);
}
PRBool
DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor *td)
{
if (!DoTypeDescriptorPrefix(cursor, &td->prefix)) {
goto error;
}
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
if (!XPT_Do16(cursor, &td->type.interface))
goto error;
} else {
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE) {
if (!XPT_Do8(cursor, &td->type.argnum))
goto error;
}
}
return PR_TRUE;
XPT_ERROR_HANDLE(td);
}
XPT_PUBLIC_API(XPTAnnotation *)
XPT_NewAnnotation(PRUint8 flags, XPTString *creator, XPTString *private_data)
{
XPTAnnotation *ann = XPT_NEWZAP(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(XPTCursor *cursor, XPTAnnotation **annp)
{
XPTMode mode = cursor->state->mode;
XPTAnnotation *ann;
if (mode == XPT_DECODE) {
ann = XPT_NEWZAP(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(cursor, &ann->creator) ||
!XPT_DoStringInline(cursor, &ann->private_data))
goto error_2;
}
/*
* If a subsequent Annotation fails, what to do?
* - free all annotations, return PR_FALSE? (current behaviour)
* - free failed annotation only, return PR_FALSE (caller can check for
* non-NULL *annp on PR_FALSE return to detect partial annotation
* decoding)?
*/
if (!XPT_ANN_IS_LAST(ann->flags) &&
!DoAnnotation(cursor, &ann->next))
goto error_2;
return PR_TRUE;
error_2:
if (ann && XPT_ANN_IS_PRIVATE(ann->flags)) {
XPT_FREEIF(ann->creator);
XPT_FREEIF(ann->private_data);
}
XPT_ERROR_HANDLE(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;
}
#if 0 /* need hashtables and stuff */
XPT_PUBLIC_API(XPTInterfaceDescriptor *)
XPT_GetDescriptorByIndex(XPTCursor *cursor, XPTHeader *header, PRUint16 index)
{
XPTInterfaceDescriptor *id = header->interface_directory + index;
if (id)
return id; /* XXX refcnt? */
/* XXX lazily load and allocate later, for now we always read them all
in */
return id;
}
#endif

Просмотреть файл

@ -117,12 +117,14 @@ XPT_NewHeader(PRUint16 num_interfaces)
header->major_version = XPT_MAJOR_VERSION;
header->minor_version = XPT_MINOR_VERSION;
header->num_interfaces = num_interfaces;
if (num_interfaces) {
header->interface_directory = XPT_CALLOC(num_interfaces *
sizeof(XPTInterfaceDirectoryEntry));
if (!header->interface_directory) {
XPT_DELETE(header);
return NULL;
}
}
header->data_pool = 0; /* XXX do we even need this struct any more? */
return header;
@ -172,7 +174,7 @@ XPT_DoHeader(XPTCursor *cursor, XPTHeader **headerp)
if (mode == XPT_DECODE)
XPT_DataOffset(cursor->state, &header->data_pool);
if (mode == XPT_DECODE) {
if (mode == XPT_DECODE && header->num_interfaces) {
header->interface_directory =
XPT_CALLOC(header->num_interfaces *
sizeof(XPTInterfaceDirectoryEntry));
@ -591,7 +593,7 @@ XPT_FillMethodDescriptor(XPTMethodDescriptor *meth, PRUint8 flags, char *name,
if (!name)
return PR_FALSE;
meth->num_args = num_args;
if (meth->num_args) {
if (num_args) {
meth->params = XPT_CALLOC(num_args * sizeof(XPTParamDescriptor));
if (!meth->params)
goto free_name;