d3dxof: Implement storage of parsed information.

This commit is contained in:
Christian Costa 2008-08-22 13:16:58 +02:00 committed by Alexandre Julliard
parent 05a2c56622
commit 2f98206111
2 changed files with 250 additions and 92 deletions

View File

@ -77,18 +77,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dxof);
#define TOKEN_CSTRING 51
#define TOKEN_ARRAY 52
#define CLSIDFMT "<%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X>"
typedef struct {
/* Buffer to parse */
LPBYTE buffer;
DWORD rem_bytes;
/* Dump template content */
char* dump;
DWORD pos;
DWORD size;
/* Misc info */
BOOL txt;
BYTE value[100];
IDirectXFileImpl* pdxf;
} parse_buffer;
static const struct IDirectXFileVtbl IDirectXFile_Vtbl;
static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl;
static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl;
@ -209,18 +209,6 @@ static BOOL read_bytes(parse_buffer * buf, LPVOID data, DWORD size)
return TRUE;
}
static void add_string(parse_buffer * buf, const char * str)
{
DWORD len = strlen(str);
if ((buf->pos + len + 1) > buf->size)
{
FIXME("Dump buffer to small\n");
return;
}
sprintf(buf->dump + buf->pos, str);
buf->pos += len;
}
static void dump_TOKEN(WORD token)
{
#define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
@ -381,6 +369,9 @@ static BOOL is_guid(parse_buffer* buf)
{
static char tmp[50];
DWORD pos = 1;
GUID class_id;
DWORD tab[10];
int ret;
if (*buf->buffer != '<')
return FALSE;
@ -397,10 +388,30 @@ static BOOL is_guid(parse_buffer* buf)
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;
ret = sscanf(tmp, CLSIDFMT, &class_id.Data1, tab, tab+1, tab+2, tab+3, tab+4, tab+5, tab+6, tab+7, tab+8, tab+9);
if (ret != 11)
{
TRACE("Wrong guid %s (%d) \n", tmp, pos);
return FALSE;
}
TRACE("Found guid %s (%d) \n", tmp, pos);
class_id.Data2 = tab[0];
class_id.Data3 = tab[1];
class_id.Data4[0] = tab[2];
class_id.Data4[1] = tab[3];
class_id.Data4[2] = tab[4];
class_id.Data4[3] = tab[5];
class_id.Data4[4] = tab[6];
class_id.Data4[5] = tab[7];
class_id.Data4[6] = tab[8];
class_id.Data4[7] = tab[9];
*(GUID*)buf->value = class_id;
return TRUE;
}
@ -428,6 +439,34 @@ static BOOL is_name(parse_buffer* buf)
buf->rem_bytes -= pos;
TRACE("Found name %s\n", tmp);
strcpy((char*)buf->value, tmp);
return TRUE;
}
static BOOL is_integer(parse_buffer* buf)
{
static char tmp[50];
DWORD pos = 0;
char c;
DWORD integer;
while (!is_separator(c = *(buf->buffer+pos)))
{
if (!((c >= '0') && (c <= '9')))
return FALSE;
tmp[pos++] = c;
}
tmp[pos] = 0;
buf->buffer += pos;
buf->rem_bytes -= pos;
sscanf(tmp, "%d", &integer);
TRACE("Found integer %s - %d\n", tmp, integer);
*(WORD*)buf->value = integer;
return TRUE;
}
@ -469,7 +508,11 @@ static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token)
token = TOKEN_GUID;
break;
}
if (is_integer(buf))
{
token = TOKEN_INTEGER;
break;
}
if (is_name(buf))
{
token = TOKEN_NAME;
@ -495,81 +538,31 @@ static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token)
case TOKEN_GUID:
case TOKEN_INTEGER_LIST:
case TOKEN_FLOAT_LIST:
break;
case TOKEN_OBRACE:
add_string(buf, "{ ");
break;
case TOKEN_CBRACE:
add_string(buf, "} ");
break;
case TOKEN_OPAREN:
add_string(buf, "( ");
break;
case TOKEN_CPAREN:
add_string(buf, ") ");
break;
case TOKEN_OBRACKET:
add_string(buf, "[ ");
break;
case TOKEN_CBRACKET:
add_string(buf, "] ");
break;
case TOKEN_OANGLE:
add_string(buf, "< ");
break;
case TOKEN_CANGLE:
add_string(buf, "> ");
break;
case TOKEN_DOT:
add_string(buf, ".");
break;
case TOKEN_COMMA:
add_string(buf, ", ");
break;
case TOKEN_SEMICOLON:
add_string(buf, "; ");
break;
case TOKEN_TEMPLATE:
add_string(buf, "template ");
break;
case TOKEN_WORD:
add_string(buf, "WORD ");
break;
case TOKEN_DWORD:
add_string(buf, "DWORD ");
break;
case TOKEN_FLOAT:
add_string(buf, "FLOAT ");
break;
case TOKEN_DOUBLE:
add_string(buf, "DOUBLE ");
break;
case TOKEN_CHAR:
add_string(buf, "CHAR ");
break;
case TOKEN_UCHAR:
add_string(buf, "UCHAR ");
break;
case TOKEN_SWORD:
add_string(buf, "SWORD ");
break;
case TOKEN_SDWORD:
add_string(buf, "SDWORD ");
break;
case TOKEN_VOID:
add_string(buf, "VOID ");
break;
case TOKEN_LPSTR:
add_string(buf, "LPSTR ");
break;
case TOKEN_UNICODE:
add_string(buf, "UNICODE ");
break;
case TOKEN_CSTRING:
add_string(buf, "CSTRING ");
break;
case TOKEN_ARRAY:
add_string(buf, "array ");
break;
default:
return 0;
@ -581,6 +574,40 @@ static WORD parse_TOKEN_dbg_opt(parse_buffer * buf, BOOL show_token)
return token;
}
static const char* get_primitive_string(WORD token)
{
switch(token)
{
case TOKEN_WORD:
return "WORD";
case TOKEN_DWORD:
return "DWORD";
case TOKEN_FLOAT:
return "FLOAT";
case TOKEN_DOUBLE:
return "DOUBLE";
case TOKEN_CHAR:
return "CHAR";
case TOKEN_UCHAR:
return "UCHAR";
case TOKEN_SWORD:
return "SWORD";
case TOKEN_SDWORD:
return "SDWORD";
case TOKEN_VOID:
return "VOID";
case TOKEN_LPSTR:
return "LPSTR";
case TOKEN_UNICODE:
return "UNICODE";
case TOKEN_CSTRING:
return "CSTRING ";
default:
break;
}
return NULL;
}
static inline WORD parse_TOKEN(parse_buffer * buf)
{
return parse_TOKEN_dbg_opt(buf, TRUE);
@ -651,8 +678,8 @@ static BOOL parse_name(parse_buffer * buf)
return FALSE;
strname[count] = 0;
/*TRACE("name = %s\n", strname);*/
add_string(buf, strname);
add_string(buf, " ");
strcpy((char*)buf->value, strname);
return TRUE;
}
@ -668,10 +695,11 @@ static BOOL parse_class_id(parse_buffer * buf)
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],
sprintf(strguid, CLSIDFMT, class_id.Data1, class_id.Data2, class_id.Data3, class_id.Data4[0],
class_id.Data4[1], class_id.Data4[2], class_id.Data4[3], class_id.Data4[4], class_id.Data4[5], class_id.Data4[6], class_id.Data4[7]);
/*TRACE("guid = {%s}\n", strguid);*/
add_string(buf, strguid);
*(GUID*)buf->value = class_id;
return TRUE;
}
@ -682,17 +710,21 @@ static BOOL parse_integer(parse_buffer * buf)
if (parse_TOKEN(buf) != TOKEN_INTEGER)
return FALSE;
if (buf->txt)
return TRUE;
if (!read_bytes(buf, &integer, 4))
return FALSE;
/*TRACE("integer = %ld\n", integer);*/
sprintf(buf->dump+buf->pos, "%d ", integer);
buf->pos = strlen(buf->dump);
*(DWORD*)buf->value = integer;
return TRUE;
}
static BOOL parse_template_option_info(parse_buffer * buf)
{
xtemplate* cur_template = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates];
if (check_TOKEN(buf) == TOKEN_DOT)
{
parse_TOKEN(buf);
@ -700,8 +732,7 @@ static BOOL parse_template_option_info(parse_buffer * buf)
return FALSE;
if (parse_TOKEN(buf) != TOKEN_DOT)
return FALSE;
sprintf(buf->dump+buf->pos, " ");
buf->pos = strlen(buf->dump);
cur_template->open = TRUE;
}
else
{
@ -709,86 +740,144 @@ static BOOL parse_template_option_info(parse_buffer * buf)
{
if (!parse_name(buf))
return FALSE;
strcpy(cur_template->childs[cur_template->nb_childs], (char*)buf->value);
if (check_TOKEN(buf) == TOKEN_GUID)
if (!parse_class_id(buf))
return FALSE;
cur_template->nb_childs++;
if (check_TOKEN(buf) != TOKEN_COMMA)
break;
parse_TOKEN(buf);
}
cur_template->open = FALSE;
}
return TRUE;
}
static BOOL parse_template_members_list(parse_buffer * buf)
{
parse_buffer save1;
int idx_member = 0;
member* cur_member;
while (1)
{
cur_member = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[idx_member];
save1 = *buf;
if (check_TOKEN(buf) == TOKEN_NAME)
{
if (!parse_name(buf))
break;
while (cur_member->idx_template < buf->pdxf->nb_xtemplates)
{
if (!strcmp((char*)buf->value, buf->pdxf->xtemplates[cur_member->idx_template].name))
break;
cur_member->idx_template++;
}
if (cur_member->idx_template == buf->pdxf->nb_xtemplates)
{
TRACE("Reference to non existing template '%s'\n", (char*)buf->value);
return FALSE;
}
if (check_TOKEN(buf) == TOKEN_NAME)
if (!parse_name(buf))
break;
if (parse_TOKEN(buf) != TOKEN_SEMICOLON)
break;
cur_member->type = TOKEN_NAME;
strcpy(cur_member->name, (char*)buf->value);
idx_member++;
}
else if (check_TOKEN(buf) == TOKEN_ARRAY)
{
parse_buffer save2;
WORD token;
int nb_dims = 0;
parse_TOKEN(buf);
token = check_TOKEN(buf);
if (is_primitive_type(token))
{
parse_TOKEN(buf);
cur_member->type = token;
}
else
{
if (!parse_name(buf))
break;
cur_member->type = TOKEN_NAME;
cur_member->idx_template = 0;
while (cur_member->idx_template < buf->pdxf->nb_xtemplates)
{
if (!strcmp((char*)buf->value, buf->pdxf->xtemplates[cur_member->idx_template].name))
break;
cur_member->idx_template++;
}
if (cur_member->idx_template == buf->pdxf->nb_xtemplates)
{
TRACE("Reference to non existing template '%s'\n", (char*)buf->value);
return FALSE;
}
}
if (!parse_name(buf))
break;
strcpy(cur_member->name, (char*)buf->value);
save2 = *buf;
while (check_TOKEN(buf) == TOKEN_OBRACKET)
{
if (nb_dims)
{
FIXME("No support for multi-dimensional array yet\n");
return FALSE;
}
parse_TOKEN(buf);
if (check_TOKEN(buf) == TOKEN_INTEGER)
{
if (!parse_integer(buf))
break;
cur_member->dim_fixed[nb_dims] = TRUE;
cur_member->dim_value[nb_dims] = *(DWORD*)buf->value;
}
else
{
if (!parse_name(buf))
break;
cur_member->dim_fixed[nb_dims] = FALSE;
/* Hack: Assume array size is specified in previous member */
cur_member->dim_value[nb_dims] = idx_member - 1;
}
if (parse_TOKEN(buf) != TOKEN_CBRACKET)
break;
save2 = *buf;
nb_dims++;
}
*buf = save2;
if (parse_TOKEN(buf) != TOKEN_SEMICOLON)
break;
cur_member->nb_dims = nb_dims;
idx_member++;
}
else if (is_primitive_type(check_TOKEN(buf)))
{
cur_member->type = check_TOKEN(buf);
parse_TOKEN(buf);
if (check_TOKEN(buf) == TOKEN_NAME)
if (!parse_name(buf))
break;
strcpy(cur_member->name, (char*)buf->value);
if (parse_TOKEN(buf) != TOKEN_SEMICOLON)
break;
idx_member++;
}
else
break;
add_string(buf, "\n");
}
*buf = save1;
buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].nb_members = idx_member;
return TRUE;
}
@ -801,7 +890,6 @@ static BOOL parse_template_parts(parse_buffer * buf)
return FALSE;
if (parse_TOKEN(buf) != TOKEN_CBRACKET)
return FALSE;
add_string(buf, "\n");
}
else
{
@ -814,7 +902,6 @@ static BOOL parse_template_parts(parse_buffer * buf)
return FALSE;
if (parse_TOKEN(buf) != TOKEN_CBRACKET)
return FALSE;
add_string(buf, "\n");
}
}
@ -827,18 +914,16 @@ static BOOL parse_template(parse_buffer * buf)
return FALSE;
if (!parse_name(buf))
return FALSE;
add_string(buf, "\n");
strcpy(buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, (char*)buf->value);
if (parse_TOKEN(buf) != TOKEN_OBRACE)
return FALSE;
add_string(buf, "\n");
if (!parse_class_id(buf))
return FALSE;
add_string(buf, "\n");
buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id = *(GUID*)buf->value;
if (!parse_template_parts(buf))
return FALSE;
if (parse_TOKEN(buf) != TOKEN_CBRACE)
return FALSE;
add_string(buf, "\n\n");
if (buf->txt)
{
/* Go to the next template */
@ -851,6 +936,10 @@ static BOOL parse_template(parse_buffer * buf)
}
}
}
TRACE("%d - %s - %s\n", buf->pdxf->nb_xtemplates, buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, debugstr_guid(&buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id));
buf->pdxf->nb_xtemplates++;
return TRUE;
}
@ -862,9 +951,8 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
buf.buffer = (LPBYTE)pvData;
buf.rem_bytes = cbSize;
buf.dump = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
buf.size = 500;
buf.txt = FALSE;
buf.pdxf = This;
FIXME("(%p/%p)->(%p,%d) partial stub!\n", This, iface, pvData, cbSize);
@ -917,21 +1005,64 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
while (buf.rem_bytes)
{
buf.pos = 0;
if (!parse_template(&buf))
{
TRACE("Template is not correct\n");
return DXFILEERR_BADVALUE;
}
else
{
TRACE("Template successfully parsed:\n");
if (TRACE_ON(d3dxof))
/* Only dump in binary format */
if (!buf.txt)
DPRINTF(buf.dump);
{
int i,j,k;
GUID* clsid;
i = This->nb_xtemplates - 1;
clsid = &This->xtemplates[i].class_id;
DPRINTF("template %s {\n", This->xtemplates[i].name);
DPRINTF(CLSIDFMT "\n", clsid->Data1, clsid->Data2, clsid->Data3, clsid->Data4[0],
clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7]);
for (j = 0; j < This->xtemplates[i].nb_members; j++)
{
if (This->xtemplates[i].members[j].nb_dims)
DPRINTF("array ");
if (This->xtemplates[i].members[j].type == TOKEN_NAME)
DPRINTF("%s ", This->xtemplates[This->xtemplates[i].members[j].idx_template].name);
else
DPRINTF("%s ", get_primitive_string(This->xtemplates[i].members[j].type));
DPRINTF("%s", This->xtemplates[i].members[j].name);
for (k = 0; k < This->xtemplates[i].members[j].nb_dims; k++)
{
if (This->xtemplates[i].members[j].dim_fixed[k])
DPRINTF("[%d]", This->xtemplates[i].members[j].dim_value[k]);
else
DPRINTF("[%s]", This->xtemplates[i].members[This->xtemplates[i].members[j].dim_value[k]].name);
}
DPRINTF(";\n");
}
if (This->xtemplates[i].open)
DPRINTF("[...]\n");
else if (This->xtemplates[i].nb_childs)
{
DPRINTF("[%s", This->xtemplates[i].childs[0]);
for (j = 1; j < This->xtemplates[i].nb_childs; j++)
DPRINTF(",%s", This->xtemplates[i].childs[j]);
DPRINTF("]\n");
}
DPRINTF("}\n");
}
}
}
HeapFree(GetProcessHeap(), 0, buf.dump);
if (TRACE_ON(d3dxof))
{
int i;
TRACE("Registered templates (%d):\n", This->nb_xtemplates);
for (i = 0; i < This->nb_xtemplates; i++)
DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
}
return DXFILE_OK;
}

