ReactOS  0.4.15-dev-1377-ga59cecd
dictionary.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Alistair Leslie-Hughes
3  * Copyright 2015 Nikolay Sivov for CodeWeavers
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 #define COBJMACROS
20 
21 #ifdef __REACTOS__
22 #include <wine/config.h>
23 #include <wine/port.h>
24 #endif
25 #include <stdarg.h>
26 #include <math.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "ole2.h"
31 #include "olectl.h"
32 #include "dispex.h"
33 #include "scrrun.h"
34 #include "scrrun_private.h"
35 
36 #include "wine/debug.h"
37 #include "wine/heap.h"
38 #include "wine/list.h"
39 
41 
42 #define BUCKET_COUNT 509
43 #define DICT_HASH_MOD 1201
44 
45 /* Implementation details
46 
47  Dictionary contains one list that links all pairs, this way
48  order in which they were added is preserved. Each bucket has
49  its own list to hold all pairs in this bucket. Initially all
50  bucket lists are zeroed and we init them once we about to add
51  first pair.
52 
53  When pair is removed it's unlinked from both lists; if it was
54  a last pair in a bucket list it stays empty in initialized state.
55 
56  Preserving pair order is important for enumeration, so far testing
57  indicates that pairs are not reordered basing on hash value.
58  */
59 
60 struct keyitem_pair {
61  struct list entry;
62  struct list bucket;
66 };
67 
68 typedef struct
69 {
71  IDictionary IDictionary_iface;
73 
76  struct list pairs;
77  struct list buckets[BUCKET_COUNT];
78  struct list notifier;
79 } dictionary;
80 
84 
86  struct list *cur;
87  struct list notify;
88 };
89 
90 static inline dictionary *impl_from_IDictionary(IDictionary *iface)
91 {
92  return CONTAINING_RECORD(iface, dictionary, IDictionary_iface);
93 }
94 
96 {
98 }
99 
100 static inline struct list *get_bucket_head(dictionary *dict, DWORD hash)
101 {
102  return &dict->buckets[hash % BUCKET_COUNT];
103 }
104 
105 static inline BOOL is_string_key(const VARIANT *key)
106 {
107  return V_VT(key) == VT_BSTR || V_VT(key) == (VT_BSTR|VT_BYREF);
108 }
109 
110 /* Only for VT_BSTR or VT_BSTR|VT_BYREF types */
111 static inline WCHAR *get_key_strptr(const VARIANT *key)
112 {
113  if (V_VT(key) == VT_BSTR)
114  return V_BSTR(key);
115 
116  if (V_BSTRREF(key))
117  return *V_BSTRREF(key);
118 
119  return NULL;
120 }
121 
122 /* should be used only when both keys are of string type, it's not checked */
123 static inline int strcmp_key(const dictionary *dict, const VARIANT *key1, const VARIANT *key2)
124 {
125  const WCHAR *str1, *str2;
126 
127  str1 = get_key_strptr(key1);
128  str2 = get_key_strptr(key2);
129  return dict->method == BinaryCompare ? wcscmp(str1, str2) : wcsicmp(str1, str2);
130 }
131 
132 static BOOL is_matching_key(const dictionary *dict, const struct keyitem_pair *pair, const VARIANT *key, DWORD hash)
133 {
134  if (is_string_key(key) && is_string_key(&pair->key)) {
135  if (hash != pair->hash)
136  return FALSE;
137 
138  return strcmp_key(dict, key, &pair->key) == 0;
139  }
140 
141  if ((is_string_key(key) && !is_string_key(&pair->key)) ||
142  (!is_string_key(key) && is_string_key(&pair->key)))
143  return FALSE;
144 
145  /* for numeric keys only check hash */
146  return hash == pair->hash;
147 }
148 
150 {
151  struct keyitem_pair *pair;
152  struct list *head, *entry;
153  VARIANT hash;
154  HRESULT hr;
155 
156  hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash);
157  if (FAILED(hr))
158  return NULL;
159 
160  head = get_bucket_head(dict, V_I4(&hash));
161  if (!head->next || list_empty(head))
162  return NULL;
163 
164  entry = list_head(head);
165  do {
166  pair = LIST_ENTRY(entry, struct keyitem_pair, bucket);
167  if (is_matching_key(dict, pair, key, V_I4(&hash))) return pair;
168  } while ((entry = list_next(head, entry)));
169 
170  return NULL;
171 }
172 
174 {
175  struct keyitem_pair *pair;
176  struct list *head;
177  VARIANT hash;
178  HRESULT hr;
179 
180  hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash);
181  if (FAILED(hr))
182  return hr;
183 
184  pair = heap_alloc(sizeof(*pair));
185  if (!pair)
186  return E_OUTOFMEMORY;
187 
188  pair->hash = V_I4(&hash);
189  VariantInit(&pair->key);
190  VariantInit(&pair->item);
191 
192  hr = VariantCopyInd(&pair->key, key);
193  if (FAILED(hr))
194  goto failed;
195 
196  hr = VariantCopyInd(&pair->item, item);
197  if (FAILED(hr))
198  goto failed;
199 
200  head = get_bucket_head(dict, pair->hash);
201  if (!head->next)
202  /* this only happens once per bucket */
203  list_init(head);
204 
205  /* link to bucket list and to full list */
206  list_add_tail(head, &pair->bucket);
207  list_add_tail(&dict->pairs, &pair->entry);
208  dict->count++;
209  return S_OK;
210 
211 failed:
212  VariantClear(&pair->key);
213  VariantClear(&pair->item);
214  heap_free(pair);
215  return hr;
216 }
217 
218 static void free_keyitem_pair(struct keyitem_pair *pair)
219 {
220  VariantClear(&pair->key);
221  VariantClear(&pair->item);
222  heap_free(pair);
223 }
224 
226 {
228 
229  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
230 
231  if (IsEqualIID(riid, &IID_IEnumVARIANT) || IsEqualIID(riid, &IID_IUnknown)) {
232  *obj = iface;
233  IEnumVARIANT_AddRef(iface);
234  return S_OK;
235  }
236  else {
237  WARN("interface not supported %s\n", debugstr_guid(riid));
238  *obj = NULL;
239  return E_NOINTERFACE;
240  }
241 }
242 
244 {
247  TRACE("(%p)->(%u)\n", This, ref);
248  return ref;
249 }
250 
252 {
255 
256  TRACE("(%p)->(%u)\n", This, ref);
257 
258  if (!ref) {
259  list_remove(&This->notify);
260  IDictionary_Release(&This->dict->IDictionary_iface);
261  heap_free(This);
262  }
263 
264  return ref;
265 }
266 
268 {
270  struct keyitem_pair *pair;
271  ULONG i = 0;
272 
273  TRACE("(%p)->(%u %p %p)\n", This, count, keys, fetched);
274 
275  if (fetched)
276  *fetched = 0;
277 
278  if (!count)
279  return S_OK;
280 
281  while (This->cur && i < count) {
282  pair = LIST_ENTRY(This->cur, struct keyitem_pair, entry);
283  VariantCopy(&keys[i], &pair->key);
284  This->cur = list_next(&This->dict->pairs, This->cur);
285  i++;
286  }
287 
288  if (fetched)
289  *fetched = i;
290 
291  return i < count ? S_FALSE : S_OK;
292 }
293 
295 {
297 
298  TRACE("(%p)->(%u)\n", This, count);
299 
300  if (!count)
301  return S_OK;
302 
303  if (!This->cur)
304  return S_FALSE;
305 
306  while (count--) {
307  This->cur = list_next(&This->dict->pairs, This->cur);
308  if (!This->cur) break;
309  }
310 
311  return count == 0 ? S_OK : S_FALSE;
312 }
313 
315 {
317 
318  TRACE("(%p)\n", This);
319 
320  This->cur = list_head(&This->dict->pairs);
321  return S_OK;
322 }
323 
325 
327 {
329  TRACE("(%p)->(%p)\n", This, cloned);
330  return create_dict_enum(This->dict, (IUnknown**)cloned);
331 }
332 
333 static const IEnumVARIANTVtbl dictenumvtbl = {
341 };
342 
344 {
345  struct dictionary_enum *This;
346 
347  *ret = NULL;
348 
349  This = heap_alloc(sizeof(*This));
350  if (!This)
351  return E_OUTOFMEMORY;
352 
353  This->IEnumVARIANT_iface.lpVtbl = &dictenumvtbl;
354  This->ref = 1;
355  This->cur = list_head(&dict->pairs);
356  list_add_tail(&dict->notifier, &This->notify);
357  This->dict = dict;
358  IDictionary_AddRef(&dict->IDictionary_iface);
359 
360  *ret = (IUnknown*)&This->IEnumVARIANT_iface;
361  return S_OK;
362 }
363 
364 static void notify_remove_pair(struct list *notifier, struct list *pair)
365 {
366  struct dictionary_enum *dict_enum;
367  struct list *cur;
368 
369  LIST_FOR_EACH(cur, notifier) {
370  dict_enum = LIST_ENTRY(cur, struct dictionary_enum, notify);
371  if (!pair)
372  dict_enum->cur = list_head(&dict_enum->dict->pairs);
373  else if (dict_enum->cur == pair) {
374  dict_enum->cur = list_next(&dict_enum->dict->pairs, dict_enum->cur);
375  }
376  }
377 }
378 
379 static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj)
380 {
382  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
383 
384  *obj = NULL;
385 
386  if(IsEqualIID(riid, &IID_IUnknown) ||
388  IsEqualIID(riid, &IID_IDictionary))
389  {
390  *obj = &This->IDictionary_iface;
391  }
393  {
394  *obj = &This->classinfo.IProvideClassInfo_iface;
395  }
396  else if ( IsEqualGUID( riid, &IID_IDispatchEx ))
397  {
398  TRACE("Interface IDispatchEx not supported - returning NULL\n");
399  *obj = NULL;
400  return E_NOINTERFACE;
401  }
402  else if ( IsEqualGUID( riid, &IID_IObjectWithSite ))
403  {
404  TRACE("Interface IObjectWithSite not supported - returning NULL\n");
405  *obj = NULL;
406  return E_NOINTERFACE;
407  }
408  else
409  {
410  WARN("interface %s not implemented\n", debugstr_guid(riid));
411  return E_NOINTERFACE;
412  }
413 
414  IUnknown_AddRef((IUnknown*)*obj);
415  return S_OK;
416 }
417 
418 static ULONG WINAPI dictionary_AddRef(IDictionary *iface)
419 {
422 
423  TRACE("(%p)->(%u)\n", This, ref);
424 
425  return ref;
426 }
427 
428 static ULONG WINAPI dictionary_Release(IDictionary *iface)
429 {
432 
433  TRACE("(%p)->(%u)\n", This, ref);
434 
435  if (!ref) {
436  IDictionary_RemoveAll(iface);
437  heap_free(This);
438  }
439 
440  return ref;
441 }
442 
443 static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pctinfo)
444 {
446 
447  TRACE("(%p)->(%p)\n", This, pctinfo);
448 
449  *pctinfo = 1;
450  return S_OK;
451 }
452 
453 static HRESULT WINAPI dictionary_GetTypeInfo(IDictionary *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
454 {
456 
457  TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
458  return get_typeinfo(IDictionary_tid, ppTInfo);
459 }
460 
461 static HRESULT WINAPI dictionary_GetIDsOfNames(IDictionary *iface, REFIID riid, LPOLESTR *rgszNames,
462  UINT cNames, LCID lcid, DISPID *rgDispId)
463 {
466  HRESULT hr;
467 
468  TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
469 
471  if(SUCCEEDED(hr))
472  {
473  hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
474  ITypeInfo_Release(typeinfo);
475  }
476 
477  return hr;
478 }
479 
480 static HRESULT WINAPI dictionary_Invoke(IDictionary *iface, DISPID dispIdMember, REFIID riid,
481  LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
482  EXCEPINFO *pExcepInfo, UINT *puArgErr)
483 {
486  HRESULT hr;
487 
488  TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
489  lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
490 
492  if(SUCCEEDED(hr))
493  {
494  hr = ITypeInfo_Invoke(typeinfo, &This->IDictionary_iface, dispIdMember, wFlags,
495  pDispParams, pVarResult, pExcepInfo, puArgErr);
496  ITypeInfo_Release(typeinfo);
497  }
498 
499  return hr;
500 }
501 
502 static HRESULT WINAPI dictionary_putref_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem)
503 {
505 
506  FIXME("(%p)->(%p %p)\n", This, Key, pRetItem);
507 
508  return E_NOTIMPL;
509 }
510 
511 static HRESULT WINAPI dictionary_put_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
512 {
514  struct keyitem_pair *pair;
515 
516  TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(item));
517 
518  if ((pair = get_keyitem_pair(This, key)))
519  return VariantCopyInd(&pair->item, item);
520 
521  return IDictionary_Add(iface, key, item);
522 }
523 
524 static HRESULT WINAPI dictionary_get_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
525 {
527  struct keyitem_pair *pair;
528 
529  TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), item);
530 
531  if ((pair = get_keyitem_pair(This, key)))
532  VariantCopy(item, &pair->item);
533  else {
534  VariantInit(item);
535  return IDictionary_Add(iface, key, item);
536  }
537 
538  return S_OK;
539 }
540 
541 static HRESULT WINAPI dictionary_Add(IDictionary *iface, VARIANT *key, VARIANT *item)
542 {
544 
545  TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(item));
546 
547  if (get_keyitem_pair(This, key))
548  return CTL_E_KEY_ALREADY_EXISTS;
549 
550  return add_keyitem_pair(This, key, item);
551 }
552 
553 static HRESULT WINAPI dictionary_get_Count(IDictionary *iface, LONG *count)
554 {
556 
557  TRACE("(%p)->(%p)\n", This, count);
558 
559  *count = This->count;
560  return S_OK;
561 }
562 
563 static HRESULT WINAPI dictionary_Exists(IDictionary *iface, VARIANT *key, VARIANT_BOOL *exists)
564 {
566 
567  TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), exists);
568 
569  if (!exists)
571 
572  *exists = get_keyitem_pair(This, key) != NULL ? VARIANT_TRUE : VARIANT_FALSE;
573  return S_OK;
574 }
575 
576 static HRESULT WINAPI dictionary_Items(IDictionary *iface, VARIANT *items)
577 {
579  struct keyitem_pair *pair;
580  SAFEARRAYBOUND bound;
581  SAFEARRAY *sa;
582  VARIANT *v;
583  HRESULT hr;
584  LONG i;
585 
586  TRACE("(%p)->(%p)\n", This, items);
587 
588  if (!items)
589  return S_OK;
590 
591  bound.lLbound = 0;
592  bound.cElements = This->count;
593  sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
594  if (!sa)
595  return E_OUTOFMEMORY;
596 
597  hr = SafeArrayAccessData(sa, (void**)&v);
598  if (FAILED(hr)) {
600  return hr;
601  }
602 
603  i = 0;
604  LIST_FOR_EACH_ENTRY(pair, &This->pairs, struct keyitem_pair, entry) {
605  VariantCopy(&v[i], &pair->item);
606  i++;
607  }
609 
611  V_ARRAY(items) = sa;
612  return S_OK;
613 }
614 
615 static HRESULT WINAPI dictionary_put_Key(IDictionary *iface, VARIANT *key, VARIANT *newkey)
616 {
618  struct keyitem_pair *pair;
619  VARIANT empty;
620  HRESULT hr;
621 
622  TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(newkey));
623 
624  if ((pair = get_keyitem_pair(This, key))) {
625  /* found existing pair for a key, add new pair with new key
626  and old item and remove old pair after that */
627 
628  hr = IDictionary_Add(iface, newkey, &pair->item);
629  if (FAILED(hr))
630  return hr;
631 
632  return IDictionary_Remove(iface, key);
633  }
634 
635  VariantInit(&empty);
636  return IDictionary_Add(iface, newkey, &empty);
637 }
638 
639 static HRESULT WINAPI dictionary_Keys(IDictionary *iface, VARIANT *keys)
640 {
642  struct keyitem_pair *pair;
643  SAFEARRAYBOUND bound;
644  SAFEARRAY *sa;
645  VARIANT *v;
646  HRESULT hr;
647  LONG i;
648 
649  TRACE("(%p)->(%p)\n", This, keys);
650 
651  if (!keys)
652  return S_OK;
653 
654  bound.lLbound = 0;
655  bound.cElements = This->count;
656  sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
657  if (!sa)
658  return E_OUTOFMEMORY;
659 
660  hr = SafeArrayAccessData(sa, (void**)&v);
661  if (FAILED(hr)) {
663  return hr;
664  }
665 
666  i = 0;
667  LIST_FOR_EACH_ENTRY(pair, &This->pairs, struct keyitem_pair, entry) {
668  VariantCopy(&v[i], &pair->key);
669  i++;
670  }
672 
673  V_VT(keys) = VT_ARRAY|VT_VARIANT;
674  V_ARRAY(keys) = sa;
675  return S_OK;
676 }
677 
678 static HRESULT WINAPI dictionary_Remove(IDictionary *iface, VARIANT *key)
679 {
681  struct keyitem_pair *pair;
682 
683  TRACE("(%p)->(%s)\n", This, debugstr_variant(key));
684 
685  if (!(pair = get_keyitem_pair(This, key)))
686  return CTL_E_ELEMENT_NOT_FOUND;
687 
688  notify_remove_pair(&This->notifier, &pair->entry);
689  list_remove(&pair->entry);
690  list_remove(&pair->bucket);
691  This->count--;
692 
694  return S_OK;
695 }
696 
697 static HRESULT WINAPI dictionary_RemoveAll(IDictionary *iface)
698 {
700  struct keyitem_pair *pair, *pair2;
701 
702  TRACE("(%p)\n", This);
703 
704  if (This->count == 0)
705  return S_OK;
706 
707  notify_remove_pair(&This->notifier, NULL);
708  LIST_FOR_EACH_ENTRY_SAFE(pair, pair2, &This->pairs, struct keyitem_pair, entry) {
709  list_remove(&pair->entry);
710  list_remove(&pair->bucket);
712  }
713  This->count = 0;
714 
715  return S_OK;
716 }
717 
719 {
721 
722  TRACE("(%p)->(%d)\n", This, method);
723 
724  if (This->count)
726 
727  This->method = method;
728  return S_OK;
729 }
730 
732 {
734 
735  TRACE("(%p)->(%p)\n", This, method);
736 
737  *method = This->method;
738  return S_OK;
739 }
740 
741 static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ret)
742 {
744 
745  TRACE("(%p)->(%p)\n", This, ret);
746 
747  return create_dict_enum(This, ret);
748 }
749 
751 {
752  DWORD hash = 0;
753 
754  if (str) {
755  while (*str) {
756  WCHAR ch;
757 
758  ch = (method == TextCompare || method == DatabaseCompare) ? towlower(*str) : *str;
759 
760  hash += (hash << 4) + ch;
761  str++;
762  }
763  }
764 
765  return hash % DICT_HASH_MOD;
766 }
767 
769 {
770  return (*((DWORD*)&num)) % DICT_HASH_MOD;
771 }
772 
774 {
775  if (isinf(flt)) {
776  *hash = 0;
777  return S_OK;
778  }
779  else if (!isnan(flt)) {
780  *hash = get_num_hash(flt);
781  return S_OK;
782  }
783 
784  /* NaN case */
785  *hash = ~0u;
787 }
788 
789 static DWORD get_ptr_hash(void *ptr)
790 {
791  return PtrToUlong(ptr) % DICT_HASH_MOD;
792 }
793 
795 {
797 
798  TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), hash);
799 
800  V_VT(hash) = VT_I4;
801  switch (V_VT(key))
802  {
803  case VT_BSTR|VT_BYREF:
804  case VT_BSTR:
806  break;
807  case VT_UI1|VT_BYREF:
808  case VT_UI1:
810  break;
811  case VT_I2|VT_BYREF:
812  case VT_I2:
814  break;
815  case VT_I4|VT_BYREF:
816  case VT_I4:
818  break;
819  case VT_UNKNOWN|VT_BYREF:
820  case VT_DISPATCH|VT_BYREF:
821  case VT_UNKNOWN:
822  case VT_DISPATCH:
823  {
825  IUnknown *unk = NULL;
826 
827  if (!src) {
828  V_I4(hash) = 0;
829  return S_OK;
830  }
831 
832  IUnknown_QueryInterface(src, &IID_IUnknown, (void**)&unk);
833  if (!unk) {
834  V_I4(hash) = ~0u;
836  }
837  V_I4(hash) = get_ptr_hash(unk);
838  IUnknown_Release(unk);
839  break;
840  }
841  case VT_DATE|VT_BYREF:
842  case VT_DATE:
843  return get_flt_hash(V_VT(key) & VT_BYREF ? *V_DATEREF(key) : V_DATE(key), &V_I4(hash));
844  case VT_R4|VT_BYREF:
845  case VT_R4:
846  return get_flt_hash(V_VT(key) & VT_BYREF ? *V_R4REF(key) : V_R4(key), &V_I4(hash));
847  case VT_R8|VT_BYREF:
848  case VT_R8:
849  return get_flt_hash(V_VT(key) & VT_BYREF ? *V_R8REF(key) : V_R8(key), &V_I4(hash));
850  case VT_INT:
851  case VT_UINT:
852  case VT_I1:
853  case VT_I8:
854  case VT_UI2:
855  case VT_UI4:
856  V_I4(hash) = ~0u;
858  default:
859  FIXME("not implemented for type %d\n", V_VT(key));
860  return E_NOTIMPL;
861  }
862 
863  return S_OK;
864 }
865 
866 static const struct IDictionaryVtbl dictionary_vtbl =
867 {
890 };
891 
893 {
894  dictionary *This;
895 
896  TRACE("(%p, %p, %s, %p)\n", factory, outer, debugstr_guid(riid), obj);
897 
898  *obj = NULL;
899 
900  This = heap_alloc(sizeof(*This));
901  if(!This) return E_OUTOFMEMORY;
902 
903  This->IDictionary_iface.lpVtbl = &dictionary_vtbl;
904  This->ref = 1;
905  This->method = BinaryCompare;
906  This->count = 0;
907  list_init(&This->pairs);
908  list_init(&This->notifier);
909  memset(This->buckets, 0, sizeof(This->buckets));
910 
911  init_classinfo(&CLSID_Dictionary, (IUnknown *)&This->IDictionary_iface, &This->classinfo);
912  *obj = &This->IDictionary_iface;
913 
914  return S_OK;
915 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
CompareMethod method
Definition: dictionary.c:74
static HRESULT WINAPI dict_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **obj)
Definition: dictionary.c:225
struct list * cur
Definition: dictionary.c:86
#define REFIID
Definition: guiddef.h:118
struct list buckets[BUCKET_COUNT]
Definition: dictionary.c:77
#define E_NOINTERFACE
Definition: winerror.h:2364
Definition: compat.h:2157
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608
static HRESULT WINAPI dictionary_put_CompareMode(IDictionary *iface, CompareMethod method)
Definition: dictionary.c:718
#define V_DATEREF(A)
Definition: oleauto.h:232
#define V_I2REF(A)
Definition: oleauto.h:246
static HRESULT WINAPI dictionary_Keys(IDictionary *iface, VARIANT *keys)
Definition: dictionary.c:639
Definition: compat.h:2173
HRESULT hr
Definition: shlfolder.c:183
Definition: compat.h:2169
struct outqueuenode * head
Definition: adnsresfilter.c:66
REFIID riid
Definition: precomp.h:44
static ULONG WINAPI dict_enum_Release(IEnumVARIANT *iface)
Definition: dictionary.c:251
static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ret)
Definition: dictionary.c:741
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define V_R8(A)
Definition: oleauto.h:262
#define V_ARRAY(A)
Definition: oleauto.h:222
#define WARN(fmt,...)
Definition: debug.h:112
int notify
Definition: msacm.c:1365
DWORD hash
Definition: dictionary.c:63
VARIANT item
Definition: dictionary.c:65
static HRESULT WINAPI dict_enum_Skip(IEnumVARIANT *iface, ULONG count)
Definition: dictionary.c:294
#define V_I2(A)
Definition: oleauto.h:245
static ULONG WINAPI dictionary_Release(IDictionary *iface)
Definition: dictionary.c:428
static HRESULT WINAPI dictionary_get_CompareMode(IDictionary *iface, CompareMethod *method)
Definition: dictionary.c:731
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847
CompareMethod
Definition: scrrun.idl:45
static HRESULT WINAPI dictionary_GetIDsOfNames(IDictionary *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: dictionary.c:461
static struct keyitem_pair * get_keyitem_pair(dictionary *dict, VARIANT *key)
Definition: dictionary.c:149
classinfo
Definition: clsfactory.c:43
DWORD LCID
Definition: nls.h:13
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
static LPOLESTR
Definition: stg_prop.c:27
static struct list * get_bucket_head(dictionary *dict, DWORD hash)
Definition: dictionary.c:100
short VARIANT_BOOL
Definition: compat.h:2149
static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pctinfo)
Definition: dictionary.c:443
Definition: send.c:48
HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory, IUnknown *outer, REFIID riid, void **obj)
Definition: dictionary.c:892
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define V_I4(A)
Definition: oleauto.h:247
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
Definition: list.h:131
#define V_UNKNOWNREF(A)
Definition: oleauto.h:282
static DWORD get_ptr_hash(void *ptr)
Definition: dictionary.c:789
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FALSE
Definition: types.h:117
int hash
Definition: main.c:58
IEnumVARIANT IEnumVARIANT_iface
Definition: dictionary.c:82
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
Definition: main.c:438
const GUID IID_IProvideClassInfo
if SUCCEEDED(hr)
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
#define S_FALSE
Definition: winerror.h:2357
struct list notifier
Definition: dictionary.c:78
const WCHAR * str
#define LIST_FOR_EACH(cursor, list)
Definition: list.h:188
static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
Definition: dictionary.c:750
HRESULT get_typeinfo(enum type_id tid, ITypeInfo **ret)
Definition: apps.c:124
static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *key, VARIANT *hash)
Definition: dictionary.c:794
struct list entry
Definition: dictionary.c:61
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PtrToUlong(u)
Definition: config.h:107
struct list pairs
Definition: dictionary.c:76
static HRESULT WINAPI dictionary_Items(IDictionary *iface, VARIANT *items)
Definition: dictionary.c:576
static DWORD get_num_hash(FLOAT num)
Definition: dictionary.c:768
LONG count
Definition: dictionary.c:75
static HRESULT WINAPI dictionary_GetTypeInfo(IDictionary *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: dictionary.c:453
static HRESULT WINAPI dictionary_get_Count(IDictionary *iface, LONG *count)
Definition: dictionary.c:553
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define V_R4(A)
Definition: oleauto.h:260
#define TRACE(s)
Definition: solgame.cpp:4
static const unsigned char dictionary[][3]
Definition: decode.c:37
static BOOL is_matching_key(const dictionary *dict, const struct keyitem_pair *pair, const VARIANT *key, DWORD hash)
Definition: dictionary.c:132
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define V_I4REF(A)
Definition: oleauto.h:248
static const struct IDictionaryVtbl dictionary_vtbl
Definition: dictionary.c:866
static HRESULT WINAPI dictionary_get_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
Definition: dictionary.c:524
LONG HRESULT
Definition: typedefs.h:79
struct list notify
Definition: dictionary.c:87
const GUID IID_IUnknown
static dictionary * impl_from_IDictionary(IDictionary *iface)
Definition: dictionary.c:90
int isinf(double x)
#define V_UI1(A)
Definition: oleauto.h:266
#define WINAPI
Definition: msvc.h:6
const IID IID_IObjectWithSite
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
static const IEnumVARIANTVtbl dictenumvtbl
Definition: dictionary.c:333
void init_classinfo(const GUID *guid, IUnknown *outer, struct provideclassinfo *classinfo)
Definition: scrrun.c:232
struct _pair * pair
method
Definition: dragdrop.c:53
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
static WCHAR * get_key_strptr(const VARIANT *key)
Definition: dictionary.c:111
const GUID IID_IDispatch
#define wcsicmp
Definition: compat.h:15
int ret
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
Definition: compat.h:2158
static ITypeInfo * typeinfo[last_tid]
Definition: apps.c:109
#define InterlockedDecrement
Definition: armddk.h:52
#define V_VT(A)
Definition: oleauto.h:211
uint32_t entry
Definition: isohybrid.c:63
static HRESULT add_keyitem_pair(dictionary *dict, VARIANT *key, VARIANT *item)
Definition: dictionary.c:173
Definition: _list.h:228
GLenum src
Definition: glext.h:6340
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_R4REF(A)
Definition: oleauto.h:261
FxCollectionEntry * cur
#define DICT_HASH_MOD
Definition: dictionary.c:43
#define BUCKET_COUNT
Definition: dictionary.c:42
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:534
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:600
static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj)
Definition: dictionary.c:379
LONG ref
Definition: dictionary.c:72
int isnan(double x)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
struct stdole::EXCEPINFO EXCEPINFO
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
static void notify_remove_pair(struct list *notifier, struct list *pair)
Definition: dictionary.c:364
static VARIANTARG static DISPID
Definition: ordinal.c:49
#define S_OK
Definition: intsafe.h:51
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define InterlockedIncrement
Definition: armddk.h:53
static ATOM item
Definition: dde.c:856
const GLdouble * v
Definition: gl.h:2040
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HRESULT WINAPI dict_enum_Reset(IEnumVARIANT *iface)
Definition: dictionary.c:314
struct list bucket
Definition: dictionary.c:62
#define V_UI1REF(A)
Definition: oleauto.h:267
#define E_NOTIMPL
Definition: ddrawi.h:99
static HRESULT create_dict_enum(dictionary *, IUnknown **)
Definition: dictionary.c:343
static HRESULT get_flt_hash(FLOAT flt, LONG *hash)
Definition: dictionary.c:773
#define V_R8REF(A)
Definition: oleauto.h:263
dictionary * dict
Definition: dictionary.c:85
static int strcmp_key(const dictionary *dict, const VARIANT *key1, const VARIANT *key2)
Definition: dictionary.c:123
Definition: _pair.h:47
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
BOOL empty
Definition: button.c:170
static HRESULT WINAPI dictionary_Add(IDictionary *iface, VARIANT *key, VARIANT *item)
Definition: dictionary.c:541
static ULONG WINAPI dict_enum_AddRef(IEnumVARIANT *iface)
Definition: dictionary.c:243
struct stdole::DISPPARAMS DISPPARAMS
__WINE_SERVER_LIST_INLINE struct list * list_next(const struct list *list, const struct list *elem)
Definition: list.h:115
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
float FLOAT
Definition: typedefs.h:69
static struct dictionary_enum * impl_from_IEnumVARIANT(IEnumVARIANT *iface)
Definition: dictionary.c:95
unsigned int ULONG
Definition: retypes.h:1
#define towlower(c)
Definition: wctype.h:97
static HRESULT WINAPI dictionary_put_Key(IDictionary *iface, VARIANT *key, VARIANT *newkey)
Definition: dictionary.c:615
static HRESULT WINAPI dictionary_RemoveAll(IDictionary *iface)
Definition: dictionary.c:697
static void free_keyitem_pair(struct keyitem_pair *pair)
Definition: dictionary.c:218
static HRESULT WINAPI dictionary_Invoke(IDictionary *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: dictionary.c:480
#define CTL_E_ILLEGALFUNCTIONCALL
Definition: olectl.h:267
#define LIST_ENTRY(type)
Definition: queue.h:175
static HRESULT WINAPI dictionary_Remove(IDictionary *iface, VARIANT *key)
Definition: dictionary.c:678
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
static TCHAR * items[]
Definition: page1.c:45
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
WINE_DEFAULT_DEBUG_CHANNEL(storage)
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
VARIANT key
Definition: dictionary.c:64
Definition: compat.h:2159
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
Definition: compat.h:2156
#define V_DATE(A)
Definition: oleauto.h:231
static HRESULT WINAPI dictionary_putref_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem)
Definition: dictionary.c:502
static BOOL is_string_key(const VARIANT *key)
Definition: dictionary.c:105
IDictionary IDictionary_iface
Definition: dictionary.c:71
static HRESULT WINAPI dict_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **cloned)
Definition: dictionary.c:326
static ULONG WINAPI dictionary_AddRef(IDictionary *iface)
Definition: dictionary.c:418
Definition: path.c:41
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static HRESULT WINAPI dictionary_Exists(IDictionary *iface, VARIANT *key, VARIANT_BOOL *exists)
Definition: dictionary.c:563
static HRESULT WINAPI dict_enum_Next(IEnumVARIANT *iface, ULONG count, VARIANT *keys, ULONG *fetched)
Definition: dictionary.c:267
#define V_BSTRREF(A)
Definition: oleauto.h:227
static HRESULT WINAPI dictionary_put_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
Definition: dictionary.c:511