Chromium Code Reviews| 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 |