Robert Shearman : widl: Arrays.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jan 24 06:45:02 CST 2006


Module: wine
Branch: refs/heads/master
Commit: d07589e32f767f3904b129aedc24ba653266ca5e
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=d07589e32f767f3904b129aedc24ba653266ca5e

Author: Robert Shearman <rob at codeweavers.com>
Date:   Tue Jan 24 11:07:13 2006 +0100

widl: Arrays.
Write out type format strings for arrays, except for the missing
generic functionality of conformance and variance descriptors.

---

 tools/widl/typegen.c |  209 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 206 insertions(+), 3 deletions(-)

diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 0c8a3b0..f334d73 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -31,6 +31,7 @@
 #include <assert.h>
 #include <ctype.h>
 #include <signal.h>
+#include <limits.h>
 
 #include "widl.h"
 #include "utils.h"
@@ -211,6 +212,75 @@ void write_procformatstring(FILE *file, 
     print_file(file, indent, "\n");
 }
 
+static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array);
+
+static size_t fields_memsize(const var_t *v)
+{
+    size_t size = 0;
+    const var_t *first = v;
+    if (!v) return 0;
+    while (NEXT_LINK(v)) v = NEXT_LINK(v);
+    while (v) {
+        size += type_memsize(v->type, v->ptr_level, v->array);
+        if (v == first) break;
+        v = PREV_LINK(v);
+    }
+    return size;
+}
+
+static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array)
+{
+    size_t size = 0;
+
+    if (ptr_level)
+        return sizeof(void *);
+
+    switch (t->type)
+    {
+    case RPC_FC_BYTE:
+    case RPC_FC_CHAR:
+    case RPC_FC_USMALL:
+    case RPC_FC_SMALL:
+        size = 1;
+        break;
+    case RPC_FC_WCHAR:
+    case RPC_FC_USHORT:
+    case RPC_FC_SHORT:
+    case RPC_FC_ENUM16:
+        size = 2;
+        break;
+    case RPC_FC_ULONG:
+    case RPC_FC_LONG:
+    case RPC_FC_ERROR_STATUS_T:
+    case RPC_FC_ENUM32:
+    case RPC_FC_FLOAT:
+        size = 4;
+        break;
+    case RPC_FC_HYPER:
+    case RPC_FC_DOUBLE:
+        size = 8;
+        break;
+    case RPC_FC_STRUCT:
+    case RPC_FC_CVSTRUCT:
+    case RPC_FC_CPSTRUCT:
+    case RPC_FC_CSTRUCT:
+    case RPC_FC_PSTRUCT:
+    case RPC_FC_BOGUS_STRUCT:
+    case RPC_FC_ENCAPSULATED_UNION:
+    case RPC_FC_NON_ENCAPSULATED_UNION:
+        size = fields_memsize(t->fields);
+        break;
+    default:
+        error("type_memsize: Unknown type %d", t->type);
+        size = 0;
+    }
+
+    if (array && array->is_const)
+        size *= array->cval;
+
+    return size;
+}
+
 static size_t write_string_tfs(FILE *file, const attr_t *attr,
                                const type_t *type, const expr_t *array,
                                const char *name)
@@ -219,12 +289,145 @@ static size_t write_string_tfs(FILE *fil
     return 0;
 }
 
