Am 21.04.2011 16:46, schrieb Henri Verbeet:
2011/4/20 Rico Schüller<[email protected]>:
+inline LPSTR get_partial_string(LPCSTR name, char initial, char final)
That should probably be static instead of inline. Also,
get_parameter_by_name() looks like it could be split up, and you can
probably avoid the copy in get_partial_string().


Something like the attached patch should be better in that regards. Any thoughts?

Cheers
Rico
commit 32208ee7a1c84f91578b934fe0308d1927e43885
Author: Rico Schüller <[email protected]>
Date:   Thu Apr 21 11:05:17 2011 +0200

    d3dx9: Improve get_parameter_by_name().

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 0f65df7..b4ffc37 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -107,6 +107,11 @@ struct ID3DXEffectCompilerImpl
     ID3DXBaseEffect *base_effect;
 };
 
+static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl 
*base,
+        struct d3dx_parameter *parameter, LPCSTR name);
+static struct d3dx_parameter *get_parameter_annotation_by_name(struct 
ID3DXBaseEffectImpl *base,
+        struct d3dx_parameter *parameter, LPCSTR name);
+
 static inline void read_dword(const char **ptr, DWORD *d)
 {
     memcpy(d, *ptr, sizeof(*d));
@@ -436,151 +441,160 @@ static void free_effect_compiler(struct 
ID3DXEffectCompilerImpl *compiler)
     }
 }
 
-static LPSTR get_partial_string(LPCSTR name, char initial, char final)
+static UINT name_length(LPCSTR name)
 {
-    UINT length;
-    LPCSTR begin;
-    LPSTR part;
+    UINT length, i;
+    const char chars[] = {'[', '.', '@'};
 
-    TRACE("name %s, initial %c, final %c\n", debugstr_a(name), initial, final);
+    length = strlen(name);
 
-    begin = initial ? (strchr(name, initial) + 1) : name;
-    length = strchr(name, final) - begin;
-    if (length < 1)
+    for (i = 0; i < sizeof(chars); ++i)
     {
-        WARN("Invalied argument specified.\n");
-        return NULL;
-    }
+        LPCSTR found = strchr(name, chars[i]);
 
-    part = HeapAlloc(GetProcessHeap(), 0, length + 1);
-    if (!part)
-    {
-        ERR("Out of memory\n");
-        return NULL;
+        if (found)
+        {
+            length = min(length, found - name);
+        }
     }
-    memcpy(part, begin, length);
-    part[length] = 0;
 
-    TRACE("part %s\n", debugstr_a(part));
-    return part;
+    return length;
 }
 
