widl: Merge marshall_arguments and unmarshall_arguments into one

function to remove the large amount of duplicated code.
This commit is contained in:
Robert Shearman 2006-02-07 12:32:24 +01:00 committed by Alexandre Julliard
parent f1bb0a474b
commit 55df46ab85
4 changed files with 92 additions and 215 deletions

View File

@ -199,7 +199,7 @@ static void write_function_stubs(type_t *iface)
type_offset_func = type_offset; type_offset_func = type_offset;
/* marshal arguments */ /* marshal arguments */
marshall_arguments(client, indent, func, &type_offset_func, PASS_IN); write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_MARSHAL);
/* send/receive message */ /* send/receive message */
/* print_client("NdrNsSendReceive(\n"); */ /* print_client("NdrNsSendReceive(\n"); */
@ -214,7 +214,8 @@ static void write_function_stubs(type_t *iface)
print_client("_StubMsg.BufferStart = (unsigned char *)_RpcMessage.Buffer;\n"); 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\n");
unmarshall_arguments(client, indent, func, &type_offset, PASS_OUT); /* unmarshall arguments */
write_remoting_arguments(client, indent, func, &type_offset, PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */ /* unmarshal return value */
if (!is_void(def->type, NULL)) if (!is_void(def->type, NULL))

View File

@ -204,7 +204,8 @@ static void write_function_stubs(type_t *iface)
/* make a copy so we don't increment the type offset twice */ /* make a copy so we don't increment the type offset twice */
type_offset_func = type_offset; type_offset_func = type_offset;
unmarshall_arguments(server, indent, func, &type_offset_func, PASS_IN); /* unmarshall arguments */
write_remoting_arguments(server, indent, func, &type_offset_func, PASS_IN, PHASE_UNMARSHAL);
} }
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
@ -298,7 +299,8 @@ static void write_function_stubs(type_t *iface)
fprintf(server, "\n"); fprintf(server, "\n");
} }
marshall_arguments(server, indent, func, &type_offset, PASS_OUT); /* marshall arguments */
write_remoting_arguments(server, indent, func, &type_offset, PASS_OUT, PHASE_MARSHAL);
/* marshall the return value */ /* marshall the return value */
if (!is_void(def->type, NULL)) if (!is_void(def->type, NULL))

View File

