Christian Costa : d3dxof: Add text format support to RegisterTemplates and fix corresponding test.
Alexandre Julliard
julliard at winehq.org
Tue Aug 19 08:47:03 CDT 2008
Module: wine
Branch: master
Commit: dd5908224ea3ec27b91d438c88acbfea70117408
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dd5908224ea3ec27b91d438c88acbfea70117408
Author: Christian Costa <titan.costa at wanadoo.fr>
Date: Tue Aug 19 14:00:32 2008 +0200
d3dxof: Add text format support to RegisterTemplates and fix corresponding test.
---
dlls/d3dxof/d3dxof.c | 296 +++++++++++++++++++++++++++++++++++++++++---
dlls/d3dxof/tests/d3dxof.c | 4 +-
2 files changed, 281 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dxof/d3dxof.c b/dlls/d3dxof/d3dxof.c
index dff299d..f16dce1 100644
--- a/dlls/d3dxof/d3dxof.c
+++ b/dlls/d3dxof/d3dxof.c
@@ -85,6 +85,7 @@ typedef struct {
char* dump;
DWORD pos;
DWORD size;
+ BOOL txt;
} parse_buffer;
@@ -264,28 +265,239 @@ static void dump_TOKEN(WORD token)
#undef DUMP_TOKEN
}
-static WORD check_TOKEN(parse_buffer * buf)
+static BOOL is_space(char c)
{
- WORD token;
+ switch (c)
+ {
+ case 0x00:
+ case 0x0D:
+ case 0x0A:
+ case ' ':
+ case '\t':
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
- if (!read_bytes(buf, &token, 2))
- return 0;
- buf->buffer -= 2;
- buf->rem_bytes += 2;
- if (0)
+static BOOL is_operator(char c)
+{
+ switch(c)
{
- TRACE("check: ");
- dump_TOKEN(token);
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ case '<':
+ case '>':
+ case ',':
+ case ';':
+ return TRUE;
+ break;
}
- return token;
+ return FALSE;
}
-static WORD parse_TOKEN(parse_buffer * buf)
+static inline BOOL is_separator(char c)
+{
+ return is_space(c) || is_operator(c);
+}
+
+static WORD get_operator_token(char c)
+{
+ switch(c)
+ {
+ case '{':
+ return TOKEN_OBRACE;
+ break;
+ case '}':
+ return TOKEN_CBRACE;
+ break;
+ case '[':
+ return TOKEN_OBRACKET;
+ break;
+ case ']':
+ return TOKEN_CBRACKET;
+ break;
+ case '(':
+ return TOKEN_OPAREN;
+ break;
+ case ')':
+ return TOKEN_CPAREN;
+ break;
+ case '<':
+ return TOKEN_OANGLE;
+ break;
+ case '>':
+ return TOKEN_CANGLE;
+ break;
+ case ',':
+ return TOKEN_COMMA;
+ break;
+ case ';':
+ return TOKEN_SEMICOLON;
+ break;
+ }
+ return 0;
+}
+
+static BOOL is_keyword(parse_buffer* buf, const char* keyword)
+{
+ DWORD len = strlen(keyword);
+ if (!strncmp((char*)buf->buffer, keyword,len) && is_separator(*(buf->buffer+len)))
+ {
+ buf->buffer += len;
+ buf->rem_bytes -= len;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static WORD get_keyword_token(parse_buffer* buf)
+{
+ if (is_keyword(buf, "template"))
+ return TOKEN_TEMPLATE;
+ if (is_keyword(buf, "WORD"))
+ return TOKEN_WORD;
+ if (is_keyword(buf, "DWORD"))
+ return TOKEN_DWORD;
+ if (is_keyword(buf, "FLOAT"))
+ return TOKEN_FLOAT;
+ if (is_keyword(buf, "DOUBLE"))
+ return TOKEN_DOUBLE;
+ if (is_keyword(buf, "CHAR"))
+ return TOKEN_CHAR;
+ if (is_keyword(buf, "UCHAR"))
+ return TOKEN_UCHAR;
+ if (is_keyword(buf, "SWORD"))
+ return TOKEN_SWORD;
+ if (is_keyword(buf, "SDWORD"))
+ return TOKEN_SDWORD;
+ if (is_keyword(buf, "VOID"))
+ return TOKEN_VOID;
+ if (is_keyword(buf, "LPSTR"))
+ return TOKEN_LPSTR;
+ if (is_keyword(buf, "UNICODE"))
+ return TOKEN_UNICODE;
+ if (is_keyword(buf, "CSTRING"))
+ return TOKEN_CSTRING;
+ if (is_keyword(buf, "array"))
+ return TOKEN_ARRAY;
+
+ return 0;
+}
+
+static BOOL is_guid(parse_buffer* buf)
+{
+ static char tmp[50];
+ DWORD pos = 1;
+
+ if (*buf->buffer != '<')
+ return FALSE;
+ tmp[0] = '<';
+ while (*(buf->buffer+pos) != '>')
+ {
+ tmp[pos] = *(buf->buffer+pos);
+ pos++;
+ }
+ tmp[pos++] = '>';
+ tmp[pos] = 0;
+ if (pos != 37 /* <+35+> */)
+ {
+ TRACE("Wrong guid %s (%d) \n", tmp, pos);
+ return FALSE;
+ }
+ TRACE("Found guid %s (%d) \n", tmp, pos);
+ buf->buffer += pos;
+ buf->rem_bytes -= pos;
+
+ return TRUE;
+}
+
+static BOOL is_name(parse_buffer* buf)
+{
+ static char tmp[50];
+ DWORD pos = 0;
+ char c;
+ BOOL error = 0;
+ while (!is_separator(c = *(buf->buffer+pos)))
+ {
+ if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))))
+ error = 1;
+ tmp[pos++] = c;
+ }
+ tmp[pos] = 0;
+
+ if (error)
+ {
+ TRACE("Wrong name %s\n", tmp);
+ return FALSE;
+ }
+
+ buf->buffer += pos;
+ buf->rem_bytes -= pos;
+
+ TRACE("Found name %s\n", tmp);
+
+ return TRUE;
+}
+
+static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token)
{
WORD token;
- if (!read_bytes(buf, &token, 2))
- return 0;
+ if (buf->txt)
+ {
+ while(1)
+ {
+ char c;
+ if (!read_bytes(buf, &c, 1))
+ return 0;
+ /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
+ if (is_space(c))
+ continue;
+ if (is_operator(c) && (c != '<'))
+ {
+ token = get_operator_token(c);
+ break;
+ }
+ else if (c == '.')
+ {
+ token = TOKEN_DOT;
+ break;
+ }
+ else
+ {
+ buf->buffer -= 1;
+ buf->rem_bytes += 1;
+
+ if ((token = get_keyword_token(buf)))
+ break;
+
+ if (is_guid(buf))
+ {
+ token = TOKEN_GUID;
+ break;
+ }
+
+ if (is_name(buf))
+ {
+ token = TOKEN_NAME;
+ break;
+ }
+
+ FIXME("Unrecognize element\n");
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ if (!read_bytes(buf, &token, 2))
+ return 0;
+ }
switch(token)
{
@@ -375,12 +587,42 @@ static WORD parse_TOKEN(parse_buffer * buf)
return 0;
}
- if (0)
+ if (show_token)
dump_TOKEN(token);
return token;
}
+static inline WORD parse_TOKEN(parse_buffer * buf)
+{
+ return parse_TOKEN_dbg_opt(buf, TRUE);
+}
+
+static WORD check_TOKEN(parse_buffer * buf)
+{
+ WORD token;
+
+ if (buf->txt)
+ {
+ parse_buffer save = *buf;
+ /*TRACE("check: ");*/
+ token = parse_TOKEN_dbg_opt(buf, FALSE);
+ *buf = save;
+ return token;
+ }
+
+ if (!read_bytes(buf, &token, 2))
+ return 0;
+ buf->buffer -= 2;
+ buf->rem_bytes += 2;
+ if (0)
+ {
+ TRACE("check: ");
+ dump_TOKEN(token);
+ }
+ return token;
+}
+
static inline BOOL is_primitive_type(WORD token)
{
BOOL ret;
@@ -413,6 +655,8 @@ static BOOL parse_name(parse_buffer * buf)
if (parse_TOKEN(buf) != TOKEN_NAME)
return FALSE;
+ if (buf->txt)
+ return TRUE;
if (!read_bytes(buf, &count, 4))
return FALSE;
if (!read_bytes(buf, strname, count))
@@ -432,6 +676,8 @@ static BOOL parse_class_id(parse_buffer * buf)
if (parse_TOKEN(buf) != TOKEN_GUID)
return FALSE;
+ if (buf->txt)
+ return TRUE;
if (!read_bytes(buf, &class_id, 16))
return FALSE;
sprintf(strguid, "<%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X>", class_id.Data1, class_id.Data2, class_id.Data3, class_id.Data4[0],
@@ -605,6 +851,18 @@ static BOOL parse_template(parse_buffer * buf)
if (parse_TOKEN(buf) != TOKEN_CBRACE)
return FALSE;
add_string(buf, "\n\n");
+ if (buf->txt)
+ {
+ /* Go to the next template */
+ while (buf->rem_bytes)
+ {
+ if (is_space(*buf->buffer))
+ {
+ buf->buffer++;
+ buf->rem_bytes--;
+ }
+ }
+ }
return TRUE;
}
@@ -618,6 +876,7 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
buf.rem_bytes = cbSize;
buf.dump = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
buf.size = 500;
+ buf.txt = FALSE;
FIXME("(%p/%p)->(%p,%d) partial stub!\n", This, iface, pvData, cbSize);
@@ -652,8 +911,7 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
if (token_header == XOFFILE_FORMAT_TEXT)
{
- FIXME("Text format not supported yet");
- return DXFILEERR_BADVALUE;
+ buf.txt = TRUE;
}
if (token_header == XOFFILE_FORMAT_COMPRESSED)
@@ -667,6 +925,8 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
return DXFILEERR_BADFILEFLOATSIZE;
+ TRACE("Header is correct\n");
+
while (buf.rem_bytes)
{
buf.pos = 0;
@@ -678,7 +938,9 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
else
TRACE("Template successfully parsed:\n");
if (TRACE_ON(d3dxof))
- DPRINTF(buf.dump);
+ /* Only dump in binary format */
+ if (!buf.txt)
+ DPRINTF(buf.dump);
}
HeapFree(GetProcessHeap(), 0, buf.dump);
diff --git a/dlls/d3dxof/tests/d3dxof.c b/dlls/d3dxof/tests/d3dxof.c
index e9ee9f2..8ee58b3 100644
--- a/dlls/d3dxof/tests/d3dxof.c
+++ b/dlls/d3dxof/tests/d3dxof.c
@@ -24,7 +24,7 @@
#include "dxfile.h"
char template[] =
-"xof 0302 txt 064\n"
+"xof 0302txt 0064\n"
"template Header\n"
"{\n"
"<3D82AB43-62DA-11CF-AB390020AF71E433>\n"
@@ -63,7 +63,7 @@ static void test_d3dxof(void)
/* RegisterTemplates does not support txt format yet */
hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, strlen(template));
- todo_wine ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
+ ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
ref = IDirectXFile_Release(lpDirectXFile);
ok(ref == 0, "Got refcount %ld, expected 1\n", ref);
More information about the wine-cvs
mailing list