From: Michael Stefaniuc mstefani@winehq.org
--- dlls/dmscript/dmscript_private.h | 9 - dlls/dmscript/script.c | 275 +++++++++---------------------- 2 files changed, 79 insertions(+), 205 deletions(-)
diff --git a/dlls/dmscript/dmscript_private.h b/dlls/dmscript/dmscript_private.h index f715c083523..0ffbc75e137 100644 --- a/dlls/dmscript/dmscript_private.h +++ b/dlls/dmscript/dmscript_private.h @@ -48,13 +48,4 @@ extern HRESULT DMUSIC_CreateDirectMusicScriptImpl(REFIID riid, void **ppobj, IUn
extern HRESULT DMUSIC_CreateDirectMusicScriptTrack(REFIID riid, void **ppobj, IUnknown *pUnkOuter);
-/***************************************************************************** - * Misc. - */ -/* for simpler reading */ -typedef struct _DMUS_PRIVATE_CHUNK { - FOURCC fccID; /* FOURCC ID of the chunk */ - DWORD dwSize; /* size of the chunk */ -} DMUS_PRIVATE_CHUNK, *LPDMUS_PRIVATE_CHUNK; - #endif /* __WINE_DMSCRIPT_PRIVATE_H */ diff --git a/dlls/dmscript/script.c b/dlls/dmscript/script.c index b6be6db89ae..4b076418fc5 100644 --- a/dlls/dmscript/script.c +++ b/dlls/dmscript/script.c @@ -25,8 +25,6 @@ #include "dmobject.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmscript); -WINE_DECLARE_DEBUG_CHANNEL(dmfile); -
/***************************************************************************** * IDirectMusicScriptImpl implementation @@ -36,10 +34,10 @@ typedef struct IDirectMusicScriptImpl { struct dmobject dmobj; LONG ref; IDirectMusicPerformance *pPerformance; - DMUS_IO_SCRIPT_HEADER *pHeader; - DMUS_IO_VERSION *pVersion; - WCHAR *pwzLanguage; - WCHAR *pwzSource; + DMUS_IO_SCRIPT_HEADER header; + DMUS_IO_VERSION version; + WCHAR *lang; + WCHAR *source; } IDirectMusicScriptImpl;
static inline IDirectMusicScriptImpl *impl_from_IDirectMusicScript(IDirectMusicScript *iface) @@ -89,10 +87,8 @@ static ULONG WINAPI IDirectMusicScriptImpl_Release(IDirectMusicScript *iface) TRACE("(%p) ref=%ld\n", This, ref);
if (!ref) { - free(This->pHeader); - free(This->pVersion); - free(This->pwzLanguage); - free(This->pwzSource); + free(This->lang); + free(This->source); free(This); }
@@ -272,192 +268,79 @@ static HRESULT load_container(IStream *stream, struct chunk_entry *riff) return hr; }
-static HRESULT WINAPI IPersistStreamImpl_Load(IPersistStream *iface, IStream *pStm) +static HRESULT WINAPI script_persist_stream_Load(IPersistStream *iface, IStream *stream) { - IDirectMusicScriptImpl *This = impl_from_IPersistStream(iface); - DMUS_PRIVATE_CHUNK Chunk; - DWORD StreamSize, StreamCount, ListSize[3], ListCount[3]; - LARGE_INTEGER liMove; /* used when skipping chunks */ - - FIXME("(%p, %p): Loading not implemented yet\n", This, pStm); - IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); - TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); - switch (Chunk.fccID) { - case FOURCC_RIFF: { - IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); - TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID)); - StreamSize = Chunk.dwSize - sizeof(FOURCC); - StreamCount = 0; - switch (Chunk.fccID) { - case DMUS_FOURCC_SCRIPT_FORM: { - TRACE_(dmfile)(": script form\n"); - do { - IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); - StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; - TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); - switch (Chunk.fccID) { - case DMUS_FOURCC_SCRIPT_CHUNK: { - TRACE_(dmfile)(": script header chunk\n"); - This->pHeader = calloc(1, Chunk.dwSize); - IStream_Read (pStm, This->pHeader, Chunk.dwSize, NULL); - break; - } - case DMUS_FOURCC_SCRIPTVERSION_CHUNK: { - TRACE_(dmfile)(": script version chunk\n"); - This->pVersion = calloc(1, Chunk.dwSize); - IStream_Read (pStm, This->pVersion, Chunk.dwSize, NULL); - TRACE_(dmfile)("version: 0x%08lx.0x%08lx\n", This->pVersion->dwVersionMS, This->pVersion->dwVersionLS); - break; - } - case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK: { - TRACE_(dmfile)(": script language chunk\n"); - This->pwzLanguage = calloc(1, Chunk.dwSize); - IStream_Read (pStm, This->pwzLanguage, Chunk.dwSize, NULL); - TRACE_(dmfile)("using language: %s\n", debugstr_w(This->pwzLanguage)); - break; - } - case DMUS_FOURCC_SCRIPTSOURCE_CHUNK: { - TRACE_(dmfile)(": script source chunk\n"); - This->pwzSource = calloc(1, Chunk.dwSize); - IStream_Read (pStm, This->pwzSource, Chunk.dwSize, NULL); - if (TRACE_ON(dmscript)) { - int count = WideCharToMultiByte(CP_ACP, 0, This->pwzSource, -1, NULL, 0, NULL, NULL); - LPSTR str = malloc(count); - WideCharToMultiByte(CP_ACP, 0, This->pwzSource, -1, str, count, NULL, NULL); - str[count-1] = '\n'; - TRACE("source:\n"); - fwrite( str, 1, count, stderr ); - free(str); - } - break; - } - case DMUS_FOURCC_GUID_CHUNK: { - TRACE_(dmfile)(": GUID chunk\n"); - This->dmobj.desc.dwValidData |= DMUS_OBJ_OBJECT; - IStream_Read (pStm, &This->dmobj.desc.guidObject, Chunk.dwSize, NULL); - break; - } - case DMUS_FOURCC_VERSION_CHUNK: { - TRACE_(dmfile)(": version chunk\n"); - This->dmobj.desc.dwValidData |= DMUS_OBJ_VERSION; - IStream_Read (pStm, &This->dmobj.desc.vVersion, Chunk.dwSize, NULL); - break; - } - case DMUS_FOURCC_CATEGORY_CHUNK: { - TRACE_(dmfile)(": category chunk\n"); - This->dmobj.desc.dwValidData |= DMUS_OBJ_CATEGORY; - IStream_Read (pStm, This->dmobj.desc.wszCategory, Chunk.dwSize, NULL); - break; - } - case FOURCC_RIFF: { - static const LARGE_INTEGER zero = {0}; - struct chunk_entry chunk = {FOURCC_LIST, .size = Chunk.dwSize, .type = Chunk.fccID}; - - IStream_Seek(pStm, zero, STREAM_SEEK_CUR, &chunk.offset); - chunk.offset.QuadPart -= 12; - load_container(pStm, &chunk); - break; - } - case FOURCC_LIST: { - IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); - TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); - ListSize[0] = Chunk.dwSize - sizeof(FOURCC); - ListCount[0] = 0; - switch (Chunk.fccID) { - case DMUS_FOURCC_UNFO_LIST: { - TRACE_(dmfile)(": UNFO list\n"); - do { - IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); - ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; - TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); - switch (Chunk.fccID) { - /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes - (though strings seem to be valid unicode) */ - case mmioFOURCC('I','N','A','M'): - case DMUS_FOURCC_UNAM_CHUNK: { - TRACE_(dmfile)(": name chunk\n"); - This->dmobj.desc.dwValidData |= DMUS_OBJ_NAME; - IStream_Read (pStm, This->dmobj.desc.wszName, Chunk.dwSize, NULL); - break; - } - case mmioFOURCC('I','A','R','T'): - case DMUS_FOURCC_UART_CHUNK: { - TRACE_(dmfile)(": artist chunk (ignored)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - case mmioFOURCC('I','C','O','P'): - case DMUS_FOURCC_UCOP_CHUNK: { - TRACE_(dmfile)(": copyright chunk (ignored)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - case mmioFOURCC('I','S','B','J'): - case DMUS_FOURCC_USBJ_CHUNK: { - TRACE_(dmfile)(": subject chunk (ignored)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - case mmioFOURCC('I','C','M','T'): - case DMUS_FOURCC_UCMT_CHUNK: { - TRACE_(dmfile)(": comment chunk (ignored)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - default: { - TRACE_(dmfile)(": unknown sub-chunk (irrelevant & skipping)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - } - TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]); - } while (ListCount[0] < ListSize[0]); - break; - } - default: { - TRACE_(dmfile)(": unknown (skipping)\n"); - liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - } - break; - } - default: { - TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); - break; - } - } - TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize); - } while (StreamCount < StreamSize); - break; - } - default: { - TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); - liMove.QuadPart = StreamSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */ - return E_FAIL; - } - } - TRACE_(dmfile)(": reading finished\n"); - break; - } - default: { - TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); - liMove.QuadPart = Chunk.dwSize; - IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */ - return E_FAIL; - } - } - - return S_OK; + IDirectMusicScriptImpl *This = impl_from_IPersistStream(iface); + struct chunk_entry script = {0}; + struct chunk_entry chunk = {.parent = &script}; + HRESULT hr; + + TRACE("(%p, %p): Loading\n", This, stream); + + if (!stream) + return E_POINTER; + + if (stream_get_chunk(stream, &script) != S_OK || script.id != FOURCC_RIFF || + script.type != DMUS_FOURCC_SCRIPT_FORM) + { + WARN("Invalid chunk %s\n", debugstr_chunk(&script)); + return DMUS_E_UNSUPPORTED_STREAM; + } + if (FAILED(hr = dmobj_parsedescriptor(stream, &script, &This->dmobj.desc, DMUS_OBJ_OBJECT)) + || FAILED(hr = stream_reset_chunk_data(stream, &script))) + return hr; + + while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) + { + switch (MAKE_IDTYPE(chunk.id, chunk.type)) + { + case DMUS_FOURCC_GUID_CHUNK: + case DMUS_FOURCC_VERSION_CHUNK: + case MAKE_IDTYPE(FOURCC_LIST, DMUS_FOURCC_UNFO_LIST): + /* already parsed/ignored by dmobj_parsedescriptor */ + break; + case DMUS_FOURCC_SCRIPT_CHUNK: + hr = stream_chunk_get_data(stream, &chunk, &This->header, sizeof(This->header)); + if (SUCCEEDED(hr)) + TRACE("header dwFlags: %#lx\n", This->header.dwFlags); + break; + case DMUS_FOURCC_SCRIPTVERSION_CHUNK: + hr = stream_chunk_get_data(stream, &chunk, &This->version, sizeof(This->version)); + if (SUCCEEDED(hr)) + TRACE("version: %#lx.%#lx\n", This->version.dwVersionMS, This->version.dwVersionLS); + break; + case MAKE_IDTYPE(FOURCC_RIFF, DMUS_FOURCC_CONTAINER_FORM): + hr = load_container(stream, &chunk); + break; + case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK: + if (This->lang) + free(This->lang); + This->lang = calloc(1, chunk.size); + hr = stream_chunk_get_wstr(stream, &chunk, This->lang, chunk.size); + if (SUCCEEDED(hr)) + TRACE("language: %s\n", debugstr_w(This->lang)); + break; + case DMUS_FOURCC_SCRIPTSOURCE_CHUNK: + if (This->source) + free(This->source); + This->source = calloc(1, chunk.size); + hr = stream_chunk_get_wstr(stream, &chunk, This->source, chunk.size); + if (SUCCEEDED(hr)) + TRACE("source: %s\n", debugstr_w(This->source)); + break; + case MAKE_IDTYPE(FOURCC_LIST, DMUS_FOURCC_REF_LIST): + FIXME("Loading the script source from file not implement."); + break; + default: + WARN("Ignoring chunk %s\n", debugstr_chunk(&chunk)); + break; + } + + if (FAILED(hr)) + return hr; + } + + return S_OK; }
static const IPersistStreamVtbl persiststream_vtbl = { @@ -466,7 +349,7 @@ static const IPersistStreamVtbl persiststream_vtbl = { dmobj_IPersistStream_Release, unimpl_IPersistStream_GetClassID, unimpl_IPersistStream_IsDirty, - IPersistStreamImpl_Load, + script_persist_stream_Load, unimpl_IPersistStream_Save, unimpl_IPersistStream_GetSizeMax };