xref: /aosp_15_r20/external/cronet/base/win/enum_variant.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/win/enum_variant.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <wrl/client.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <algorithm>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker namespace base {
14*6777b538SAndroid Build Coastguard Worker namespace win {
15*6777b538SAndroid Build Coastguard Worker 
EnumVariant(ULONG count)16*6777b538SAndroid Build Coastguard Worker EnumVariant::EnumVariant(ULONG count) : current_index_(0) {
17*6777b538SAndroid Build Coastguard Worker   for (ULONG i = 0; i < count; ++i)
18*6777b538SAndroid Build Coastguard Worker     items_.emplace_back(ScopedVariant::kEmptyVariant);
19*6777b538SAndroid Build Coastguard Worker }
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker EnumVariant::~EnumVariant() = default;
22*6777b538SAndroid Build Coastguard Worker 
ItemAt(ULONG index)23*6777b538SAndroid Build Coastguard Worker VARIANT* EnumVariant::ItemAt(ULONG index) {
24*6777b538SAndroid Build Coastguard Worker   DCHECK_LT(index, items_.size());
25*6777b538SAndroid Build Coastguard Worker   // This is a hack to return a mutable pointer to the ScopedVariant, even
26*6777b538SAndroid Build Coastguard Worker   // though the original intent of the AsInput method was to allow only readonly
27*6777b538SAndroid Build Coastguard Worker   // access to the wrapped variant.
28*6777b538SAndroid Build Coastguard Worker   return items_[index].AsInput();
29*6777b538SAndroid Build Coastguard Worker }
30*6777b538SAndroid Build Coastguard Worker 
Next(ULONG requested_count,VARIANT * out_elements,ULONG * out_elements_received)31*6777b538SAndroid Build Coastguard Worker HRESULT EnumVariant::Next(ULONG requested_count,
32*6777b538SAndroid Build Coastguard Worker                           VARIANT* out_elements,
33*6777b538SAndroid Build Coastguard Worker                           ULONG* out_elements_received) {
34*6777b538SAndroid Build Coastguard Worker   if (!out_elements)
35*6777b538SAndroid Build Coastguard Worker     return E_INVALIDARG;
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker   DCHECK_LE(current_index_, items_.size());
38*6777b538SAndroid Build Coastguard Worker   ULONG available_count = static_cast<ULONG>(items_.size()) - current_index_;
39*6777b538SAndroid Build Coastguard Worker   ULONG count = std::min(requested_count, available_count);
40*6777b538SAndroid Build Coastguard Worker   for (ULONG i = 0; i < count; ++i)
41*6777b538SAndroid Build Coastguard Worker     out_elements[i] = items_[current_index_ + i].Copy();
42*6777b538SAndroid Build Coastguard Worker   current_index_ += count;
43*6777b538SAndroid Build Coastguard Worker 
44*6777b538SAndroid Build Coastguard Worker   // The caller can choose not to get the number of received elements by setting
45*6777b538SAndroid Build Coastguard Worker   // |out_elements_received| to nullptr.
46*6777b538SAndroid Build Coastguard Worker   if (out_elements_received)
47*6777b538SAndroid Build Coastguard Worker     *out_elements_received = count;
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker   return (count == requested_count ? S_OK : S_FALSE);
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker 
Skip(ULONG skip_count)52*6777b538SAndroid Build Coastguard Worker HRESULT EnumVariant::Skip(ULONG skip_count) {
53*6777b538SAndroid Build Coastguard Worker   ULONG count = skip_count;
54*6777b538SAndroid Build Coastguard Worker   if (current_index_ + count > static_cast<ULONG>(items_.size()))
55*6777b538SAndroid Build Coastguard Worker     count = static_cast<ULONG>(items_.size()) - current_index_;
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker   current_index_ += count;
58*6777b538SAndroid Build Coastguard Worker   return (count == skip_count ? S_OK : S_FALSE);
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker 
Reset()61*6777b538SAndroid Build Coastguard Worker HRESULT EnumVariant::Reset() {
62*6777b538SAndroid Build Coastguard Worker   current_index_ = 0;
63*6777b538SAndroid Build Coastguard Worker   return S_OK;
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker 
Clone(IEnumVARIANT ** out_cloned_object)66*6777b538SAndroid Build Coastguard Worker HRESULT EnumVariant::Clone(IEnumVARIANT** out_cloned_object) {
67*6777b538SAndroid Build Coastguard Worker   if (!out_cloned_object)
68*6777b538SAndroid Build Coastguard Worker     return E_INVALIDARG;
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   size_t count = items_.size();
71*6777b538SAndroid Build Coastguard Worker   Microsoft::WRL::ComPtr<EnumVariant> other =
72*6777b538SAndroid Build Coastguard Worker       Microsoft::WRL::Make<EnumVariant>(static_cast<ULONG>(count));
73*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < count; ++i)
74*6777b538SAndroid Build Coastguard Worker     other->items_[i] = static_cast<const VARIANT&>(items_[i]);
75*6777b538SAndroid Build Coastguard Worker 
76*6777b538SAndroid Build Coastguard Worker   other->Skip(current_index_);
77*6777b538SAndroid Build Coastguard Worker   return other.CopyTo(IID_PPV_ARGS(out_cloned_object));
78*6777b538SAndroid Build Coastguard Worker }
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker }  // namespace win
81*6777b538SAndroid Build Coastguard Worker }  // namespace base
82