{
xmlnode node;
const struct IXMLDOMDocument2Vtbl *lpVtbl;
- const struct IPersistStreamVtbl *lpvtblIPersistStream;
+ const struct IPersistStreamInitVtbl *lpvtblIPersistStreamInit;
const struct IObjectWithSiteVtbl *lpvtblIObjectWithSite;
const struct IObjectSafetyVtbl *lpvtblIObjectSafety;
const struct ISupportErrorInfoVtbl *lpvtblISupportErrorInfo;
return priv;
}
-static xmlDocPtr doparse( char *ptr, int len )
+/* links a "<?xml" node as a first child */
+void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node)
{
+ assert(doc != NULL);
+ if (doc->standalone != -1) xmlAddPrevSibling( doc->children, node );
+}
+
+/* unlinks a first "<?xml" child if it was created */
+xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
+{
+ xmlNodePtr node;
+
+ assert(doc != NULL);
+
+ if (doc->standalone != -1)
+ {
+ node = doc->children;
+ xmlUnlinkNode( node );
+ }
+ else
+ node = NULL;
+
+ return node;
+}
+
+static xmlDocPtr doparse( char *ptr, int len, const char *encoding )
+{
+ xmlDocPtr doc;
+
#ifdef HAVE_XMLREADMEMORY
/*
* use xmlReadMemory if possible so we can suppress
* writing errors to stderr
*/
- return xmlReadMemory( ptr, len, NULL, NULL,
- XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
+ doc = xmlReadMemory( ptr, len, NULL, encoding,
+ XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
#else
- return xmlParseMemory( ptr, len );
+ doc = xmlParseMemory( ptr, len );
#endif
+
+ /* create first child as a <?xml...?> */
+ if (doc && doc->standalone != -1)
+ {
+ xmlNodePtr node;
+ char buff[30];
+ xmlChar *xmlbuff = (xmlChar*)buff;
+
+ node = xmlNewDocPI( doc, (xmlChar*)"xml", NULL );
+
+ /* version attribute can't be omitted */
+ sprintf(buff, "version=\"%s\"", doc->version ? (char*)doc->version : "1.0");
+ xmlNodeAddContent( node, xmlbuff );
+
+ if (doc->encoding)
+ {
+ sprintf(buff, " encoding=\"%s\"", doc->encoding);
+ xmlNodeAddContent( node, xmlbuff );
+ }
+
+ if (doc->standalone != -2)
+ {
+ sprintf(buff, " standalone=\"%s\"", doc->standalone == 0 ? "no" : "yes");
+ xmlNodeAddContent( node, xmlbuff );
+ }
+
+ xmldoc_link_xmldecl( doc, node );
+ }
+
+ return doc;
}
LONG xmldoc_add_ref(xmlDocPtr doc)
{
LONG ref = InterlockedIncrement(&priv_from_xmlDocPtr(doc)->refs);
- TRACE("%d\n", ref);
+ TRACE("(%p)->(%d)\n", doc, ref);
return ref;
}
{
xmldoc_priv *priv = priv_from_xmlDocPtr(doc);
LONG ref = InterlockedDecrement(&priv->refs);
- TRACE("%d\n", ref);
+ TRACE("(%p)->(%d)\n", doc, ref);
if(ref == 0)
{
orphan_entry *orphan, *orphan2;
return (xmlDocPtr)This->node.node;
}
-static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)
+static inline domdoc *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
{
- return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStream));
+ return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc, lpvtblIPersistStreamInit));
}
static inline domdoc *impl_from_IObjectWithSite(IObjectWithSite *iface)
}
/************************************************************************
- * xmldoc implementation of IPersistStream.
+ * domdoc implementation of IPersistStream.
*/
-static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(
- IPersistStream *iface, REFIID riid, LPVOID *ppvObj)
+static HRESULT WINAPI domdoc_IPersistStreamInit_QueryInterface(
+ IPersistStreamInit *iface, REFIID riid, void **ppvObj)
{
- domdoc *this = impl_from_IPersistStream(iface);
- return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
+ domdoc *this = impl_from_IPersistStreamInit(iface);
+ return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)this, riid, ppvObj);
}
-static ULONG WINAPI xmldoc_IPersistStream_AddRef(
- IPersistStream *iface)
+static ULONG WINAPI domdoc_IPersistStreamInit_AddRef(
+ IPersistStreamInit *iface)
{
- domdoc *this = impl_from_IPersistStream(iface);
- return IXMLDocument_AddRef((IXMLDocument *)this);
+ domdoc *this = impl_from_IPersistStreamInit(iface);
+ return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)this);
}
-static ULONG WINAPI xmldoc_IPersistStream_Release(
- IPersistStream *iface)
+static ULONG WINAPI domdoc_IPersistStreamInit_Release(
+ IPersistStreamInit *iface)
{
- domdoc *this = impl_from_IPersistStream(iface);
- return IXMLDocument_Release((IXMLDocument *)this);
+ domdoc *this = impl_from_IPersistStreamInit(iface);
+ return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)this);
}
-static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(
- IPersistStream *iface, CLSID *classid)
+static HRESULT WINAPI domdoc_IPersistStreamInit_GetClassID(
+ IPersistStreamInit *iface, CLSID *classid)
{
TRACE("(%p,%p): stub!\n", iface, classid);
return S_OK;
}
-static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(
- IPersistStream *iface)
+static HRESULT WINAPI domdoc_IPersistStreamInit_IsDirty(
+ IPersistStreamInit *iface)
{
- domdoc *This = impl_from_IPersistStream(iface);
-
+ domdoc *This = impl_from_IPersistStreamInit(iface);
FIXME("(%p): stub!\n", This);
-
return S_FALSE;
}
-static HRESULT WINAPI xmldoc_IPersistStream_Load(
- IPersistStream *iface, LPSTREAM pStm)
+static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
+ IPersistStreamInit *iface, LPSTREAM pStm)
{
- domdoc *This = impl_from_IPersistStream(iface);
+ domdoc *This = impl_from_IPersistStreamInit(iface);
HRESULT hr;
HGLOBAL hglobal;
DWORD read, written, len;
len = GlobalSize(hglobal);
ptr = GlobalLock(hglobal);
if (len != 0)
- xmldoc = parse_xml(ptr, len);
+ xmldoc = doparse(ptr, len, NULL);
GlobalUnlock(hglobal);
if (!xmldoc)
return attach_xmldoc( &This->node, xmldoc );
}
-static HRESULT WINAPI xmldoc_IPersistStream_Save(
- IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)
+static HRESULT WINAPI domdoc_IPersistStreamInit_Save(
+ IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty)
{
- domdoc *This = impl_from_IPersistStream(iface);
+ domdoc *This = impl_from_IPersistStreamInit(iface);
HRESULT hr;
BSTR xmlString;
return hr;
}
-static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(
- IPersistStream *iface, ULARGE_INTEGER *pcbSize)
+static HRESULT WINAPI domdoc_IPersistStreamInit_GetSizeMax(
+ IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize)
{
- domdoc *This = impl_from_IPersistStream(iface);
+ domdoc *This = impl_from_IPersistStreamInit(iface);
TRACE("(%p)->(%p): stub!\n", This, pcbSize);
return E_NOTIMPL;
}
-static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =
+static HRESULT WINAPI domdoc_IPersistStreamInit_InitNew(
+ IPersistStreamInit *iface)
{
- xmldoc_IPersistStream_QueryInterface,
- xmldoc_IPersistStream_AddRef,
- xmldoc_IPersistStream_Release,
- xmldoc_IPersistStream_GetClassID,
- xmldoc_IPersistStream_IsDirty,
- xmldoc_IPersistStream_Load,
- xmldoc_IPersistStream_Save,
- xmldoc_IPersistStream_GetSizeMax,
+ domdoc *This = impl_from_IPersistStreamInit(iface);
+ TRACE("(%p)\n", This);
+ return S_OK;
+}
+
+static const IPersistStreamInitVtbl xmldoc_IPersistStreamInit_VTable =
+{
+ domdoc_IPersistStreamInit_QueryInterface,
+ domdoc_IPersistStreamInit_AddRef,
+ domdoc_IPersistStreamInit_Release,
+ domdoc_IPersistStreamInit_GetClassID,
+ domdoc_IPersistStreamInit_IsDirty,
+ domdoc_IPersistStreamInit_Load,
+ domdoc_IPersistStreamInit_Save,
+ domdoc_IPersistStreamInit_GetSizeMax,
+ domdoc_IPersistStreamInit_InitNew
};
/* ISupportErrorInfo interface */
REFIID riid, void** ppvObj )
{
domdoc *This = impl_from_ISupportErrorInfo(iface);
- return IXMLDocument_QueryInterface((IXMLDocument *)This, riid, ppvObj);
+ return IXMLDOMDocument2_QueryInterface((IXMLDOMDocument2 *)This, riid, ppvObj);
}
static ULONG WINAPI support_error_AddRef(
ISupportErrorInfo *iface )
{
domdoc *This = impl_from_ISupportErrorInfo(iface);
- return IXMLDocument_AddRef((IXMLDocument *)This);
+ return IXMLDOMDocument2_AddRef((IXMLDOMDocument2 *)This);
}
static ULONG WINAPI support_error_Release(
ISupportErrorInfo *iface )
{
domdoc *This = impl_from_ISupportErrorInfo(iface);
- return IXMLDocument_Release((IXMLDocument *)This);
+ return IXMLDOMDocument2_Release((IXMLDOMDocument2 *)This);
}
static HRESULT WINAPI support_error_InterfaceSupportsErrorInfo(
{
*ppvObject = IXMLDOMNode_from_impl(&This->node);
}
- else if (IsEqualGUID(&IID_IPersistStream, riid))
+ else if (IsEqualGUID(&IID_IPersistStream, riid) ||
+ IsEqualGUID(&IID_IPersistStreamInit, riid))
{
- *ppvObject = &(This->lpvtblIPersistStream);
+ *ppvObject = &(This->lpvtblIPersistStreamInit);
}
else if (IsEqualGUID(&IID_IObjectWithSite, riid))
{
V_VT(&type) = VT_I1;
V_I1(&type) = NODE_ELEMENT;
- hr = IXMLDOMDocument_createNode(iface, type, tagname, NULL, &node);
+ hr = IXMLDOMDocument2_createNode(iface, type, tagname, NULL, &node);
if (hr == S_OK)
{
IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void**)element);
V_VT(&type) = VT_I1;
V_I1(&type) = NODE_DOCUMENT_FRAGMENT;
- hr = IXMLDOMDocument_createNode(iface, type, NULL, NULL, &node);
+ hr = IXMLDOMDocument2_createNode(iface, type, NULL, NULL, &node);
if (hr == S_OK)
{
IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocumentFragment, (void**)frag);
V_VT(&type) = VT_I1;
V_I1(&type) = NODE_ATTRIBUTE;
- hr = IXMLDOMDocument_createNode(iface, type, name, NULL, &node);
+ hr = IXMLDOMDocument2_createNode(iface, type, name, NULL, &node);
if (hr == S_OK)
{
IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMAttribute, (void**)attribute);
case NODE_ATTRIBUTE:
case NODE_ENTITY_REFERENCE:
case NODE_PROCESSING_INSTRUCTION:
- if (!name || SysStringLen(name) == 0) return E_FAIL;
+ if (!name || *name == 0) return E_FAIL;
default:
break;
}
domdoc *This = obj;
xmlDocPtr xmldoc;
- xmldoc = doparse( ptr, len );
+ xmldoc = doparse( ptr, len, NULL );
if(xmldoc) {
xmldoc->_private = create_priv();
return attach_xmldoc(&This->node, xmldoc);
hr = IUnknown_QueryInterface(iface, &IID_IPersistStream, (void**)&pDocStream);
if(hr == S_OK)
{
- hr = xmldoc_IPersistStream_Load(pDocStream, pStream);
+ hr = IPersistStream_Load(pDocStream, pStream);
IStream_Release(pStream);
if(hr == S_OK)
{
*isSuccessful = VARIANT_TRUE;
- TRACE("Using ID_IStream to load Document\n");
+ TRACE("Using IStream to load Document\n");
return S_OK;
}
else
{
*isSuccessful = VARIANT_FALSE;
- if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
+ if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
{
- xmldoc = doparse( str, len );
+ xmldoc = doparse( str, len, "UTF-8" );
heap_free( str );
if ( !xmldoc )
This->error = E_FAIL;
domdoc *This = impl_from_IXMLDOMDocument2( iface );
HANDLE handle;
xmlSaveCtxtPtr ctx;
+ xmlNodePtr xmldecl;
HRESULT ret = S_OK;
TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
if(V_VT(&destination) == VT_UNKNOWN)
{
IUnknown *pUnk = V_UNKNOWN(&destination);
- IXMLDOMDocument *pDocument;
+ IXMLDOMDocument2 *pDocument;
- ret = IXMLDOMDocument_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
+ ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument2, (void**)&pDocument);
if(ret == S_OK)
{
BSTR bXML;
VARIANT_BOOL bSuccessful;
- ret = IXMLDOMDocument_get_xml(iface, &bXML);
+ ret = IXMLDOMDocument2_get_xml(iface, &bXML);
if(ret == S_OK)
{
- ret = IXMLDOMDocument_loadXML(pDocument, bXML, &bSuccessful);
+ ret = IXMLDOMDocument2_loadXML(pDocument, bXML, &bSuccessful);
SysFreeString(bXML);
}
- IXMLDOMDocument_Release(pDocument);
+ IXMLDOMDocument2_Release(pDocument);
}
TRACE("ret %d\n", ret);
return S_FALSE;
}
+ xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
+ xmldoc_link_xmldecl(get_doc(This), xmldecl);
+
/* will close file through close callback */
xmlSaveClose(ctx);
return E_OUTOFMEMORY;
doc->lpVtbl = &domdoc_vtbl;
- doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
+ doc->lpvtblIPersistStreamInit = &xmldoc_IPersistStreamInit_VTable;
doc->lpvtblIObjectWithSite = &domdocObjectSite;
doc->lpvtblIObjectSafety = &domdocObjectSafetyVtbl;
doc->lpvtblISupportErrorInfo = &support_error_vtbl;