Index: base/win/enum_variant.cc |
=================================================================== |
--- base/win/enum_variant.cc (revision 0) |
+++ base/win/enum_variant.cc (revision 0) |
@@ -0,0 +1,87 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/logging.h" |
+#include "base/win/enum_variant.h" |
+ |
+namespace base { |
+namespace win { |
+ |
+EnumVariant::EnumVariant(unsigned long count) |
+ : count_(count) { |
+ items_.reset(new VARIANT[count_]); |
+ current_index_ = 0; |
+ iunknown_ref_count_ = 1; |
+} |
+ |
+EnumVariant::~EnumVariant() { |
+} |
+ |
+VARIANT* EnumVariant::get(unsigned long index) { |
+ DCHECK(index < count_); |
+ return &items_[index]; |
+} |
+ |
+ULONG STDMETHODCALLTYPE EnumVariant::AddRef() { |
+ return InterlockedIncrement(&iunknown_ref_count_); |
+} |
+ |
+ULONG STDMETHODCALLTYPE EnumVariant::Release() { |
+ ULONG ref_count = InterlockedDecrement(&iunknown_ref_count_); |
+ if (ref_count == 0) |
+ delete this; |
+ return ref_count; |
+} |
+ |
+STDMETHODIMP EnumVariant::QueryInterface(REFIID riid, void** ppv) { |
+ if (riid == IID_IUnknown || |
+ riid == IID_IEnumVARIANT) { |
+ *ppv = this; |
+ AddRef(); |
+ return S_OK; |
+ } |
+ |
+ *ppv = NULL; |
+ return E_NOINTERFACE; |
+} |
+ |
+STDMETHODIMP EnumVariant::Next(ULONG requested_count, |
+ VARIANT* out_elements, |
+ ULONG* out_elements_received) { |
+ unsigned long count = requested_count; |
+ if (current_index_ + count > count_) |
+ count = count_ - current_index_; |
+ |
+ for (unsigned long i = 0; i < count; ++i) |
+ out_elements[i] = items_[current_index_ + i]; |
+ current_index_ += count; |
+ *out_elements_received = count; |
+ |
+ return (count == requested_count ? S_OK : S_FALSE); |
+} |
+ |
+STDMETHODIMP EnumVariant::Skip(ULONG skip_count) { |
+ unsigned long count = skip_count; |
+ if (current_index_ + count > count_) |
+ count = count_ - current_index_; |
+ |
+ current_index_ += count; |
+ return (count == skip_count ? S_OK : S_FALSE); |
+} |
+ |
+STDMETHODIMP EnumVariant::Reset() { |
+ current_index_ = 0; |
+ return S_OK; |
+} |
+ |
+STDMETHODIMP EnumVariant::Clone(IEnumVARIANT** out_cloned_object) { |
+ EnumVariant* other = new EnumVariant(count_); |
+ for (unsigned long i = 0; i < count_; ++i) |
+ *other->get(i) = items_[i]; |
darin (slow to review)
2011/11/22 01:16:52
it is interesting that there is no memory manageme
dmazzoni
2011/11/22 08:08:14
Good question.
A VARIANT isn't an object, it's da
|
+ *out_cloned_object = other; |
+ return S_OK; |
+} |
+ |
+} // namespace win |
+} // namespace base |