View File

@ -1,7 +1,7 @@
/*
* DirectX File private interfaces (D3DXOF.DLL)
*
* Copyright 2004 Christian Costa
* Copyright 2004, 2008 Christian Costa
*
* This file contains the (internal) driver registration functions,
* driver enumeration APIs and DirectDraw creation functions.
@ -33,9 +33,36 @@
#include "winuser.h"
#include "dxfile.h"
#define MAX_NAME_LEN 32
#define MAX_ARRAY_DIM 1
#define MAX_MEMBERS 50
#define MAX_CHILDS 10
#define MAX_TEMPLATES 200
typedef struct {
DWORD type;
LONG idx_template;
char name[MAX_NAME_LEN];
ULONG nb_dims;
BOOL dim_fixed[MAX_ARRAY_DIM]; /* fixed or variable */
ULONG dim_value[MAX_ARRAY_DIM]; /* fixed value or member index */
} member;
typedef struct {
char name[MAX_NAME_LEN];
GUID class_id;
BOOL open;
ULONG nb_childs;
char childs[MAX_CHILDS][MAX_NAME_LEN];
ULONG nb_members;
member members[MAX_MEMBERS];
} xtemplate;
typedef struct {
IDirectXFile lpVtbl;
LONG ref;
ULONG nb_xtemplates;
xtemplate xtemplates[MAX_TEMPLATES];
} IDirectXFileImpl;
typedef struct {