-static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl 
*base, struct d3dx_parameter *parameter, LPCSTR name, BOOL is_annotation)
+static struct d3dx_parameter *get_parameter_element_by_name(struct 
ID3DXBaseEffectImpl *base,
+        struct d3dx_parameter *parameter, LPCSTR name)
 {
-    unsigned int i;
+    UINT element;
     struct d3dx_parameter *temp_parameter;
-    LPSTR part;
+    LPCSTR part;
 
-    TRACE("base %p, parameter %p, name %s, is_annotation %s\n", base, 
parameter, debugstr_a(name), is_annotation ? "YES" : "NO");
+    TRACE("base %p, parameter %p, name %s\n", base, parameter, 
debugstr_a(name));
 
-    if (!name) return NULL;
+    if (!name || !*name) return parameter;
 
-    /* members */
-    if (strchr(name, '.'))
+    element = atoi(name);
+    part = strchr(name, ']') + 1;
+
+    if (parameter->element_count > element)
     {
-        part = get_partial_string(name, 0, '.');
-        temp_parameter = get_parameter_by_name(base, parameter, part, 
is_annotation);
-        HeapFree(GetProcessHeap(), 0, part);
+        temp_parameter = 
get_parameter_struct(parameter->member_handles[element]);
 
-        if (temp_parameter)
+        switch (*part++)
         {
-            temp_parameter = get_parameter_by_name(base, temp_parameter, 
strchr(name, '.') + 1, FALSE);
-            TRACE("Returning sub parameter %p\n", temp_parameter);
-            return temp_parameter;
-        }
+            case '.':
+                return get_parameter_by_name(base, temp_parameter, part);
 
-        TRACE("Sub parameter not found\n");
-        return NULL;
-    }
+            case '@':
+                return get_parameter_annotation_by_name(base, temp_parameter, 
part);
 
-    /* annotations */
-    if (strchr(name, '@'))
-    {
-        part = get_partial_string(name, 0, '@');
-        temp_parameter = get_parameter_by_name(base, parameter, part, 
is_annotation);
-        HeapFree(GetProcessHeap(), 0, part);
+            case '\0':
+                return temp_parameter;
 
-        if (temp_parameter)
-        {
-            temp_parameter = get_parameter_by_name(base, temp_parameter, 
strchr(name, '@') + 1, TRUE);
-            TRACE("Returning sub parameter %p\n", temp_parameter);
-            return temp_parameter;
+            default:
+                FIXME("Unhandled case \"%c\"\n", *--part);
+                break;
         }
-
-        TRACE("Sub parameter not found\n");
-        return NULL;
     }
 
-    /* elements */
-    if (strchr(name, '['))
+    TRACE("Parameter not found\n");
+    return NULL;
+}
+
+static struct d3dx_parameter *get_parameter_annotation_by_name(struct 
ID3DXBaseEffectImpl *base,
+        struct d3dx_parameter *parameter, LPCSTR name)
+{
+    UINT i, length;
+    struct d3dx_parameter *temp_parameter;
+    LPCSTR part;
+
+    TRACE("base %p, parameter %p, name %s\n", base, parameter, 
debugstr_a(name));
+
+    if (!name || !*name) return parameter;
+
+    length = name_length(name);
+    part = name + length;
+
+    for (i = 0; i < parameter->annotation_count; ++i)
     {
-        part = get_partial_string(name, 0, '[');
-        temp_parameter = get_parameter_by_name(base, parameter, part, 
is_annotation);
-        HeapFree(GetProcessHeap(), 0, part);
+        temp_parameter = 
get_parameter_struct(parameter->annotation_handles[i]);
 
-        if (temp_parameter)
+        if (!strcmp(temp_parameter->name, name))
+        {
+            TRACE("Returning parameter %p\n", temp_parameter);
+            return temp_parameter;
+        }
+        else if (strlen(temp_parameter->name) == length && 
!strncmp(temp_parameter->name, name, length))
         {
-            unsigned int index;
+            switch (*part++)
+            {
+                case '.':
+                    return get_parameter_by_name(base, temp_parameter, part);
 
-            part = get_partial_string(name, '[', ']');
-            index = atoi(part);
-            HeapFree(GetProcessHeap(), 0, part);
+                case '[':
+                    return get_parameter_element_by_name(base, temp_parameter, 
part);
 
-            if (index < temp_parameter->element_count)
-            {
-                TRACE("Returning sub parameter %p\n", 
get_parameter_struct(temp_parameter->member_handles[index]));
-                return 
get_parameter_struct(temp_parameter->member_handles[index]);
+                default:
+                    FIXME("Unhandled case \"%c\"\n", *--part);
+                    break;
             }
         }
-
-        TRACE("Sub parameter not found\n");
-        return NULL;
     }
 
+    TRACE("Parameter not found\n");
+    return NULL;
+}
+
+static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl 
*base,
+        struct d3dx_parameter *parameter, LPCSTR name)
+{
+    UINT i, count, length;
+    struct d3dx_parameter *temp_parameter;
+    D3DXHANDLE *handles;
+    LPCSTR part;
+
+    TRACE("base %p, parameter %p, name %s\n", base, parameter, 
debugstr_a(name));
+
+    if (!name || !*name) return parameter;
+
     if (!parameter)
     {
-        for (i=0; i < base->parameter_count; i++)
-        {
-            temp_parameter = get_parameter_struct(base->parameter_handles[i]);
-
-            if (!strcmp(temp_parameter->name, name))
-            {
-                TRACE("Returning parameter %p\n", temp_parameter);
-                return temp_parameter;
-            }
-        }
+        count = base->parameter_count;
+        handles = base->parameter_handles;
     }
     else
     {
-        if (is_annotation)
-        {
-            for (i = 0; i < parameter->annotation_count; i++)
-            {
-                temp_parameter = 
get_parameter_struct(parameter->annotation_handles[i]);
+        count = parameter->member_count;
+        handles = parameter->member_handles;
+    }
 
-                if (!strcmp(temp_parameter->name, name))
-                {
-                    TRACE("Returning parameter %p\n", temp_parameter);
-                    return temp_parameter;
-                }
-            }
+    length = name_length(name);
+    part = name + length;
+
+    for (i = 0; i < count; i++)
+    {
+        temp_parameter = get_parameter_struct(handles[i]);
+
+        if (!strcmp(temp_parameter->name, name))
+        {
+            TRACE("Returning parameter %p\n", temp_parameter);
+            return temp_parameter;
         }
-        else
+        else if (strlen(temp_parameter->name) == length && 
!strncmp(temp_parameter->name, name, length))
         {
-            unsigned int count;
+            switch (*part++)
+            {
+                case '.':
+                    return get_parameter_by_name(base, temp_parameter, part);
 
-            if (parameter->element_count) count = parameter->element_count;
-            else count = parameter->member_count;
+                case '@':
+                    return get_parameter_annotation_by_name(base, 
temp_parameter, part);
 
-            for (i = 0; i < count; i++)
-            {
-                temp_parameter = 
get_parameter_struct(parameter->member_handles[i]);
+                case '[':
+                    return get_parameter_element_by_name(base, temp_parameter, 
part);
 
-                if (!strcmp(temp_parameter->name, name))
-                {
-                    TRACE("Returning parameter %p\n", temp_parameter);
-                    return temp_parameter;
-                }
+                default:
+                    FIXME("Unhandled case \"%c\"\n", *--part);
+                    break;
             }
         }
     }
@@ -743,7 +757,7 @@ static D3DXHANDLE WINAPI 
ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface
 
     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
 
-    if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE);
+    if (!param) param = get_parameter_by_name(This, NULL, parameter);
 
     if (!parameter)
     {
@@ -775,7 +789,7 @@ static D3DXHANDLE WINAPI 
ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect
 
     TRACE("iface %p, parameter %p, name %s\n", This, parameter, 
debugstr_a(name));
 
-    if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE);
+    if (!param) param = get_parameter_by_name(This, NULL, parameter);
 
     if (!name)
     {
@@ -784,7 +798,7 @@ static D3DXHANDLE WINAPI 
ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect
         return handle;
     }
 
-    handle = get_parameter_handle(get_parameter_by_name(This, param, name, 
FALSE));
+    handle = get_parameter_handle(get_parameter_by_name(This, param, name));
     TRACE("Returning parameter %p\n", handle);
 
     return handle;
@@ -806,7 +820,7 @@ static D3DXHANDLE WINAPI 
ID3DXBaseEffectImpl_GetParameterElement(ID3DXBaseEffect
 
     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
 
-    if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE);
+    if (!param) param = get_parameter_by_name(This, NULL, parameter);
 
     if (!param)
     {

commit 55ac28b2b6ca4442441042f65bd2f9eb05b7e7bb
Author: Rico Schüller <[email protected]>
Date:   Wed Apr 20 21:58:25 2011 +0200

    d3dx9: Improve ID3DXBaseEffect::GetParameter().

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index d44616c..0f65df7 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -739,9 +739,12 @@ static HRESULT WINAPI 
ID3DXBaseEffectImpl_GetFunctionDesc(ID3DXBaseEffect *iface
 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect 
*iface, D3DXHANDLE parameter, UINT index)
 {
     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
+    struct d3dx_parameter *param = is_valid_parameter(This, parameter);
 
     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
 
+    if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE);
+
     if (!parameter)
     {
         if (index < This->parameter_count)
@@ -752,8 +755,6 @@ static D3DXHANDLE WINAPI 
ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface
     }
     else
     {
-        struct d3dx_parameter *param = is_valid_parameter(This, parameter);
-
         if (param && !param->element_count && index < param->member_count)
         {
             TRACE("Returning parameter %p\n", param->member_handles[index]);


Reply via email to