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]);