1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/win/enum_variant.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 11 namespace base { 12 namespace win { 13 14 EnumVariant::EnumVariant(unsigned long count) 15 : items_(new VARIANT[count]), 16 count_(count), 17 current_index_(0) { 18 } 19 20 EnumVariant::~EnumVariant() { 21 } 22 23 VARIANT* EnumVariant::ItemAt(unsigned long index) { 24 DCHECK(index < count_); 25 return &items_[index]; 26 } 27 28 ULONG STDMETHODCALLTYPE EnumVariant::AddRef() { 29 return IUnknownImpl::AddRef(); 30 } 31 32 ULONG STDMETHODCALLTYPE EnumVariant::Release() { 33 return IUnknownImpl::Release(); 34 } 35 36 STDMETHODIMP EnumVariant::QueryInterface(REFIID riid, void** ppv) { 37 if (riid == IID_IEnumVARIANT) { 38 *ppv = static_cast<IEnumVARIANT*>(this); 39 AddRef(); 40 return S_OK; 41 } 42 43 return IUnknownImpl::QueryInterface(riid, ppv); 44 } 45 46 STDMETHODIMP EnumVariant::Next(ULONG requested_count, 47 VARIANT* out_elements, 48 ULONG* out_elements_received) { 49 unsigned long count = std::min(requested_count, count_ - current_index_); 50 for (unsigned long i = 0; i < count; ++i) 51 out_elements[i] = items_[current_index_ + i]; 52 current_index_ += count; 53 *out_elements_received = count; 54 55 return (count == requested_count ? S_OK : S_FALSE); 56 } 57 58 STDMETHODIMP EnumVariant::Skip(ULONG skip_count) { 59 unsigned long count = skip_count; 60 if (current_index_ + count > count_) 61 count = count_ - current_index_; 62 63 current_index_ += count; 64 return (count == skip_count ? S_OK : S_FALSE); 65 } 66 67 STDMETHODIMP EnumVariant::Reset() { 68 current_index_ = 0; 69 return S_OK; 70 } 71 72 STDMETHODIMP EnumVariant::Clone(IEnumVARIANT** out_cloned_object) { 73 EnumVariant* other = new EnumVariant(count_); 74 if (count_ > 0) 75 memcpy(other->ItemAt(0), &items_[0], count_ * sizeof(VARIANT)); 76 other->Skip(current_index_); 77 other->AddRef(); 78 *out_cloned_object = other; 79 return S_OK; 80 } 81 82 } // namespace win 83 } // namespace base 84