- Changed the interface for getting the interface_is argnum.

- Merged the typelib types for array and array_with_length.
- Added typelib types for string_with_size and wstring_with_size
This commit is contained in:
jband%netscape.com 1999-09-20 02:50:28 +00:00
Родитель ca2ce65b99
Коммит 04c77e4064
9 изменённых файлов: 316 добавлений и 148 удалений

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

@ -284,7 +284,16 @@ nsProxyObject::AutoProxyParameterList(PRUint32 methodIndex, nsXPTMethodInfo *met
nsIID* iid = nsnull;
if(type.TagPart() == nsXPTType::T_INTERFACE_IS)
{
uint8 arg_num = paramInfo.GetInterfaceIsArgNumber();
uint8 arg_num;
rv = interfaceInfo->GetInterfaceIsArgNumberForParam(methodIndex, &paramInfo, &arg_num);
if(NS_FAILED(rv))
{
// This is really bad that we are here.
rv = NS_ERROR_PROXY_INVALID_IN_PARAMETER;
continue;
}
const nsXPTParamInfo& param = methodInfo->GetParam(arg_num);
const nsXPTType& currentType = param.GetType();

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

@ -80,6 +80,11 @@ public:
const nsXPTParamInfo* param,
uint16 dimension,
uint8* argnum) = 0;
NS_IMETHOD GetInterfaceIsArgNumberForParam(uint16 methodIndex,
const nsXPTParamInfo* param,
uint8* argnum) = 0;
};
#endif /* nsIInterfaceInfo_h___ */

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

@ -103,8 +103,14 @@ public:
TagPart() == T_INTERFACE_IS);}
PRBool IsArray() const
{return (PRBool) (TagPart() == T_ARRAY ||
TagPart() == T_ARRAY_WITH_LENGTH);}
{return (PRBool) TagPart() == T_ARRAY;}
// 'Dependent' means that params of this type are dependent upon other
// params. e.g. an T_INTERFACE_IS is dependent upon some other param at
// runtime to say what the interface type of this param really is.
PRBool IsDependent() const
{return (PRBool) (TagPart() == T_INTERFACE_IS ||
TagPart() == TD_ARRAY);}
uint8 TagPart() const
{return (uint8) (flags & XPT_TDP_TAGMASK);}
@ -132,7 +138,8 @@ public:
T_INTERFACE = TD_INTERFACE_TYPE ,
T_INTERFACE_IS = TD_INTERFACE_IS_TYPE,
T_ARRAY = TD_ARRAY ,
T_ARRAY_WITH_LENGTH = TD_ARRAY_WITH_LENGTH
T_PSTRING_SIZE_IS = TD_PSTRING_SIZE_IS ,
T_PWSTRING_SIZE_IS = TD_PWSTRING_SIZE_IS
};
// NO DATA - this a flyweight wrapper
};
@ -151,13 +158,7 @@ public:
PRBool IsShared() const {return (PRBool) (XPT_PD_IS_SHARED(flags));}
const nsXPTType GetType() const {return type.prefix;}
uint8 GetInterfaceIsArgNumber() const
{
NS_PRECONDITION(GetType().TagPart() == nsXPTType::T_INTERFACE_IS,"not an interface_is");
return type.argnum;
}
// NOTE: gettting the interface or interface iid is done via methods on
// nsIInterfaceInfo
// NOTE: other activities on types are done via methods on nsIInterfaceInfo
private:
nsXPTParamInfo(); // no implementation

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

