ReactOS  0.4.14-dev-115-g4576127
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 #include "config.h"
22 #include "wine/port.h"
23 
24 #include <stdarg.h>
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "olectl.h"
30 #include "dispex.h"
31 #include "scrrun.h"
32 #include "scrrun_private.h"
33 
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36 #include "wine/heap.h"
37 #include "wine/list.h"
38 
40 
41 #define BUCKET_COUNT 509
42 #define DICT_HASH_MOD 1201
43 
44 /* Implementation details
45 
46  Dictionary contains one list that links all pairs, this way
47  order in which they were added is preserved. Each bucket has
48  its own list to hold all pairs in this bucket. Initially all
49  bucket lists are zeroed and we init them once we about to add
50  first pair.
51 
52  When pair is removed it's unlinked from both lists; if it was
53  a last pair in a bucket list it stays empty in initialized state.
54 
55  Preserving pair order is important for enumeration, so far testing
56  indicates that pairs are not reordered basing on hash value.
57  */
58 
59 struct keyitem_pair {
60  struct list entry;
61  struct list bucket;
65 };
66 
67 typedef struct
68 {
70  IDictionary IDictionary_iface;
72 
75  struct list pairs;
76  struct list buckets[BUCKET_COUNT];
77  struct list notifier;
78 } dictionary;
79 
83 
85  struct list *cur;
86  struct list notify;
87 };
88 
89 static inline dictionary *impl_from_IDictionary(IDictionary *iface)
90 {
91  return CONTAINING_RECORD(iface, dictionary, IDictionary_iface);
92 }
93 
95 {
97 }
98 
99 static inline struct list *get_bucket_head(dictionary *dict, DWORD hash)
100 {
101  return &dict->buckets[hash % BUCKET_COUNT];
102 }
103 
104 static inline BOOL is_string_key(const VARIANT *key)
105 {
106  return V_VT(key) == VT_BSTR || V_VT(key) == (VT_BSTR|VT_BYREF);
107 }
108 
109 /* Only for VT_BSTR or VT_BSTR|VT_BYREF types */
110 static inline WCHAR *get_key_strptr(const VARIANT *key)
111 {
112  if (V_VT(key) == VT_BSTR)
113  return V_BSTR(key);
114 
115  if (V_BSTRREF(key))
116  return *V_BSTRREF(key);
117 
118  return NULL;
119 }
120 
121 /* should be used only when both keys are of string type, it's not checked */
122 static inline int strcmp_key(const dictionary *dict, const VARIANT *key1, const VARIANT *key2)
123 {
124  const WCHAR *str1, *str2;
125 
126  str1 = get_key_strptr(key1);
127  str2 = get_key_strptr(key2);
128  return dict->method == BinaryCompare ? strcmpW(str1, str2) : strcmpiW(str1, str2);
129 }
130 
131 static BOOL is_matching_key(const dictionary *dict, const struct keyitem_pair *pair, const VARIANT *key, DWORD hash)
132 {
133  if (is_string_key(key) && is_string_key(&pair->key)) {
134  if (hash != pair->hash)
135  return FALSE;
136 
137  return strcmp_key(dict, key, &pair->key) == 0;
138  }
139 
140  if ((is_string_key(key) && !is_string_key(&pair->key)) ||
141  (!is_string_key(key) && is_string_key(&pair->key)))
142  return FALSE;
143 
144  /* for numeric keys only check hash */
145  return hash == pair->hash;
146 }
147 
149 {
150  struct keyitem_pair *pair;
151  struct list *head, *entry;
152  VARIANT hash;
153  HRESULT hr;
154 
155  hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash);
156  if (FAILED(hr))
157  return NULL;
158 
159  head = get_bucket_head(dict, V_I4(&hash));
160  if (!head->next || list_empty(head))
161  return NULL;
162 
163  entry = list_head(head);
164  do {
165  pair = LIST_ENTRY(entry, struct keyitem_pair, bucket);
166  if (is_matching_key(dict, pair, key, V_I4(&hash))) return pair;
167  } while ((entry = list_next(head, entry)));
168 
169  return NULL;
170 }
171 
173 {
174  struct keyitem_pair *pair;
175  struct list *head;
176  VARIANT hash;
177  HRESULT hr;
178 
179  hr = IDictionary_get_HashVal(&dict->IDictionary_iface, key, &hash);
180  if (FAILED(hr))
181  return hr;
182 
183  pair = heap_alloc(sizeof(*pair));
184  if (!pair)
185  return E_OUTOFMEMORY;
186 
187  pair->hash = V_I4(&hash);
188  VariantInit(&pair->key);
189  VariantInit(&pair->item);
190 
191  hr = VariantCopyInd(&pair->key, key);
192  if (FAILED(hr))
193  goto failed;
194 
195  hr = VariantCopyInd(&pair->item, item);
196  if (FAILED(hr))
197  goto failed;
198 
199  head = get_bucket_head(dict, pair->hash);
200  if (!head->next)
201  /* this only happens once per bucket */
202  list_init(head);
203 
204  /* link to bucket list and to full list */
205  list_add_tail(head, &pair->bucket);
206  list_add_tail(&dict->pairs, &pair->entry);
207  dict->count++;
208  return S_OK;
209 
210 failed:
211  VariantClear(&pair->key);
212  VariantClear(&pair->item);
213  heap_free(pair);
214  return hr;
215 }
216 
217 static void free_keyitem_pair(struct keyitem_pair *pair)
218 {
219  VariantClear(&pair->key);
220  VariantClear(&pair->item);
221  heap_free(pair);
222 }
223 
225 {
227 
228  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
229 
230  if (IsEqualIID(riid, &IID_IEnumVARIANT) || IsEqualIID(riid, &IID_IUnknown)) {
231  *obj = iface;
232  IEnumVARIANT_AddRef(iface);
233  return S_OK;
234  }
235  else {
236  WARN("interface not supported %s\n", debugstr_guid(riid));
237  *obj = NULL;
238  return E_NOINTERFACE;
239  }
240 }
241 
243 {
246  TRACE("(%p)->(%u)\n", This, ref);
247  return ref;
248 }
249 
251 {
254 
255  TRACE("(%p)->(%u)\n", This, ref);
256 
257  if (!ref) {
258  list_remove(&This->notify);
259  IDictionary_Release(&This->dict->IDictionary_iface);
260  heap_free(This);
261  }
262 
263  return ref;
264 }
265 
267 {
269  struct keyitem_pair *pair;
270  ULONG i = 0;
271 
272  TRACE("(%p)->(%u %p %p)\n", This, count, keys, fetched);
273 
274  if (fetched)
275  *fetched = 0;
276 
277  if (!count)
278  return S_OK;
279 
280  while (This->cur && i < count) {
281  pair = LIST_ENTRY(This->cur, struct keyitem_pair, entry);
282  VariantCopy(&keys[i], &pair->key);
283  This->cur = list_next(&This->dict->pairs, This->cur);
284  i++;
285  }
286 
287  if (fetched)
288  *fetched = i;
289 
290  return i < count ? S_FALSE : S_OK;
291 }
292 
294 {
296 
297  TRACE("(%p)->(%u)\n", This, count);
298 
299  if (!count)
300  return S_OK;
301 
302  if (!This->cur)
303  return S_FALSE;
304 
305  while (count--) {
306  This->cur = list_next(&This->dict->pairs, This->cur);
307  if (!This->cur) break;
308  }
309 
310  return count == 0 ? S_OK : S_FALSE;
311 }
312 
314 {
316 
317  TRACE("(%p)\n", This);
318 
319  This->cur = list_head(&This->dict->pairs);
320  return S_OK;
321 }
322 
324 
326 {
328  TRACE("(%p)->(%p)\n", This, cloned);
329  return create_dict_enum(This->dict, (IUnknown**)cloned);
330 }
331 
332 static const IEnumVARIANTVtbl dictenumvtbl = {
340 };
341 
343 {
344  struct dictionary_enum *This;
345 
346  *ret = NULL;
347 
348  This = heap_alloc(sizeof(*This));
349  if (!This)
350  return E_OUTOFMEMORY;
351 
352  This->IEnumVARIANT_iface.lpVtbl = &dictenumvtbl;
353  This->ref = 1;
354  This->cur = list_head(&dict->pairs);
355  list_add_tail(&dict->notifier, &This->notify);
356  This->dict = dict;
357  IDictionary_AddRef(&dict->IDictionary_iface);
358 
359  *ret = (IUnknown*)&This->IEnumVARIANT_iface;
360  return S_OK;
361 }
362 
363 static void notify_remove_pair(struct list *notifier, struct list *pair)
364 {
365  struct dictionary_enum *dict_enum;
366  struct list *cur;
367 
368  LIST_FOR_EACH(cur, notifier) {
369  dict_enum = LIST_ENTRY(cur, struct dictionary_enum, notify);
370  if (!pair)
371  dict_enum->cur = list_head(&dict_enum->dict->pairs);
372  else if (dict_enum->cur == pair) {
373  dict_enum->cur = list_next(&dict_enum->dict->pairs, dict_enum->cur);
374  }
375  }
376 }
377 
378 static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj)
379 {
381  TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
382 
383  *obj = NULL;
384 
385  if(IsEqualIID(riid, &IID_IUnknown) ||
387  IsEqualIID(riid, &IID_IDictionary))
388  {
389  *obj = &This->IDictionary_iface;
390  }
392  {
393  *obj = &This->classinfo.IProvideClassInfo_iface;
394  }
395  else if ( IsEqualGUID( riid, &IID_IDispatchEx ))
396  {
397  TRACE("Interface IDispatchEx not supported - returning NULL\n");
398  *obj = NULL;
399  return E_NOINTERFACE;
400  }
401  else if ( IsEqualGUID( riid, &IID_IObjectWithSite ))
402  {
403  TRACE("Interface IObjectWithSite not supported - returning NULL\n");
404  *obj = NULL;
405  return E_NOINTERFACE;
406  }
407  else
408  {
409  WARN("interface %s not implemented\n", debugstr_guid(riid));
410  return E_NOINTERFACE;
411  }
412 
413  IUnknown_AddRef((IUnknown*)*obj);
414  return S_OK;
415 }
416 
417 static ULONG WINAPI dictionary_AddRef(IDictionary *iface)
418 {
421 
422  TRACE("(%p)->(%u)\n", This, ref);
423 
424  return ref;
425 }
426 
427 static ULONG WINAPI dictionary_Release(IDictionary *iface)
428 {
431 
432  TRACE("(%p)->(%u)\n", This, ref);
433 
434  if (!ref) {
435  IDictionary_RemoveAll(iface);
436  heap_free(This);
437  }
438 
439  return ref;
440 }
441 
442 static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pctinfo)
443 {
445 
446  TRACE("(%p)->(%p)\n", This, pctinfo);
447 
448  *pctinfo = 1;
449  return S_OK;
450 }
451 
452 static HRESULT WINAPI dictionary_GetTypeInfo(IDictionary *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
453 {
455 
456  TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
457  return get_typeinfo(IDictionary_tid, ppTInfo);
458 }
459 
460 static HRESULT WINAPI dictionary_GetIDsOfNames(IDictionary *iface, REFIID riid, LPOLESTR *rgszNames,
461  UINT cNames, LCID lcid, DISPID *rgDispId)
462 {
465  HRESULT hr;
466 
467  TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
468 
470  if(SUCCEEDED(hr))
471  {
472  hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
473  ITypeInfo_Release(typeinfo);
474  }
475 
476  return hr;
477 }
478 
479 static HRESULT WINAPI dictionary_Invoke(IDictionary *iface, DISPID dispIdMember, REFIID riid,
480  LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
481  EXCEPINFO *pExcepInfo, UINT *puArgErr)
482 {
485  HRESULT hr;
486 
487  TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
488  lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
489 
491  if(SUCCEEDED(hr))
492  {
493  hr = ITypeInfo_Invoke(typeinfo, &This->IDictionary_iface, dispIdMember, wFlags,
494  pDispParams, pVarResult, pExcepInfo, puArgErr);
495  ITypeInfo_Release(typeinfo);
496  }
497 
498  return hr;
499 }
500 
501 static HRESULT WINAPI dictionary_putref_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem)
502 {
504 
505  FIXME("(%p)->(%p %p)\n", This, Key, pRetItem);
506 
507  return E_NOTIMPL;
508 }
509 
510 static HRESULT WINAPI dictionary_put_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
511 {
513  struct keyitem_pair *pair;
514 
515  TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(item));
516 
517  if ((pair = get_keyitem_pair(This, key)))
518  return VariantCopyInd(&pair->item, item);
519 
520  return IDictionary_Add(iface, key, item);
521 }
522 
523 static HRESULT WINAPI dictionary_get_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
524 {
526  struct keyitem_pair *pair;
527 
528  TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), item);
529 
530  if ((pair = get_keyitem_pair(This, key)))
531  VariantCopy(item, &pair->item);
532  else {
533  VariantInit(item);
534  return IDictionary_Add(iface, key, item);
535  }
536 
537  return S_OK;
538 }
539 
540 static HRESULT WINAPI dictionary_Add(IDictionary *iface, VARIANT *key, VARIANT *item)
541 {
543 
544  TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(item));
545 
546  if (get_keyitem_pair(This, key))
547  return CTL_E_KEY_ALREADY_EXISTS;
548 
549  return add_keyitem_pair(This, key, item);
550 }
551 
552 static HRESULT WINAPI dictionary_get_Count(IDictionary *iface, LONG *count)
553 {
555 
556  TRACE("(%p)->(%p)\n", This, count);
557 
558  *count = This->count;
559  return S_OK;
560 }
561 
562 static HRESULT WINAPI dictionary_Exists(IDictionary *iface, VARIANT *key, VARIANT_BOOL *exists)
563 {
565 
566  TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), exists);
567 
568  if (!exists)
570 
571  *exists = get_keyitem_pair(This, key) != NULL ? VARIANT_TRUE : VARIANT_FALSE;
572  return S_OK;
573 }
574 
575 static HRESULT WINAPI dictionary_Items(IDictionary *iface, VARIANT *items)
576 {
578  struct keyitem_pair *pair;
579  SAFEARRAYBOUND bound;
580  SAFEARRAY *sa;
581  VARIANT *v;
582  HRESULT hr;
583  LONG i;
584 
585  TRACE("(%p)->(%p)\n", This, items);
586 
587  if (!items)
588  return S_OK;
589 
590  bound.lLbound = 0;
591  bound.cElements = This->count;
592  sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
593  if (!sa)
594  return E_OUTOFMEMORY;
595 
596  hr = SafeArrayAccessData(sa, (void**)&v);
597  if (FAILED(hr)) {
599  return hr;
600  }
601 
602  i = 0;
603  LIST_FOR_EACH_ENTRY(pair, &This->pairs, struct keyitem_pair, entry) {
604  VariantCopy(&v[i], &pair->item);
605  i++;
606  }
608 
610  V_ARRAY(items) = sa;
611  return S_OK;
612 }
613 
614 static HRESULT WINAPI dictionary_put_Key(IDictionary *iface, VARIANT *key, VARIANT *newkey)
615 {
617  struct keyitem_pair *pair;
618  VARIANT empty;
619  HRESULT hr;
620 
621  TRACE("(%p)->(%s %s)\n", This, debugstr_variant(key), debugstr_variant(newkey));
622 
623  if ((pair = get_keyitem_pair(This, key))) {
624  /* found existing pair for a key, add new pair with new key
625  and old item and remove old pair after that */
626 
627  hr = IDictionary_Add(iface, newkey, &pair->item);
628  if (FAILED(hr))
629  return hr;
630 
631  return IDictionary_Remove(iface, key);
632  }
633 
634  VariantInit(&empty);
635  return IDictionary_Add(iface, newkey, &empty);
636 }
637 
638 static HRESULT WINAPI dictionary_Keys(IDictionary *iface, VARIANT *keys)
639 {
641  struct keyitem_pair *pair;
642  SAFEARRAYBOUND bound;
643  SAFEARRAY *sa;
644  VARIANT *v;
645  HRESULT hr;
646  LONG i;
647 
648  TRACE("(%p)->(%p)\n", This, keys);
649 
650  if (!keys)
651  return S_OK;
652 
653  bound.lLbound = 0;
654  bound.cElements = This->count;
655  sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
656  if (!sa)
657  return E_OUTOFMEMORY;
658 
659  hr = SafeArrayAccessData(sa, (void**)&v);
660  if (FAILED(hr)) {
662  return hr;
663  }
664 
665  i = 0;
666  LIST_FOR_EACH_ENTRY(pair, &This->pairs, struct keyitem_pair, entry) {
667  VariantCopy(&v[i], &pair->key);
668  i++;
669  }
671 
672  V_VT(keys) = VT_ARRAY|VT_VARIANT;
673  V_ARRAY(keys) = sa;
674  return S_OK;
675 }
676 
677 static HRESULT WINAPI dictionary_Remove(IDictionary *iface, VARIANT *key)
678 {
680  struct keyitem_pair *pair;
681 
682  TRACE("(%p)->(%s)\n", This, debugstr_variant(key));
683 
684  if (!(pair = get_keyitem_pair(This, key)))
685  return CTL_E_ELEMENT_NOT_FOUND;
686 
687  notify_remove_pair(&This->notifier, &pair->entry);
688  list_remove(&pair->entry);
689  list_remove(&pair->bucket);
690  This->count--;
691 
693  return S_OK;
694 }
695 
696 static HRESULT WINAPI dictionary_RemoveAll(IDictionary *iface)
697 {
699  struct keyitem_pair *pair, *pair2;
700 
701  TRACE("(%p)\n", This);
702 
703  if (This->count == 0)
704  return S_OK;
705 
706  notify_remove_pair(&This->notifier, NULL);
707  LIST_FOR_EACH_ENTRY_SAFE(pair, pair2, &This->pairs, struct keyitem_pair, entry) {
708  list_remove(&pair->entry);
709  list_remove(&pair->bucket);
711  }
712  This->count = 0;
713 
714  return S_OK;
715 }
716 
718 {
720 
721  TRACE("(%p)->(%d)\n", This, method);
722 
723  if (This->count)
725 
726  This->method = method;
727  return S_OK;
728 }
729 
731 {
733 
734  TRACE("(%p)->(%p)\n", This, method);
735 
736  *method = This->method;
737  return S_OK;
738 }
739 
740 static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ret)
741 {
743 
744  TRACE("(%p)->(%p)\n", This, ret);
745 
746  return create_dict_enum(This, ret);
747 }
748 
750 {
751  DWORD hash = 0;
752 
753  if (str) {
754  while (*str) {
755  WCHAR ch;
756 
757  ch = (method == TextCompare || method == DatabaseCompare) ? tolowerW(*str) : *str;
758 
759  hash += (hash << 4) + ch;
760  str++;
761  }
762  }
763 
764  return hash % DICT_HASH_MOD;
765 }
766 
768 {
769  return (*((DWORD*)&num)) % DICT_HASH_MOD;
770 }
771 
773 {
774  if (isinf(flt)) {
775  *hash = 0;
776  return S_OK;
777  }
778  else if (!isnan(flt)) {
779  *hash = get_num_hash(flt);
780  return S_OK;
781  }
782 
783  /* NaN case */
784  *hash = ~0u;
786 }
787 
788 static DWORD get_ptr_hash(void *ptr)
789 {
790  return PtrToUlong(ptr) % DICT_HASH_MOD;
791 }
792 
794 {
796 
797  TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), hash);
798 
799  V_VT(hash) = VT_I4;
800  switch (V_VT(key))
801  {
802  case VT_BSTR|VT_BYREF:
803  case VT_BSTR:
805  break;
806  case VT_UI1|VT_BYREF:
807  case VT_UI1:
809  break;
810  case VT_I2|VT_BYREF:
811  case VT_I2:
813  break;
814  case VT_I4|VT_BYREF:
815  case VT_I4:
817  break;
818  case VT_UNKNOWN|VT_BYREF:
819  case VT_DISPATCH|VT_BYREF:
820  case VT_UNKNOWN:
821  case VT_DISPATCH:
822  {
824  IUnknown *unk = NULL;
825 
826  if (!src) {
827  V_I4(hash) = 0;
828  return S_OK;
829  }
830 
831  IUnknown_QueryInterface(src, &IID_IUnknown, (void**)&unk);
832  if (!unk) {
833  V_I4(hash) = ~0u;
835  }
836  V_I4(hash) = get_ptr_hash(unk);
837  IUnknown_Release(unk);
838  break;
839  }
840  case VT_DATE|VT_BYREF:
841  case VT_DATE:
842  return get_flt_hash(V_VT(key) & VT_BYREF ? *V_DATEREF(key) : V_DATE(key), &V_I4(hash));
843  case VT_R4|VT_BYREF:
844  case VT_R4:
845  return get_flt_hash(V_VT(key) & VT_BYREF ? *V_R4REF(key) : V_R4(key), &V_I4(hash));
846  case VT_R8|VT_BYREF:
847  case VT_R8:
848  return get_flt_hash(V_VT(key) & VT_BYREF ? *V_R8REF(key) : V_R8(key), &V_I4(hash));
849  case VT_INT:
850  case VT_UINT:
851  case VT_I1:
852  case VT_I8:
853  case VT_UI2:
854  case VT_UI4:
855  V_I4(hash) = ~0u;
857  default:
858  FIXME("not implemented for type %d\n", V_VT(key));
859  return E_NOTIMPL;
860  }
861 
862  return S_OK;
863 }
864 
865 static const struct IDictionaryVtbl dictionary_vtbl =
866 {
889 };
890 
892 {
893  dictionary *This;
894 
895  TRACE("(%p, %p, %s, %p)\n", factory, outer, debugstr_guid(riid), obj);
896 
897  *obj = NULL;
898 
899  This = heap_alloc(sizeof(*This));
900  if(!This) return E_OUTOFMEMORY;
901 
902  This->IDictionary_iface.lpVtbl = &dictionary_vtbl;
903  This->ref = 1;
904  This->method = BinaryCompare;
905  This->count = 0;
906  list_init(&This->pairs);
907  list_init(&This->notifier);
908  memset(This->buckets, 0, sizeof(This->buckets));
909 
910  init_classinfo(&CLSID_Dictionary, (IUnknown *)&This->IDictionary_iface, &This->classinfo);
911  *obj = &This->IDictionary_iface;
912 
913  return S_OK;
914 }
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:73
static HRESULT WINAPI dict_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **obj)
Definition: dictionary.c:224
struct list * cur
Definition: dictionary.c:85
#define REFIID
Definition: guiddef.h:118
struct list buckets[BUCKET_COUNT]
Definition: dictionary.c:76
#define E_NOINTERFACE
Definition: winerror.h:2364
Definition: compat.h:1939
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:717
#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:638
Definition: compat.h:1955
HRESULT hr
Definition: shlfolder.c:183
Definition: compat.h:1951
struct outqueuenode * head
Definition: adnsresfilter.c:66
REFIID riid
Definition: precomp.h:44
static ULONG WINAPI dict_enum_Release(IEnumVARIANT *iface)
Definition: dictionary.c:250
static const WCHAR empty[]
Definition: main.c:49
static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ret)
Definition: dictionary.c:740
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:111
int notify
Definition: msacm.c:1353
DWORD hash
Definition: dictionary.c:62
VARIANT item
Definition: dictionary.c:64
static HRESULT WINAPI dict_enum_Skip(IEnumVARIANT *iface, ULONG count)
Definition: dictionary.c:293
#define V_I2(A)
Definition: oleauto.h:245
static ULONG WINAPI dictionary_Release(IDictionary *iface)
Definition: dictionary.c:427
static HRESULT WINAPI dictionary_get_CompareMode(IDictionary *iface, CompareMethod *method)
Definition: dictionary.c:730
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:850
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:460
static struct keyitem_pair * get_keyitem_pair(dictionary *dict, VARIANT *key)
Definition: dictionary.c:148
classinfo
Definition: clsfactory.c:43
DWORD LCID
Definition: nls.h:13
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:571
static LPOLESTR
Definition: stg_prop.c:27
static struct list * get_bucket_head(dictionary *dict, DWORD hash)
Definition: dictionary.c:99
short VARIANT_BOOL
Definition: compat.h:1931
static HRESULT WINAPI dictionary_GetTypeInfoCount(IDictionary *iface, UINT *pctinfo)
Definition: dictionary.c:442
Definition: send.c:47
HRESULT WINAPI Dictionary_CreateInstance(IClassFactory *factory, IUnknown *outer, REFIID riid, void **obj)
Definition: dictionary.c:891
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:788
__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
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
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
int hash
Definition: main.c:58
IEnumVARIANT IEnumVARIANT_iface
Definition: dictionary.c:81
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1139
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
Definition: main.c:440
const GUID IID_IProvideClassInfo
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
#define S_FALSE
Definition: winerror.h:2357
struct list notifier
Definition: dictionary.c:77
const WCHAR * str
#define LIST_FOR_EACH(cursor, list)
Definition: list.h:188
smooth NULL
Definition: ftsmooth.c:416
static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
Definition: dictionary.c:749
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:793
struct list entry
Definition: dictionary.c:60
#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:75
static HRESULT WINAPI dictionary_Items(IDictionary *iface, VARIANT *items)
Definition: dictionary.c:575
static DWORD get_num_hash(FLOAT num)
Definition: dictionary.c:767
LONG count
Definition: dictionary.c:74
static HRESULT WINAPI dictionary_GetTypeInfo(IDictionary *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: dictionary.c:452
static HRESULT WINAPI dictionary_get_Count(IDictionary *iface, LONG *count)
Definition: dictionary.c:552
__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:131
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define V_I4REF(A)
Definition: oleauto.h:248
static const struct IDictionaryVtbl dictionary_vtbl
Definition: dictionary.c:865
static HRESULT WINAPI dictionary_get_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
Definition: dictionary.c:523
LONG HRESULT
Definition: typedefs.h:77
struct list notify
Definition: dictionary.c:86
const GUID IID_IUnknown
static dictionary * impl_from_IDictionary(IDictionary *iface)
Definition: dictionary.c:89
int isinf(double x)
#define V_UI1(A)
Definition: oleauto.h:266
#define WINAPI
Definition: msvc.h:8
const IID IID_IObjectWithSite
unsigned short WORD
Definition: ntddk_ex.h:93
WINE_UNICODE_INLINE WCHAR tolowerW(WCHAR ch)
Definition: unicode.h:135
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
static const IEnumVARIANTVtbl dictenumvtbl
Definition: dictionary.c:332
void init_classinfo(const GUID *guid, IUnknown *outer, struct provideclassinfo *classinfo)
Definition: scrrun.c:233
struct _pair * pair
method
Definition: dragdrop.c:53
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1349
static WCHAR * get_key_strptr(const VARIANT *key)
Definition: dictionary.c:110
const GUID IID_IDispatch
int ret
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:651
Definition: compat.h:1940
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:172
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
#define strcmpiW(s1, s2)
Definition: unicode.h:39
#define DICT_HASH_MOD
Definition: dictionary.c:42
#define BUCKET_COUNT
Definition: dictionary.c:41
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
SAFEARRAY *WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
Definition: safearray.c:602
static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj)
Definition: dictionary.c:378
LONG ref
Definition: dictionary.c:71
int isnan(double x)
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:363
static VARIANTARG static DISPID
Definition: ordinal.c:49
#define S_OK
Definition: intsafe.h:59
#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
static HRESULT WINAPI dict_enum_Reset(IEnumVARIANT *iface)
Definition: dictionary.c:313
struct list bucket
Definition: dictionary.c:61
#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:342
static HRESULT get_flt_hash(FLOAT flt, LONG *hash)
Definition: dictionary.c:772
#define V_R8REF(A)
Definition: oleauto.h:263
dictionary * dict
Definition: dictionary.c:84
static int strcmp_key(const dictionary *dict, const VARIANT *key1, const VARIANT *key2)
Definition: dictionary.c:122
Definition: _pair.h:47
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static HRESULT WINAPI dictionary_Add(IDictionary *iface, VARIANT *key, VARIANT *item)
Definition: dictionary.c:540
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
static ULONG WINAPI dict_enum_AddRef(IEnumVARIANT *iface)
Definition: dictionary.c:242
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:67
static struct dictionary_enum * impl_from_IEnumVARIANT(IEnumVARIANT *iface)
Definition: dictionary.c:94
unsigned int ULONG
Definition: retypes.h:1
static HRESULT WINAPI dictionary_put_Key(IDictionary *iface, VARIANT *key, VARIANT *newkey)
Definition: dictionary.c:614
static HRESULT WINAPI dictionary_RemoveAll(IDictionary *iface)
Definition: dictionary.c:696
static void free_keyitem_pair(struct keyitem_pair *pair)
Definition: dictionary.c:217
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:479
#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:677
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:751
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:63
Definition: compat.h:1941
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1170
Definition: compat.h:1938
#define V_DATE(A)
Definition: oleauto.h:231
static HRESULT WINAPI dictionary_putref_Item(IDictionary *iface, VARIANT *Key, VARIANT *pRetItem)
Definition: dictionary.c:501
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static BOOL is_string_key(const VARIANT *key)
Definition: dictionary.c:104
IDictionary IDictionary_iface
Definition: dictionary.c:70
static HRESULT WINAPI dict_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **cloned)
Definition: dictionary.c:325
static ULONG WINAPI dictionary_AddRef(IDictionary *iface)
Definition: dictionary.c:417
Definition: path.c:42
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:562
static HRESULT WINAPI dict_enum_Next(IEnumVARIANT *iface, ULONG count, VARIANT *keys, ULONG *fetched)
Definition: dictionary.c:266
#define V_BSTRREF(A)
Definition: oleauto.h:227
static HRESULT WINAPI dictionary_put_Item(IDictionary *iface, VARIANT *key, VARIANT *item)
Definition: dictionary.c:510