-static size_t write_array_tfs(FILE *file, const attr_t *attr,
+static size_t write_array_tfs(FILE *file, const attr_t *attrs,
                               const type_t *type, const expr_t *array,
                               const char *name)
 {
-    error("write_array_tfs: Unimplemented. name: %s\n", name);
-    return 0;
+    const expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS);
+    const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
+    int has_length = length_is && (length_is->type != EXPR_VOID);
+    int has_size = size_is && (size_is->type != EXPR_VOID) && !array->is_const;
+
+    /* FIXME: need to analyse type for pointers */
+
+    if (NEXT_LINK(array)) /* multi-dimensional array */
+    {
+        error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name);
+        return 0;
+    }
+    else
+    {
+        if (!has_length && !has_size)
+        {
+            /* fixed array */
+            size_t typestring_size;
+            size_t size = type_memsize(type, 0, array);
+            if (size < USHRT_MAX)
+            {
+                print_file(file, 2, "0x%x, /* FC_SMFARRAY */\n", RPC_FC_SMFARRAY);
+                /* alignment */
+                print_file(file, 2, "0x%x, /* 0 */\n", 0);
+                /* size */
+                print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", size, size);
+                typestring_size = 4;
+            }
+            else
+            {
+                print_file(file, 2, "0x%x, /* FC_LGFARRAY */\n", RPC_FC_LGFARRAY);
+                /* alignment */
+                print_file(file, 2, "0x%x, /* 0 */\n", 0);
+                /* size */
+                print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", size, size);
+                typestring_size = 6;
+            }
+
+            /* FIXME: write out pointer descriptor if necessary */
+
+            print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+            print_file(file, 2, "FC_END,\n");
+            typestring_size += 2;
+
+            return typestring_size;
+        }
+        else if (has_length && !has_size)
+        {
+            /* varying array */
+            size_t typestring_size;
+            size_t element_size = type_memsize(type, 0, NULL);
+            size_t elements = array->cval;
+            size_t total_size = element_size * elements;
+
+            if (total_size < USHRT_MAX)
+            {
+                print_file(file, 2, "0x%x, /* FC_SMVARRAY */\n", RPC_FC_SMVARRAY);
+                /* alignment */
+                print_file(file, 2, "0x%x, /* 0 */\n", 0);
+                /* total size */
+                print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", total_size, total_size);
+                /* number of elements */
+                print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", elements, elements);
+                typestring_size = 6;
+            }
+            else
+            {
+                print_file(file, 2, "0x%x, /* FC_LGVARRAY */\n", RPC_FC_LGVARRAY);
+                /* alignment */
+                print_file(file, 2, "0x%x, /* 0 */\n", 0);
+                /* total size */
+                print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", total_size, total_size);
+                /* number of elements */
+                print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", elements, elements);
+                typestring_size = 10;
+            }
+            /* element size */
+            print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
+            typestring_size += 2;
+
+            /* FIXME: write out variance descriptor */
+            /* FIXME: write out pointer descriptor if necessary */
+
+            print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+            print_file(file, 2, "FC_END,\n");
+            typestring_size += 2;
+
+            return typestring_size;
+        }
+        else if (!has_length && has_size)
+        {
+            /* conformant array */
+            size_t typestring_size;
+            size_t element_size = type_memsize(type, 0, NULL);
+
+            print_file(file, 2, "0x%x, /* FC_CARRAY */\n", RPC_FC_CARRAY);
+            /* alignment */
+            print_file(file, 2, "0x%x, /* 0 */\n", 0);
+            /* element size */
+            print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
+            typestring_size = 4;
+
+            /* FIXME: write out conformance descriptor */
+            /* FIXME: write out pointer descriptor if necessary */
+
+            print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+            print_file(file, 2, "FC_END,\n");
+            typestring_size += 2;
+
+            return typestring_size;
+        }
+        else
+        {
+            /* conformant varying array */
+            size_t typestring_size;
+            size_t element_size = type_memsize(type, 0, NULL);
+
+            print_file(file, 2, "0x%x, /* FC_CARRAY */\n", RPC_FC_CARRAY);
+            /* alignment */
+            print_file(file, 2, "0x%x, /* 0 */\n", 0);
+            /* element size */
+            print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
+            typestring_size = 4;
+
+            /* FIXME: write out conformance descriptor */
+            /* FIXME: write out variance descriptor */
+            /* FIXME: write out pointer descriptor if necessary */
+
+            print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+            print_file(file, 2, "FC_END,\n");
+            typestring_size += 2;
+
+            return typestring_size;
+        }
+    }
 }
 
 static size_t write_typeformatstring_var(FILE *file, int indent,




More information about the wine-cvs mailing list