@ -250,6 +250,28 @@ nsInterfaceInfo::GetIIDForParam(uint16 methodIndex,
return paramRecord->GetIID(iid);
}
// this is a private helper
NS_IMETHODIMP
nsInterfaceInfo::GetTypeInArray(const nsXPTParamInfo* param,
uint16 dimension,
const XPTTypeDescriptor** type)
{
const XPTTypeDescriptor *td = &param->type;
const XPTTypeDescriptor *additional_types =
this->mInterfaceRecord->interfaceDescriptor->additional_types;
for (uint16 i = 0; i < dimension; i++) {
if (XPT_TDP_TAG(td->prefix) != TD_ARRAY) {
NS_ASSERTION(0, "bad dimension");
return NS_ERROR_INVALID_ARG;
}
td = &additional_types[td->type.additional_type];
}
*type = td;
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceInfo::GetTypeForParam(uint16 methodIndex,
const nsXPTParamInfo* param,
@ -267,18 +289,15 @@ nsInterfaceInfo::GetTypeForParam(uint16 methodIndex,
return NS_ERROR_INVALID_ARG;
}
const XPTTypeDescriptor *td = &param->type;
const XPTTypeDescriptor *additional_types =
this->mInterfaceRecord->interfaceDescriptor->additional_types;
const XPTTypeDescriptor *td;
for(uint16 i = 0; i < dimension; i++) {
uint8 tag = XPT_TDP_TAG(td->prefix);
if (tag != TD_ARRAY && tag != TD_ARRAY_WITH_LENGTH) {
NS_ASSERTION(0, "bad dimension");
return NS_ERROR_INVALID_ARG;
}
td = &additional_types[td->type.additional_type];
if (dimension) {
nsresult rv = GetTypeInArray(param, dimension, &td);
if (NS_FAILED(rv))
return rv;
}
else
td = &param->type;
*type = nsXPTType(td->prefix);
return NS_OK;
@ -292,7 +311,6 @@ nsInterfaceInfo::GetSizeIsArgNumberForParam(uint16 methodIndex,
{
NS_PRECONDITION(param, "bad pointer");
NS_PRECONDITION(argnum, "bad pointer");
NS_PRECONDITION(dimension > 0, "arrays have no size_is for dimension 0");
if (methodIndex < mMethodBaseIndex)
return mParent->GetSizeIsArgNumberForParam(methodIndex, param,
@ -303,23 +321,25 @@ nsInterfaceInfo::GetSizeIsArgNumberForParam(uint16 methodIndex,
return NS_ERROR_INVALID_ARG;
}
const XPTTypeDescriptor *td = &param->type;
const XPTTypeDescriptor *additional_types =
this->mInterfaceRecord->interfaceDescriptor->additional_types;
const XPTTypeDescriptor *td;
uint16 depth = dimension;
while (1)
{
uint8 tag = XPT_TDP_TAG(td->prefix);
if (tag != TD_ARRAY && tag != TD_ARRAY_WITH_LENGTH) {
NS_ASSERTION(0, "bad dimension");
return NS_ERROR_INVALID_ARG;
if (dimension) {
nsresult rv = GetTypeInArray(param, dimension, &td);
if (NS_FAILED(rv))
return rv;
}
else
td = &param->type;
if (0 == --depth)
// verify that this is a type that has size_is
switch (XPT_TDP_TAG(td->prefix)) {
case TD_ARRAY:
case TD_PSTRING_SIZE_IS:
case TD_PWSTRING_SIZE_IS:
break;
td = &additional_types[td->type.additional_type];
default:
NS_ASSERTION(0, "not a size_is");
return NS_ERROR_INVALID_ARG;
}
*argnum = td->argnum;
@ -334,7 +354,6 @@ nsInterfaceInfo::GetLengthIsArgNumberForParam(uint16 methodIndex,
{
NS_PRECONDITION(param, "bad pointer");
NS_PRECONDITION(argnum, "bad pointer");
NS_PRECONDITION(dimension > 0, "arrays have no length_is for dimension 0");
if (methodIndex < mMethodBaseIndex)
return mParent->GetLengthIsArgNumberForParam(methodIndex, param,
@ -345,34 +364,65 @@ nsInterfaceInfo::GetLengthIsArgNumberForParam(uint16 methodIndex,
return NS_ERROR_INVALID_ARG;
}
const XPTTypeDescriptor *td = &param->type;
const XPTTypeDescriptor *additional_types =
this->mInterfaceRecord->interfaceDescriptor->additional_types;
const XPTTypeDescriptor *td;
uint16 depth = dimension;
while (1)
{
uint8 tag = XPT_TDP_TAG(td->prefix);
if (tag != TD_ARRAY && tag != TD_ARRAY_WITH_LENGTH) {
NS_ASSERTION(0, "bad dimension");
return NS_ERROR_INVALID_ARG;
if (dimension) {
nsresult rv = GetTypeInArray(param, dimension, &td);
if (NS_FAILED(rv)) {
return rv;
}
}
else
td = &param->type;
if (0 == --depth) {
if (tag != TD_ARRAY_WITH_LENGTH) {
NS_ASSERTION(0, "asked for length_is for dimension without one");
return NS_ERROR_INVALID_ARG;
}
// verify that this is a type that has length_is
switch (XPT_TDP_TAG(td->prefix)) {
case TD_ARRAY:
case TD_PSTRING_SIZE_IS:
case TD_PWSTRING_SIZE_IS:
break;
}
td = &additional_types[td->type.additional_type];
default:
NS_ASSERTION(0, "not a length_is");
return NS_ERROR_INVALID_ARG;
}
*argnum = td->argnum2;
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceInfo::GetInterfaceIsArgNumberForParam(uint16 methodIndex,
const nsXPTParamInfo* param,
uint8* argnum)
{
NS_PRECONDITION(param, "bad pointer");
NS_PRECONDITION(argnum, "bad pointer");
if (methodIndex < mMethodBaseIndex)
return mParent->GetInterfaceIsArgNumberForParam(methodIndex, param,
argnum);
if (methodIndex >= mMethodBaseIndex + mMethodCount) {
NS_ASSERTION(0, "bad index");
return NS_ERROR_INVALID_ARG;
}
const XPTTypeDescriptor *td = &param->type;
while (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
td = &this->mInterfaceRecord->interfaceDescriptor->
additional_types[td->type.additional_type];
}
if (XPT_TDP_TAG(td->prefix) != TD_INTERFACE_IS_TYPE) {
NS_ASSERTION(0, "not an iid_is");
return NS_ERROR_INVALID_ARG;
}
*argnum = td->argnum;
return NS_OK;
}
#ifdef DEBUG
#include <stdio.h>

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

@ -76,6 +76,10 @@ class nsInterfaceInfo : public nsIInterfaceInfo
const nsXPTParamInfo* param,
uint16 dimension,
uint8* argnum);
NS_IMETHOD GetInterfaceIsArgNumberForParam(uint16 methodIndex,
const nsXPTParamInfo* param,
uint8* argnum);
public:
virtual ~nsInterfaceInfo();
@ -83,6 +87,10 @@ public:
void NS_EXPORT print(FILE *fd);
#endif
private:
NS_IMETHOD GetTypeInArray(const nsXPTParamInfo* param,
uint16 dimension,
const XPTTypeDescriptor** type);
private:
friend class nsInterfaceRecord;

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

@ -568,6 +568,8 @@ find_arg_with_name(TreeState *state, const char *name, int16 *argnum)
IDL_PARAM_DCL(IDL_LIST(params).data).simple_declarator).str;
if (!strcmp(cur_name, name)) {
/* XXX ought to verify that this is the right type here */
/* XXX for iid_is this must be an iid */
/* XXX for size_is and length_is this must be a uint32 */
*argnum = count;
return TRUE;
}
@ -575,10 +577,55 @@ find_arg_with_name(TreeState *state, const char *name, int16 *argnum)
return FALSE;
}
/* return value is for success or failure */
static gboolean
get_size_and_length(TreeState *state, IDL_tree type,
int16 *size_is_argnum, int16 *length_is_argnum,
gboolean *has_size_is, gboolean *has_length_is)
{
*has_size_is = FALSE;
*has_length_is = FALSE;
if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) {
IDL_tree sd = IDL_PARAM_DCL(state->tree).simple_declarator;
const char *size_is;
const char *length_is;
/* only if size_is is found does any of this matter */
size_is = IDL_tree_property_get(sd, "size_is");
if (!size_is)
return TRUE;
if (!find_arg_with_name(state, size_is, size_is_argnum)) {
IDL_tree_error(type, "can't find matching argument for "
"[size_is(%s)]\n", size_is);
return FALSE;
}
*has_size_is = TRUE;
/* length_is is optional */
length_is = IDL_tree_property_get(sd, "length_is");
if (length_is) {
*has_length_is = TRUE;
if (!find_arg_with_name(state, length_is, length_is_argnum)) {
IDL_tree_error(type, "can't find matching argument for "
"[length_is(%s)]\n", length_is);
return FALSE;
}
}
}
return TRUE;
}
static gboolean
fill_td_from_type(TreeState *state, XPTTypeDescriptor *td, IDL_tree type)
{
IDL_tree up;
int16 size_is_argnum;
int16 length_is_argnum;
gboolean has_size_is;
gboolean has_length_is;
gboolean is_array = FALSE;
if (type) {
@ -587,40 +634,29 @@ fill_td_from_type(TreeState *state, XPTTypeDescriptor *td, IDL_tree type)
if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) {
IDL_tree sd = IDL_PARAM_DCL(state->tree).simple_declarator;
if(IDL_tree_property_get(sd, "array")) {
const char *size_is;
const char *length_is;
int16 size_is_argnum;
int16 length_is_argnum;
is_array = TRUE;
/* size_is is required! */
size_is = IDL_tree_property_get(sd, "size_is");
if (!size_is) {
if (!get_size_and_length(state, type,
&size_is_argnum, &length_is_argnum,
&has_size_is, &has_length_is)) {
/* error was reported by helper function */
return FALSE;
}
if (!has_size_is) {
IDL_tree_error(type, "[array] requires [size_is()]\n");
return FALSE;
}
if (!find_arg_with_name(state, size_is, &size_is_argnum)) {
IDL_tree_error(type, "can't find matching argument for "
"[size_is(%s)]\n", size_is);
return FALSE;
}
/* length_is is optional */
length_is = IDL_tree_property_get(sd, "length_is");
if (length_is &&
!find_arg_with_name(state, length_is, &length_is_argnum)) {
IDL_tree_error(type, "can't find matching argument for "
"[length_is(%s)]\n", length_is);
return FALSE;
}
td->argnum = size_is_argnum;
if (length_is) {
td->prefix.flags = TD_ARRAY_WITH_LENGTH | XPT_TDP_POINTER;
td->argnum2 = length_is_argnum;
} else {
td->prefix.flags = TD_ARRAY | XPT_TDP_POINTER;
}
td->argnum = size_is_argnum;
if (has_length_is)
td->argnum2 = length_is_argnum;
else
td->argnum2 = size_is_argnum;
/*
* XXX - NOTE - this will be broken for multidimensional
@ -664,11 +700,48 @@ handle_typedef:
td->prefix.flags = TD_WCHAR;
break;
case IDLN_TYPE_STRING:
/* XXXshaver string-type? */
if (is_array) {
td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER;
} else {
if (!get_size_and_length(state, type,
&size_is_argnum, &length_is_argnum,
&has_size_is, &has_length_is)) {
/* error was reported by helper function */
return FALSE;
}
if (has_size_is) {
td->prefix.flags = TD_PSTRING_SIZE_IS | XPT_TDP_POINTER;
td->argnum = size_is_argnum;
if (has_length_is)
td->argnum2 = length_is_argnum;
else
td->argnum2 = size_is_argnum;
} else {
td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER;
}
}
break;
case IDLN_TYPE_WIDE_STRING:
if (is_array) {
td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER;
} else {
if (!get_size_and_length(state, type,
&size_is_argnum, &length_is_argnum,
&has_size_is, &has_length_is)) {
/* error was reported by helper function */
return FALSE;
}
if (has_size_is) {
td->prefix.flags = TD_PWSTRING_SIZE_IS | XPT_TDP_POINTER;
td->argnum = size_is_argnum;
if (has_length_is)
td->argnum2 = length_is_argnum;
else
td->argnum2 = size_is_argnum;
} else {
td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER;
}
}
break;
case IDLN_TYPE_BOOLEAN:
td->prefix.flags = TD_BOOL;

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

@ -304,23 +304,20 @@ enum XPTTypeDescriptorTags {
TD_INTERFACE_TYPE = 18,
TD_INTERFACE_IS_TYPE = 19,
TD_ARRAY = 20,
TD_ARRAY_WITH_LENGTH = 21
TD_PSTRING_SIZE_IS = 21,
TD_PWSTRING_SIZE_IS = 22
};
struct XPTTypeDescriptor {
XPTTypeDescriptorPrefix prefix;
PRUint8 argnum;
PRUint8 argnum2;
PRUint8 argnum; /* used for iid_is and size_is */
PRUint8 argnum2; /* used for length_is */
union {
PRUint16 interface;
PRUint16 additional_type;
PRUint16 interface; /* used for TD_INTERFACE_TYPE */
PRUint16 additional_type; /* used for TD_ARRAY */
} type;
};
/* this is bogus
#define XPT_TYPEDESCRIPTOR_SIZE (1 + 2)
*/
#define XPT_COPY_TYPE(to, from) \
(to).prefix.flags = (from).prefix.flags; \
(to).argnum = (from).argnum; \

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

@ -419,16 +419,28 @@ XPT_PUBLIC_API(PRUint32)
XPT_SizeOfTypeDescriptor(XPTTypeDescriptor *td, XPTInterfaceDescriptor *id)
{
PRUint32 size = 1; /* prefix */
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE)
switch (XPT_TDP_TAG(td->prefix)) {
case TD_INTERFACE_TYPE:
size += 2; /* interface_index */
else if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE)
size += 1; /* arg_num */
else if (XPT_TDP_TAG(td->prefix) == TD_ARRAY)
size += 1 + XPT_SizeOfTypeDescriptor(
&id->additional_types[td->type.additional_type], id);
else if (XPT_TDP_TAG(td->prefix) == TD_ARRAY_WITH_LENGTH)
break;
case TD_INTERFACE_IS_TYPE:
size += 1; /* argnum */
break;
case TD_ARRAY:
size += 2 + XPT_SizeOfTypeDescriptor(
&id->additional_types[td->type.additional_type], id);
break;
case TD_PSTRING_SIZE_IS:
size += 2; /* argnum + argnum2 */
break;
case TD_PWSTRING_SIZE_IS:
size += 2; /* argnum + argnum2 */
break;
default:
/* nothing special */
break;
}
return size;
}
@ -736,21 +748,18 @@ DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor *td,
goto error;
}
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
switch (XPT_TDP_TAG(td->prefix)) {
case TD_INTERFACE_TYPE:
if (!XPT_Do16(cursor, &td->type.interface))
goto error;
}
else if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_IS_TYPE) {
break;
case TD_INTERFACE_IS_TYPE:
if (!XPT_Do8(cursor, &td->argnum))
goto error;
}
else if (XPT_TDP_TAG(td->prefix) == TD_ARRAY ||
XPT_TDP_TAG(td->prefix) == TD_ARRAY_WITH_LENGTH) {
if (!XPT_Do8(cursor, &td->argnum))
goto error;
if (XPT_TDP_TAG(td->prefix) == TD_ARRAY_WITH_LENGTH)
if (!XPT_Do8(cursor, &td->argnum2))
break;
case TD_ARRAY:
if (!XPT_Do8(cursor, &td->argnum) ||
!XPT_Do8(cursor, &td->argnum2))
goto error;
if (cursor->state->mode == XPT_DECODE) {
@ -758,12 +767,23 @@ DoTypeDescriptor(XPTCursor *cursor, XPTTypeDescriptor *td,
goto error;
td->type.additional_type = id->num_additional_types - 1;
}
if (!DoTypeDescriptor(cursor,
&id->additional_types[td->type.additional_type],
id))
goto error;
}
break;
case TD_PSTRING_SIZE_IS:
case TD_PWSTRING_SIZE_IS:
if (!XPT_Do8(cursor, &td->argnum) ||
!XPT_Do8(cursor, &td->argnum2))
goto error;
break;
default:
/* nothing special */
break;
}
return PR_TRUE;
XPT_ERROR_HANDLE(td);

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

@ -35,25 +35,29 @@
#define BASE_INDENT 3
static char *type_array[18] = {"int8", "int16", "int32", "int64",
static char *type_array[23] =
{"int8", "int16", "int32", "int64",
"uint8", "uint16", "uint32", "uint64",
"float", "double", "boolean", "char",
"wchar_t", "void", "reserved", "reserved",
"reserved", "reserved"};
"reserved", "reserved", "reserved", "reserved",
"reserved", "reserved", "reserved"};
static char *ptype_array[20] = {"int8 *", "int16 *", "int32 *", "int64 *",
static char *ptype_array[23] =
{"int8 *", "int16 *", "int32 *", "int64 *",
"uint8 *", "uint16 *", "uint32 *", "uint64 *",
"float *", "double *", "boolean *", "char *",
"wchar_t *", "void *", "nsIID *", "bstr",
"string", "wstring", "Interface *",
"InterfaceIs *"};
"string", "wstring", "Interface *", "InterfaceIs *",
"array", "string_s", "wstring_s"};
static char *rtype_array[20] = {"int8 &", "int16 &", "int32 &", "int64 &",
static char *rtype_array[23] =
{"int8 &", "int16 &", "int32 &", "int64 &",
"uint8 &", "uint16 &", "uint32 &", "uint64 &",
"float &", "double &", "boolean &", "char &",
"wchar_t &", "void &", "nsIID &", "bstr",
"string", "wstring", "Interface &",
"InterfaceIs &"};
"string &", "wstring &", "Interface &", "InterfaceIs &",
"array &", "string_s &", "wstring_s &"};
PRBool param_problems = PR_FALSE;
@ -639,7 +643,7 @@ XPT_GetStringForType(XPTHeader *header, XPTTypeDescriptor *td,
int tag = XPT_TDP_TAG(td->prefix);
if (tag == TD_ARRAY || tag == TD_ARRAY_WITH_LENGTH) {
if (tag == TD_ARRAY) {
isArray = PR_TRUE;
td = &id->additional_types[td->type.additional_type];
tag = XPT_TDP_TAG(td->prefix);
@ -746,11 +750,6 @@ XPT_DumpTypeDescriptor(XPTTypeDescriptor *td,
int new_indent;
if (XPT_TDP_TAG(td->prefix) == TD_ARRAY) {
fprintf(stdout, "%*sArray (size in arg %d) of...\n",
indent, " ", td->argnum);
td = &id->additional_types[td->type.additional_type];
indent += BASE_INDENT;
} else if (XPT_TDP_TAG(td->prefix) == TD_ARRAY_WITH_LENGTH) {
fprintf(stdout, "%*sArray (size in arg %d and length in arg %d) of...\n",
indent, " ", td->argnum, td->argnum2);
td = &id->additional_types[td->type.additional_type];
@ -780,6 +779,12 @@ XPT_DumpTypeDescriptor(XPTTypeDescriptor *td,
fprintf(stdout, "%*sTag: %d\n", indent, " ",
XPT_TDP_TAG(td->prefix));
if (XPT_TDP_TAG(td->prefix) == TD_PSTRING_SIZE_IS ||
XPT_TDP_TAG(td->prefix) == TD_PWSTRING_SIZE_IS) {
fprintf(stdout, "%*s - size in arg %d and length in arg %d\n",
indent, " ", td->argnum, td->argnum2);
}
if (XPT_TDP_TAG(td->prefix) == TD_INTERFACE_TYPE) {
fprintf(stdout, "%*sInterfaceTypeDescriptor:\n", indent, " ");
fprintf(stdout, "%*sIndex of IDE: %d\n", new_indent, " ",