Module: wine Branch: master Commit: dd5908224ea3ec27b91d438c88acbfea70117408 URL: http://source.winehq.org/git/wine.git/?a=commit;h=dd5908224ea3ec27b91d438c88...
Author: Christian Costa titan.costa@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);