widl: Implement support for pointers to base types.

This commit is contained in:
Eric Kohl 2006-03-24 17:40:17 +01:00 committed by Alexandre Julliard
parent e97a1afbab
commit 1a5c6ef47d
3 changed files with 202 additions and 29 deletions

View File

@ -88,6 +88,29 @@ static void print_message_buffer_size(const func_t *func)
}
static int has_out_arg_or_return(const func_t *func)
{
var_t *var;
if (!is_void(func->def->type, NULL))
return 1;
if (!func->args)
return 0;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
if (is_attr(var->attrs, ATTR_OUT))
return 1;
var = PREV_LINK(var);
}
return 0;
}
static void write_function_stubs(type_t *iface)
{
const func_t *func = iface->funcs;
@ -212,13 +235,9 @@ static void write_function_stubs(type_t *iface)
indent--;
print_client("_StubMsg.BufferStart = (unsigned char *)_RpcMessage.Buffer;\n");
print_client("_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n\n");
print_client("_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n");
/* unmarshall arguments */
write_remoting_arguments(client, indent, func, &type_offset, PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */
if (!is_void(def->type, NULL))
if (has_out_arg_or_return(func))
{
fprintf(client, "\n");
@ -229,8 +248,16 @@ static void write_function_stubs(type_t *iface)
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset);
indent -= 2;
fprintf(client, "\n");
}
/* unmarshall arguments */
fprintf(client, "\n");
write_remoting_arguments(client, indent, func, &type_offset, PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */
if (!is_void(def->type, NULL))
{
fprintf(client, "\n");
print_client("_RetVal = *(");
write_type(client, def->type, def, def->tname);
fprintf(client, " *)_StubMsg.Buffer;\n");

View File

@ -88,6 +88,77 @@ static void write_parameters_init(const func_t *func)
}
static void declare_args(const func_t *func)
{
int in_attr, out_attr;
int i = 0;
var_t *var;
if (!func->args)
return;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
in_attr = is_attr(var->attrs, ATTR_IN);
out_attr = is_attr(var->attrs, ATTR_OUT);
if (!out_attr && !in_attr)
in_attr = 1;
if (!in_attr)
{
print_server("");
write_type(server, var->type, NULL, var->tname);
fprintf(server, " _W%u;\n", i++);
}
print_server("");
write_type(server, var->type, var, var->tname);
fprintf(server, " ");
write_name(server, var);
write_array(server, var->array, 0);
fprintf(server, ";\n");
var = PREV_LINK(var);
}
}
static void assign_out_args(const func_t *func)
{
int in_attr, out_attr;
int i = 0, sep = 0;
var_t *var;
if (!func->args)
return;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
in_attr = is_attr(var->attrs, ATTR_IN);
out_attr = is_attr(var->attrs, ATTR_OUT);
if (!out_attr && !in_attr)
in_attr = 1;
if (!in_attr)
{
print_server("");
write_name(server, var);
fprintf(server, " = &_W%u;\n", i++);
sep = 1;
}
var = PREV_LINK(var);
}
if (sep)
fprintf(server, "\n");
}
static void write_function_stubs(type_t *iface)
{
char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
@ -144,23 +215,8 @@ static void write_function_stubs(type_t *iface)
fprintf(server, " _RetVal;\n");
}
/* declare arguments */
if (func->args)
{
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
print_server("");
write_type(server, var->type, var, var->tname);
fprintf(server, " ");
write_name(server, var);
write_array(server, var->array, 0);
fprintf(server, ";\n");
var = PREV_LINK(var);
}
}
/* Declare arguments */
declare_args(func);
print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
print_server("RPC_STATUS _Status;\n");
@ -226,6 +282,8 @@ static void write_function_stubs(type_t *iface)
print_server("RpcEndExcept\n");
fprintf(server, "\n");
/* Assign 'out' arguments */
assign_out_args(func);
/* Call the real server function */
if (!is_void(def->type, NULL))

