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