@ -1338,8 +1338,25 @@ unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment)
return get_required_buffer_size_type(var->type, var->ptr_level, var->array, var->name, alignment); return get_required_buffer_size_type(var->type, var->ptr_level, var->array, var->name, alignment);
} }
void marshall_arguments(FILE *file, int indent, const func_t *func, static inline const char *function_from_phase(enum remoting_phase phase)
unsigned int *type_offset, enum pass pass) {
switch (phase)
{
case PHASE_BUFFERSIZE:
return "BufferSize";
case PHASE_MARSHAL:
return "Marshall";
case PHASE_UNMARSHAL:
return "Unmarshall";
case PHASE_FREE:
return "Free";
}
return NULL;
}
void write_remoting_arguments(FILE *file, int indent, const func_t *func,
unsigned int *type_offset, enum pass pass,
enum remoting_phase phase)
{ {
unsigned int last_size = 0; unsigned int last_size = 0;
var_t *var; var_t *var;
@ -1375,12 +1392,12 @@ void marshall_arguments(FILE *file, int indent, const func_t *func,
{ {
if (var->array && var->array->is_const) if (var->array && var->array->is_const)
print_file(file, indent, print_file(file, indent,
"NdrNonConformantStringMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n", "NdrNonConformantString%s(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
var->name, *type_offset); function_from_phase(phase), var->name, *type_offset);
else else
print_file(file, indent, print_file(file, indent,
"NdrConformantStringMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n", "NdrConformantString%s(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
var->name, *type_offset); function_from_phase(phase), var->name, *type_offset);
last_size = 1; last_size = 1;
} }
else if (is_array_type(var->attrs, var->ptr_level, var->array)) else if (is_array_type(var->attrs, var->ptr_level, var->array))
@ -1399,35 +1416,45 @@ void marshall_arguments(FILE *file, int indent, const func_t *func,
array_type = "FixedArray"; array_type = "FixedArray";
else if (has_length && !has_size) else if (has_length && !has_size)
{ {
print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ if (phase == PHASE_MARSHAL)
print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); {
write_expr(file, length_is, 1); print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
fprintf(file, ";\n\n"); print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
write_expr(file, length_is, 1);
fprintf(file, ";\n\n");
}
array_type = "VaryingArray"; array_type = "VaryingArray";
} }
else if (!has_length && has_size) else if (!has_length && has_size)
{ {
print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); if (phase == PHASE_MARSHAL)
write_expr(file, size_is ? size_is : var->array, 1); {
fprintf(file, ";\n\n"); print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
write_expr(file, size_is ? size_is : var->array, 1);
fprintf(file, ";\n\n");
}
array_type = "ConformantArray"; array_type = "ConformantArray";
} }
else else
{ {
print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); if (phase == PHASE_MARSHAL)
write_expr(file, size_is ? size_is : var->array, 1); {
fprintf(file, ";\n"); print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ write_expr(file, size_is ? size_is : var->array, 1);
print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); fprintf(file, ";\n");
write_expr(file, length_is, 1); print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
fprintf(file, ";\n\n"); print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
write_expr(file, length_is, 1);
fprintf(file, ";\n\n");
}
array_type = "ConformantVaryingArray"; array_type = "ConformantVaryingArray";
} }
} }
print_file(file, indent, print_file(file, indent,
"Ndr%sMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n", "Ndr%s%s(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
array_type, var->name, *type_offset); array_type, function_from_phase(phase), var->name,
*type_offset);
last_size = 1; last_size = 1;
} }
else if (var->ptr_level == 0 && is_base_type(var->type->type)) else if (var->ptr_level == 0 && is_base_type(var->type->type))
@ -1474,18 +1501,34 @@ void marshall_arguments(FILE *file, int indent, const func_t *func,
continue; continue;
default: default:
error("marshall_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, var->type->type); error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, var->type->type);
size = 0; size = 0;
} }
if (alignment != 0) if (alignment != 0)
print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment); print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
print_file(file, indent, "*("); if (phase == PHASE_MARSHAL)
write_type(file, var->type, var, var->tname); {
fprintf(file, " *)_StubMsg.Buffer = "); print_file(file, indent, "*(");
write_name(file, var); write_type(file, var->type, var, var->tname);
fprintf(file, ";\n"); fprintf(file, " *)_StubMsg.Buffer = ");
write_name(file, var);
fprintf(file, ";\n");
}
else if (phase == PHASE_UNMARSHAL)
{
print_file(file, indent, "");
write_name(file, var);
fprintf(file, " = *(");
write_type(file, var->type, var, var->tname);
fprintf(file, " *)_StubMsg.Buffer;\n");
print_file(file, indent, "_StubMsg.Buffer += sizeof(");
write_type(file, var->type, var, var->tname);
fprintf(file, ");\n");
}
else
error("write_remoting_arguments: Unimplemented for base types for phase %d\n", phase);
print_file(file, indent, "_StubMsg.Buffer += sizeof("); print_file(file, indent, "_StubMsg.Buffer += sizeof(");
write_type(file, var->type, var, var->tname); write_type(file, var->type, var, var->tname);
fprintf(file, ");\n"); fprintf(file, ");\n");
@ -1512,197 +1555,21 @@ void marshall_arguments(FILE *file, int indent, const func_t *func,
ndrtype = "ComplexStruct"; ndrtype = "ComplexStruct";
break; break;
default: default:
error("marshall_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n", error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
var->name, var->type->type, var->ptr_level); var->name, var->type->type, var->ptr_level);
ndrtype = NULL; ndrtype = NULL;
} }
print_file(file, indent, print_file(file, indent,
"Ndr%sMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n", "Ndr%s%s(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
ndrtype, var->name, *type_offset); ndrtype, function_from_phase(phase), var->name, *type_offset);
last_size = 1; last_size = 1;
} }
else else
{ {
print_file(file, indent, print_file(file, indent,
"NdrPointerMarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n", "NdrPointer%s(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d]);\n",
var->name, *type_offset); function_from_phase(phase), var->name, *type_offset);
last_size = 1;
}
fprintf(file, "\n");
}
}
void unmarshall_arguments(FILE *file, int indent, const func_t *func,
unsigned int *type_offset, enum pass pass)
{
unsigned int last_size = 0;
var_t *var;
if (!func->args)
return;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
for (; var; *type_offset += get_size_typeformatstring_var(var), var = PREV_LINK(var))
{
int in_attr = is_attr(var->attrs, ATTR_IN);
int out_attr = is_attr(var->attrs, ATTR_OUT);
if (!in_attr && !out_attr)
in_attr = 1;
switch (pass)
{
case PASS_IN:
if (!in_attr)
continue;
break;
case PASS_OUT:
if (!out_attr)
continue;
break;
case PASS_RETURN:
break;
}
if (is_string_type(var->attrs, var->ptr_level, var->array))
{
if (var->array && var->array->is_const)
print_file(file, indent,
"NdrNonConformantStringUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
var->name, *type_offset);
else
print_file(file, indent,
"NdrConformantStringUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
var->name, *type_offset);
last_size = 1;
}
else if (is_array_type(var->attrs, var->ptr_level, var->array))
{
const expr_t *length_is = get_attrp(var->attrs, ATTR_LENGTHIS);
const expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS);
const char *array_type;
int has_length = length_is && (length_is->type != EXPR_VOID);
int has_size = (size_is && (size_is->type != EXPR_VOID)) || !var->array->is_const;
if (var->array && NEXT_LINK(var->array)) /* multi-dimensional array */
array_type = "ComplexArray";
else
{
if (!has_length && !has_size)
array_type = "FixedArray";
else if (has_length && !has_size)
array_type = "VaryingArray";
else if (!has_length && has_size)
array_type = "ConformantArray";
else
array_type = "ConformantVaryingArray";
}
print_file(file, indent,
"Ndr%sUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
array_type, var->name, *type_offset);
last_size = 1;
}
else if (var->ptr_level == 0 && is_base_type(var->type->type))
{
unsigned int size;
unsigned int alignment = 0;
switch (var->type->type)
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_USMALL:
size = 1;
alignment = 0;
break;
case RPC_FC_WCHAR:
case RPC_FC_USHORT:
case RPC_FC_SHORT:
size = 2;
if (last_size != 0 && last_size < 2)
alignment = (2 - last_size);
break;
case RPC_FC_ULONG:
case RPC_FC_LONG:
case RPC_FC_FLOAT:
case RPC_FC_ERROR_STATUS_T:
size = 4;
if (last_size != 0 && last_size < 4)
alignment = (4 - last_size);
break;
case RPC_FC_HYPER:
case RPC_FC_DOUBLE:
size = 8;
if (last_size != 0 && last_size < 4)
alignment = (4 - last_size);
break;
case RPC_FC_IGNORE:
case RPC_FC_BIND_PRIMITIVE:
/* no unmarshalling needed */
continue;
default:
error("unmarshall_arguments: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, var->type->type);
size = 0;
}
if (alignment != 0)
print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment);
print_file(file, indent, "");
write_name(file, var);
fprintf(file, " = *(");
write_type(file, var->type, var, var->tname);
fprintf(file, " *)_StubMsg.Buffer;\n");
print_file(file, indent, "_StubMsg.Buffer += sizeof(");
write_type(file, var->type, var, var->tname);
fprintf(file, ");\n");
last_size = size;
}
else if (var->ptr_level == 0)
{
const char *ndrtype;
switch (var->type->type)
{
case RPC_FC_STRUCT:
ndrtype = "SimpleStruct";
break;
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
ndrtype = "ConformantStruct";
break;
case RPC_FC_CVSTRUCT:
ndrtype = "ConformantVaryingStruct";
break;
case RPC_FC_BOGUS_STRUCT:
ndrtype = "ComplexStruct";
break;
default:
error("unmarshall_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
var->name, var->type->type, var->ptr_level);
ndrtype = NULL;
}
print_file(file, indent,
"Ndr%sUnmarshall(&_StubMsg, (unsigned char *)%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
ndrtype, var->name, *type_offset);
last_size = 1;
}
else
{
print_file(file, indent,
"NdrPointerUnmarshall(&_StubMsg, (unsigned char **)&%s, &__MIDL_TypeFormatString.Format[%d], 0);\n",
var->name, *type_offset);
last_size = 1; last_size = 1;
} }
fprintf(file, "\n"); fprintf(file, "\n");

View File

@ -27,11 +27,18 @@ enum pass
PASS_RETURN PASS_RETURN
}; };
enum remoting_phase
{
PHASE_BUFFERSIZE,
PHASE_MARSHAL,
PHASE_UNMARSHAL,
PHASE_FREE
};
void write_procformatstring(FILE *file, type_t *iface); void write_procformatstring(FILE *file, type_t *iface);
void write_typeformatstring(FILE *file, type_t *iface); void write_typeformatstring(FILE *file, type_t *iface);
unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment); unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment);
void marshall_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass); void write_remoting_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass, enum remoting_phase phase);
void unmarshall_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass);
size_t get_size_procformatstring_var(const var_t *var); size_t get_size_procformatstring_var(const var_t *var);
size_t get_size_typeformatstring_var(const var_t *var); size_t get_size_typeformatstring_var(const var_t *var);
int write_expr_eval_routines(FILE *file, const char *iface); int write_expr_eval_routines(FILE *file, const char *iface);