View File

@ -1181,6 +1181,8 @@ static size_t write_typeformatstring_var(FILE *file, int indent,
else if (ptr_level == 1 && !type_has_ref(type))
{
size_t start_offset = *typeformat_offset;
int in_attr = is_attr(var->attrs, ATTR_IN);
int out_attr = is_attr(var->attrs, ATTR_OUT);
int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (!pointer_type) pointer_type = RPC_FC_RP;
@ -1189,9 +1191,11 @@ static size_t write_typeformatstring_var(FILE *file, int indent,
{
#define CASE_BASETYPE(fctype) \
case RPC_##fctype: \
print_file(file, indent, "0x%x, 0x08, /* %s [simple_pointer] */\n", \
print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", \
pointer_type, \
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP")); \
(!in_attr && out_attr) ? 0x0C : 0x08, \
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), \
(!in_attr && out_attr) ? "[allocated_on_stack] " : ""); \
print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \
print_file(file, indent, "0x5c, /* FC_PAD */\n"); \
*typeformat_offset += 4; \
@ -1331,6 +1335,8 @@ static unsigned int get_required_buffer_size_type(
}
if (ptr_level == 0 && type_has_ref(type))
return get_required_buffer_size_type(type->ref, 0 /* FIXME */, array, name, alignment);
if (ptr_level == 1)
return 25; /* FIXME: Only 'in' pointers need this */
return 0;
}
@ -1557,9 +1563,91 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
}
else
{
print_file(file, indent,
"NdrPointer%s(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
function_from_phase(phase), var->name, *type_offset);
int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (!pointer_type)
pointer_type = RPC_FC_RP;
if (pointer_type == RPC_FC_RP)
{
unsigned int size;
switch (var->type->type)
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_USMALL:
size = 1;
break;
case RPC_FC_WCHAR:
case RPC_FC_USHORT:
case RPC_FC_SHORT:
size = 2;
break;
case RPC_FC_ULONG:
case RPC_FC_LONG:
case RPC_FC_FLOAT:
case RPC_FC_ERROR_STATUS_T:
size = 4;
break;
case RPC_FC_HYPER:
case RPC_FC_DOUBLE:
size = 8;
break;
case RPC_FC_IGNORE:
case RPC_FC_BIND_PRIMITIVE:
/* no marshalling needed */
continue;
default:
error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, var->type->type);
size = 0;
}
print_file(file, indent,
"_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n",
size - 1, size - 1);
if (phase == PHASE_MARSHAL)
{
print_file(file, indent, "*(");
write_type(file, var->type, NULL, var->tname);
fprintf(file, " *)_StubMsg.Buffer = *");
write_name(file, var);
fprintf(file, ";\n");
}
else if (phase == PHASE_UNMARSHAL)
{
print_file(file, indent, (pass == PASS_IN) ? "" : "*");
write_name(file, var);
fprintf(file, (pass == PASS_IN) ? " = (" : " = *(");
write_type(file, var->type, NULL, var->tname);
fprintf(file, " *)_StubMsg.Buffer;\n");
}
print_file(file, indent, "_StubMsg.Buffer += sizeof(");
write_type(file, var->type, NULL, var->tname);
fprintf(file, ");\n");
}
else if (pointer_type == RPC_FC_UP)
{
print_file(file, indent, "NdrPointer%s(\n", function_from_phase(phase));
indent++;
print_file(file, indent, "(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
print_file(file, indent, "(unsigned char *)%s,\n", var->name);
print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
*type_offset, (phase == PHASE_MARSHAL) ? ");" : ",");
if (phase == PHASE_UNMARSHAL)
print_file(file, indent, "(unsigned char *)0);\n");
indent--;
}
else if (pointer_type == RPC_FC_FP)
{
error("write_remoting_arguments: Unimplemented for full pointers to base types\n");
}
}
fprintf(file, "\n");
}