riched20: Initial support for word break callback procedures.
[wine] / dlls / msxml3 / nodemap.c
1 /*
2  *    Node map implementation
3  *
4  * Copyright 2005 Mike McCormack
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #define COBJMACROS
24
25 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31 #include "msxml2.h"
32
33 #include "msxml_private.h"
34
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
38
39 #ifdef HAVE_LIBXML2
40
41 typedef struct _xmlnodemap
42 {
43     const struct IXMLDOMNamedNodeMapVtbl *lpVtbl;
44     LONG ref;
45     IXMLDOMNode *node;
46 } xmlnodemap;
47
48 static inline xmlnodemap *impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap *iface )
49 {
50     return (xmlnodemap *)((char*)iface - FIELD_OFFSET(xmlnodemap, lpVtbl));
51 }
52
53 static HRESULT WINAPI xmlnodemap_QueryInterface(
54     IXMLDOMNamedNodeMap *iface,
55     REFIID riid, void** ppvObject )
56 {
57     TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject);
58
59     if( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
60         IsEqualGUID( riid, &IID_IUnknown ) ||
61         IsEqualGUID( riid, &IID_IDispatch ) ||
62         IsEqualGUID( riid, &IID_IXMLDOMNode ) )
63     {
64         *ppvObject = iface;
65     }
66     else
67         return E_NOINTERFACE;
68
69     IXMLDOMElement_AddRef( iface );
70
71     return S_OK;
72 }
73
74 static ULONG WINAPI xmlnodemap_AddRef(
75     IXMLDOMNamedNodeMap *iface )
76 {
77     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
78     return InterlockedIncrement( &This->ref );
79 }
80
81 static ULONG WINAPI xmlnodemap_Release(
82     IXMLDOMNamedNodeMap *iface )
83 {
84     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
85     ULONG ref;
86
87     ref = InterlockedDecrement( &This->ref );
88     if ( ref == 0 )
89     {
90         IXMLDOMNode_Release( This->node );
91         HeapFree( GetProcessHeap(), 0, This );
92     }
93
94     return ref;
95 }
96
97 static HRESULT WINAPI xmlnodemap_GetTypeInfoCount(
98     IXMLDOMNamedNodeMap *iface,
99     UINT* pctinfo )
100 {
101     FIXME("\n");
102     return E_NOTIMPL;
103 }
104
105 static HRESULT WINAPI xmlnodemap_GetTypeInfo(
106     IXMLDOMNamedNodeMap *iface,
107     UINT iTInfo, LCID lcid,
108     ITypeInfo** ppTInfo )
109 {
110     FIXME("\n");
111     return E_NOTIMPL;
112 }
113
114 static HRESULT WINAPI xmlnodemap_GetIDsOfNames(
115     IXMLDOMNamedNodeMap *iface,
116     REFIID riid, LPOLESTR* rgszNames,
117     UINT cNames, LCID lcid, DISPID* rgDispId )
118 {
119     FIXME("\n");
120     return E_NOTIMPL;
121 }
122
123 static HRESULT WINAPI xmlnodemap_Invoke(
124     IXMLDOMNamedNodeMap *iface,
125     DISPID dispIdMember, REFIID riid, LCID lcid,
126     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
127     EXCEPINFO* pExcepInfo, UINT* puArgErr )
128 {
129     FIXME("\n");
130     return E_NOTIMPL;
131 }
132
133 xmlChar *xmlChar_from_wchar( LPWSTR str )
134 {
135     DWORD len;
136     xmlChar *xmlstr;
137
138     len = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
139     xmlstr = (xmlChar*) HeapAlloc( GetProcessHeap(), 0, len );
140     if ( xmlstr )
141         WideCharToMultiByte( CP_UTF8, 0, str, -1, (LPSTR) xmlstr, len, NULL, NULL );
142     return xmlstr;
143 }
144
145 static HRESULT WINAPI xmlnodemap_getNamedItem(
146     IXMLDOMNamedNodeMap *iface,
147     BSTR name,
148     IXMLDOMNode** namedItem)
149 {
150     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
151     xmlChar *element_name;
152     xmlAttrPtr attr;
153     xmlNodePtr node;
154
155     TRACE("%p %s\n", This, debugstr_w(name) );
156
157     node = xmlNodePtr_from_domnode( This->node, 0 );
158     if ( !node )
159         return E_FAIL;
160
161     element_name = xmlChar_from_wchar( name );
162     attr = xmlHasNsProp( node, element_name, NULL );
163     HeapFree( GetProcessHeap(), 0, element_name );
164
165     if ( !attr )
166         return E_FAIL;
167
168     *namedItem = create_node( (xmlNodePtr) attr );
169
170     return S_OK;
171 }
172
173 static HRESULT WINAPI xmlnodemap_setNamedItem(
174     IXMLDOMNamedNodeMap *iface,
175     IXMLDOMNode* newItem,
176     IXMLDOMNode** namedItem)
177 {
178     FIXME("\n");
179     return E_NOTIMPL;
180 }
181
182 static HRESULT WINAPI xmlnodemap_removeNamedItem(
183     IXMLDOMNamedNodeMap *iface,
184     BSTR name,
185     IXMLDOMNode** namedItem)
186 {
187     FIXME("\n");
188     return E_NOTIMPL;
189 }
190
191 static HRESULT WINAPI xmlnodemap_get_item(
192     IXMLDOMNamedNodeMap *iface,
193     long index,
194     IXMLDOMNode** listItem)
195 {
196     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
197     xmlNodePtr node;
198     xmlAttrPtr curr;
199     long attrIndex;
200
201     TRACE("%p %ld\n", This, index);
202
203     *listItem = NULL;
204
205     if (index < 0)
206         return S_FALSE;
207
208     node = xmlNodePtr_from_domnode( This->node, 0 );
209     curr = node->properties;
210
211     for (attrIndex = 0; attrIndex < index; attrIndex++) {
212         if (curr->next == NULL)
213             return S_FALSE;
214         else
215             curr = curr->next;
216     }
217     
218     *listItem = create_node( (xmlNodePtr) curr );
219
220     return S_OK;
221 }
222
223 static HRESULT WINAPI xmlnodemap_get_length(
224     IXMLDOMNamedNodeMap *iface,
225     long* listLength)
226 {
227     xmlNodePtr node;
228     xmlAttrPtr first;
229     xmlAttrPtr curr;
230     long attrCount;
231
232     xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
233
234     TRACE("%p\n", This);
235
236     node = xmlNodePtr_from_domnode( This->node, 0 );
237     if ( !node )
238         return E_FAIL;
239
240     first = node->properties;
241     if (first == NULL) {
242         *listLength = 0;
243         return S_OK;
244     }
245
246     curr = first;
247     attrCount = 1;
248     while (curr->next != NULL) {
249         attrCount++;
250         curr = curr->next;
251     }
252     *listLength = attrCount;
253  
254     return S_OK;
255 }
256
257 static HRESULT WINAPI xmlnodemap_getQualifiedItem(
258     IXMLDOMNamedNodeMap *iface,
259     BSTR baseName,
260     BSTR namespaceURI,
261     IXMLDOMNode** qualifiedItem)
262 {
263     FIXME("\n");
264     return E_NOTIMPL;
265 }
266
267 static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
268     IXMLDOMNamedNodeMap *iface,
269     BSTR baseName,
270     BSTR namespaceURI,
271     IXMLDOMNode** qualifiedItem)
272 {
273     FIXME("\n");
274     return E_NOTIMPL;
275 }
276
277 static HRESULT WINAPI xmlnodemap_nextNode(
278     IXMLDOMNamedNodeMap *iface,
279     IXMLDOMNode** nextItem)
280 {
281     FIXME("\n");
282     return E_NOTIMPL;
283 }
284
285 static HRESULT WINAPI xmlnodemap_reset(
286     IXMLDOMNamedNodeMap *iface )
287 {
288     FIXME("\n");
289     return E_NOTIMPL;
290 }
291
292 static HRESULT WINAPI xmlnodemap__newEnum(
293     IXMLDOMNamedNodeMap *iface,
294     IUnknown** ppUnk)
295 {
296     FIXME("\n");
297     return E_NOTIMPL;
298 }
299
300 static const struct IXMLDOMNamedNodeMapVtbl xmlnodemap_vtbl =
301 {
302     xmlnodemap_QueryInterface,
303     xmlnodemap_AddRef,
304     xmlnodemap_Release,
305     xmlnodemap_GetTypeInfoCount,
306     xmlnodemap_GetTypeInfo,
307     xmlnodemap_GetIDsOfNames,
308     xmlnodemap_Invoke,
309     xmlnodemap_getNamedItem,
310     xmlnodemap_setNamedItem,
311     xmlnodemap_removeNamedItem,
312     xmlnodemap_get_item,
313     xmlnodemap_get_length,
314     xmlnodemap_getQualifiedItem,
315     xmlnodemap_removeQualifiedItem,
316     xmlnodemap_nextNode,
317     xmlnodemap_reset,
318     xmlnodemap__newEnum,
319 };
320
321 IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
322 {
323     xmlnodemap *nodemap;
324
325     nodemap = HeapAlloc( GetProcessHeap(), 0, sizeof *nodemap );
326     if ( !nodemap )
327         return NULL;
328
329     nodemap->lpVtbl = &xmlnodemap_vtbl;
330     nodemap->node = node;
331     nodemap->ref = 1;
332
333     IXMLDOMNode_AddRef( node );
334     /* Since we AddRef a node here, we don't need to call xmldoc_add_ref() */
335
336     return (IXMLDOMNamedNodeMap*) &nodemap->lpVtbl;
337 }
338
339 #endif