widl: Use the typegen function for marshalling/unmarshalling in proxies.

This commit is contained in:
Alexandre Julliard 2007-01-26 12:00:42 +01:00
parent 9f1e9ad326
commit 9e6acf818f
1 changed files with 44 additions and 490 deletions

View File

@ -161,34 +161,6 @@ int cant_be_null(const var_t *v)
return 1; /* Default is RPC_FC_RP. */
}
static int is_user_derived(const var_t *v)
{
const attr_list_t *attrs = v->attrs;
const type_t *type = v->type;
if (! attrs && type)
{
attrs = type->attrs;
type = type->ref;
}
while (attrs)
{
if (is_attr(attrs, ATTR_WIREMARSHAL))
return 1;
if (type)
{
attrs = type->attrs;
type = type->ref;
}
else
attrs = NULL;
}
return 0;
}
static void proxy_check_pointers( const var_list_t *args )
{
const var_t *arg;
@ -205,324 +177,6 @@ static void proxy_check_pointers( const var_list_t *args )
}
}
static void marshall_size_arg( const var_t *arg )
{
int index = 0;
const type_t *type = arg->type;
expr_t *expr;
expr = get_attrp( arg->attrs, ATTR_SIZEIS );
if (expr)
{
print_proxy( "_StubMsg.MaxCount = ", arg->name );
write_expr(proxy, expr, 0);
fprintf(proxy, ";\n\n");
print_proxy( "NdrConformantArrayBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
return;
}
if (is_user_derived(arg))
{
print_proxy("NdrUserMarshalBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name);
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index);
return;
}
if (is_string_type(arg->attrs, arg->ptr_level, arg->array))
{
print_proxy("NdrConformantStringBufferSize( &_StubMsg, (unsigned char*)s, ", arg->name);
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index);
}
switch( type->type )
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 1, arg->name );
break;
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
case RPC_FC_ENUM16:
print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 2, arg->name );
break;
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_ENUM32:
print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 4, arg->name );
break;
case RPC_FC_STRUCT:
print_proxy( "NdrSimpleStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index );
break;
case RPC_FC_CARRAY:
print_proxy( "NdrConformantArrayBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
break;
case RPC_FC_BOGUS_STRUCT:
print_proxy( "NdrComplexStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index );
break;
case RPC_FC_FP:
{
var_t temp;
memset( &temp, 0, sizeof temp );
temp.type = type->ref;
temp.name = arg->name; /* FIXME */
#if 0
print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name );
#endif
marshall_size_arg( &temp );
}
break;
case RPC_FC_IP:
print_proxy( "NdrPointerBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
break;
default:
print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type );
}
}
static void proxy_gen_marshall_size( const var_list_t *args )
{
const var_t *arg;
print_proxy( "_StubMsg.BufferLength = 0U;\n" );
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{
if (is_attr(arg->attrs, ATTR_IN))
{
marshall_size_arg( arg );
fprintf(proxy, "\n");
}
}
}
static void marshall_copy_arg( const var_t *arg )
{
int index = 0;
type_t *type = arg->type;
expr_t *expr;
expr = get_attrp( arg->attrs, ATTR_SIZEIS );
if (expr)
{
print_proxy( "_StubMsg.MaxCount = ", arg->name );
write_expr(proxy, expr, 0);
fprintf(proxy, ";\n\n");
print_proxy( "NdrConformantArrayMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
return;
}
if (is_user_derived(arg))
{
print_proxy("NdrUserMarshalMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name);
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index);
return;
}
if (is_string_type(arg->attrs, arg->ptr_level, arg->array))
{
print_proxy("NdrConformantStringMarshall( &_StubMsg, (unsigned char*)s, ", arg->name);
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index);
}
switch( type->type )
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
case RPC_FC_ENUM16:
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_ENUM32:
print_proxy( "*(");
write_type(proxy, arg->type, arg, arg->tname);
fprintf(proxy, " *)_StubMsg.Buffer = %s;\n", arg->name );
print_proxy("_StubMsg.Buffer += sizeof(");
write_type(proxy, arg->type, arg, arg->tname);
fprintf(proxy, ");\n");
break;
case RPC_FC_STRUCT:
/* FIXME: add the format string, and set the index below */
print_proxy( "NdrSimpleStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
break;
case RPC_FC_CARRAY:
break;
case RPC_FC_BOGUS_STRUCT:
print_proxy( "NdrComplexStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index );
break;
case RPC_FC_FP:
{
var_t temp;
memset( &temp, 0, sizeof temp );
temp.type = type->ref;
temp.name = arg->name; /* FIXME */
#if 0
print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name );
#endif
marshall_copy_arg( &temp );
}
break;
case RPC_FC_IP:
print_proxy( "NdrPointerMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index );
break;
default:
print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type );
}
}
static void gen_marshall_copydata( const var_list_t *args )
{
const var_t *arg;
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{
if (is_attr(arg->attrs, ATTR_IN))
{
marshall_copy_arg( arg );
fprintf(proxy, "\n");
}
}
}
static void gen_marshall( const var_list_t *args )
{
/* generated code to determine the size of the buffer required */
proxy_gen_marshall_size( args );
/* generated code to allocate the buffer */
print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" );
/* generated code to copy the args into the buffer */
gen_marshall_copydata( args );
print_proxy( "\n");
}
static void unmarshall_copy_arg( const var_t *arg )
{
int index = 0;
type_t *type = arg->type;
expr_t *expr;
expr = get_attrp( arg->attrs, ATTR_SIZEIS );
if (expr)
{
print_proxy( "NdrConformantArrayUnmarshall( &_StubMsg, (unsigned char**)&%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index );
return;
}
if (is_user_derived(arg))
{
print_proxy("NdrUserMarshalUnmarshall( &_StubMsg, (unsigned char**)&%s, ", arg->name);
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0 );\n", index);
return;
}
if (is_string_type(arg->attrs, arg->ptr_level, arg->array))
{
print_proxy("NdrConformantStringUnmarshall( &_StubMsg, (unsigned char**)&s, ", arg->name);
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0 );\n", index);
}
switch( type->type )
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
case RPC_FC_ENUM16:
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_ENUM32:
print_proxy( "%s = *(", arg->name );
write_type(proxy, arg->type, arg, arg->tname);
fprintf(proxy," *)_StubMsg.Buffer;\n");
print_proxy("_StubMsg.Buffer += sizeof(");
write_type(proxy, arg->type, arg, arg->tname);
fprintf(proxy, ");\n");
break;
case RPC_FC_STRUCT:
print_proxy( "NdrSimpleStructUnmarshall(&_StubMsg, (unsigned char**)%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index );
break;
case RPC_FC_CARRAY:
print_proxy( "NdrConformantArrayUnmarshall( &_StubMsg, (unsigned char**)&%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index );
break;
case RPC_FC_BOGUS_STRUCT:
print_proxy( "NdrComplexStructUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0 );\n", index );
break;
case RPC_FC_FP:
{
var_t temp;
memset( &temp, 0, sizeof temp );
temp.type = type->ref;
temp.name = arg->name; /* FIXME */
#if 1
print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name );
#endif
unmarshall_copy_arg( &temp );
}
break;
case RPC_FC_IP:
print_proxy( "NdrPointerUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name );
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index );
break;
default:
print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type );
}
}
static void gen_unmarshall( var_list_t *args )
{
const var_t *arg;
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{
if (is_attr(arg->attrs, ATTR_OUT))
{
unmarshall_copy_arg( arg );
fprintf(proxy, "\n");
}
}
}
static void free_variable( const var_t *arg )
{
var_t *constraint;
@ -587,10 +241,12 @@ static void proxy_free_variables( var_list_t *args )
}
}
static void gen_proxy(type_t *iface, const func_t *cur, int idx)
static void gen_proxy(type_t *iface, const func_t *cur, int idx,
unsigned int proc_offset, unsigned int *type_offset)
{
var_t *def = cur->def;
int has_ret = !is_void(def->type, def);
unsigned int offset;
indent = 0;
write_type(proxy, def->type, def, def->tname);
@ -624,32 +280,26 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx)
print_proxy( "{\n" );
indent++;
gen_marshall( cur->args );
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_IN, PHASE_BUFFERSIZE);
print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" );
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, type_offset, PASS_IN, PHASE_MARSHAL);
print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" );
fprintf(proxy, "\n");
print_proxy("if ((_Msg.DataRepresentation&0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n");
indent++;
print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[0]);\n" );
print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset );
indent--;
fprintf(proxy, "\n");
gen_unmarshall( cur->args );
if (has_ret) {
/*
* FIXME: We only need to round the buffer up if it could be unaligned...
* We should calculate how much buffer we used and output the following
* line only if necessary.
*/
print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n");
write_remoting_arguments(proxy, indent, cur, &offset, PASS_OUT, PHASE_UNMARSHAL);
print_proxy( "_RetVal = *(" );
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, " *)_StubMsg.Buffer;\n");
print_proxy("_StubMsg.Buffer += sizeof(");
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, ");\n");
}
if (has_ret)
print_phase_basetype(proxy, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal");
indent--;
print_proxy( "}\n");
@ -681,107 +331,13 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx)
print_proxy( "\n");
}
static void stub_write_locals( var_list_t *args )
{
int n = 0;
const var_t *arg;
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{
int outptr = is_attr(arg->attrs, ATTR_OUT)
&& ! is_attr(arg->attrs, ATTR_IN);
/* create a temporary variable to store the output */
if (outptr) {
var_t temp;
memset( &temp, 0, sizeof temp );
temp.ptr_level = arg->ptr_level - 1; /* dereference once */
print_proxy("");
write_type(proxy, arg->type, &temp, arg->tname);
fprintf(proxy, " _M%d;\n",n++);
}
print_proxy("");
write_type(proxy, arg->type, arg, arg->tname);
fprintf(proxy, " ");
write_name(proxy, arg);
fprintf(proxy, ";\n");
}
}
static void stub_unmarshall( const var_list_t *args )
{
int n = 0;
const var_t *arg;
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
{
if (is_attr(arg->attrs, ATTR_IN))
{
unmarshall_copy_arg( arg );
fprintf(proxy,"\n");
}
else if (is_attr(arg->attrs, ATTR_OUT)) {
type_t *type = arg->type;
switch( type->type )
{
case RPC_FC_STRUCT:
print_proxy("MIDL_memset(");
write_name(proxy, arg);
fprintf(proxy,", 0, sizeof(");
write_type(proxy, arg->type, arg, arg->tname);
fprintf(proxy,"));\n");
break;
default:
print_proxy("");
write_name(proxy, arg);
fprintf(proxy," = &_M%d;\n", n);
print_proxy("MIDL_memset(&_M%d, 0, sizeof _M%d);\n", n, n);
++n;
break;
}
}
}
}
static void stub_gen_marshall_size( const var_list_t *args )
{
const var_t *arg;
print_proxy( "_StubMsg.BufferLength = 0U;\n" );
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
if (is_attr(arg->attrs, ATTR_OUT))
marshall_size_arg( arg );
}
static void stub_gen_marshall_copydata( const var_list_t *args )
{
const var_t *arg;
if (!args) return;
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
if (is_attr(arg->attrs, ATTR_OUT))
marshall_copy_arg( arg );
}
static void stub_genmarshall( const var_list_t *args )
{
/* FIXME: size buffer */
stub_gen_marshall_size( args );
print_proxy("NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n");
stub_gen_marshall_copydata( args );
}
static void gen_stub(type_t *iface, const func_t *cur, const char *cas)
static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
unsigned int proc_offset, unsigned int *type_offset)
{
var_t *def = cur->def;
const var_t *arg;
int has_ret = !is_void(def->type, def);
unsigned int offset;
indent = 0;
print_proxy( "void __RPC_STUB %s_", iface->name);
@ -795,15 +351,9 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas)
indent--;
print_proxy( "{\n");
indent++;
/* local variables */
if (has_ret) {
print_proxy("");
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, " _RetVal;\n");
}
print_proxy("%s * _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name);
print_proxy("MIDL_STUB_MESSAGE _StubMsg;\n");
stub_write_locals( cur->args );
declare_stub_args( proxy, indent, cur );
fprintf(proxy, "\n");
/* FIXME: trace */
@ -816,13 +366,16 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas)
indent++;
print_proxy("if ((_Msg->DataRepresentation&0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n");
indent++;
print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[0]);\n" );
print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset );
indent--;
fprintf(proxy, "\n");
stub_unmarshall( cur->args );
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_IN, PHASE_UNMARSHAL);
fprintf(proxy, "\n");
assign_stub_out_args( proxy, indent, cur );
print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n");
fprintf(proxy, "\n");
print_proxy("");
@ -845,29 +398,26 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas)
print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n");
fprintf(proxy, "\n");
stub_genmarshall( cur->args );
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_OUT, PHASE_BUFFERSIZE);
print_proxy("NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n");
offset = *type_offset;
write_remoting_arguments(proxy, indent, cur, &offset, PASS_OUT, PHASE_MARSHAL);
fprintf(proxy, "\n");
if (has_ret) {
/*
* FIXME: We only need to round the buffer up if it could be unaligned...
* We should calculate how much buffer we used and output the following
* line only if necessary.
*/
print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n");
print_proxy( "*(" );
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, " *)_StubMsg.Buffer = _RetVal;\n");
print_proxy("_StubMsg.Buffer += sizeof(");
write_type(proxy, def->type, def, def->tname);
fprintf(proxy, ");\n");
}
if (has_ret)
print_phase_basetype(proxy, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal");
indent--;
print_proxy("}\n");
print_proxy("RpcFinally\n");
print_proxy("{\n");
offset = *type_offset;
write_remoting_arguments(proxy, indent+1, cur, &offset, PASS_OUT, PHASE_FREE);
print_proxy("}\n");
print_proxy("RpcEndFinally\n");
@ -918,10 +468,11 @@ static int write_stub_methods(type_t *iface)
return i;
}
static void write_proxy(type_t *iface)
static void write_proxy(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset)
{
int midx = -1, stubs;
const func_t *cur;
unsigned int offset;
if (!iface->funcs) return;
@ -946,8 +497,10 @@ static void write_proxy(type_t *iface)
break;
}
}
gen_proxy(iface, cur, idx);
gen_stub(iface, cur, cname);
offset = *type_offset;
gen_proxy(iface, cur, idx, *proc_offset, type_offset);
gen_stub(iface, cur, cname, *proc_offset, &offset);
*proc_offset += get_size_procformatstring_func( cur );
if (midx == -1) midx = idx;
else if (midx != idx) parser_error("method index mismatch in write_proxy");
midx++;
@ -1008,6 +561,7 @@ void write_proxies(ifref_list_t *ifaces)
ifref_t *cur;
char *file_id = proxy_token;
int c;
unsigned int proc_offset = 0, type_offset = 0;
if (!do_proxies) return;
if (do_everything && !ifaces) return;
@ -1018,7 +572,7 @@ void write_proxies(ifref_list_t *ifaces)
if (ifaces)
LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry )
if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs))
write_proxy(cur->iface);
write_proxy(cur->iface, &proc_offset, &type_offset);
write_stubdesc();