scoped_safearray.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2019 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. #ifndef BASE_WIN_SCOPED_SAFEARRAY_H_
  5. #define BASE_WIN_SCOPED_SAFEARRAY_H_
  6. #include <objbase.h>
  7. #include "base/base_export.h"
  8. #include "base/logging.h"
  9. namespace base {
  10. namespace win {
  11. // Manages a Windows SAFEARRAY. This is a minimal wrapper that simply provides
  12. // RAII semantics and does not duplicate the extensive functionality that
  13. // CComSafeArray offers.
  14. class BASE_EXPORT ScopedSafearray {
  15. public:
  16. explicit ScopedSafearray(SAFEARRAY* safearray = nullptr)
  17. : safearray_(safearray) {}
  18. // Move constructor
  19. ScopedSafearray(ScopedSafearray&& r) noexcept : safearray_(r.safearray_) {
  20. r.safearray_ = nullptr;
  21. }
  22. // Move operator=. Allows assignment from a ScopedSafearray rvalue.
  23. ScopedSafearray& operator=(ScopedSafearray&& rvalue) {
  24. Reset(rvalue.Release());
  25. return *this;
  26. }
  27. ~ScopedSafearray() { Destroy(); }
  28. void Destroy() {
  29. if (safearray_) {
  30. HRESULT hr = SafeArrayDestroy(safearray_);
  31. DCHECK_EQ(S_OK, hr);
  32. safearray_ = nullptr;
  33. }
  34. }
  35. // Give ScopedSafearray ownership over an already allocated SAFEARRAY or
  36. // nullptr.
  37. void Reset(SAFEARRAY* safearray = nullptr) {
  38. if (safearray != safearray_) {
  39. Destroy();
  40. safearray_ = safearray;
  41. }
  42. }
  43. // Releases ownership of the SAFEARRAY to the caller.
  44. SAFEARRAY* Release() {
  45. SAFEARRAY* safearray = safearray_;
  46. safearray_ = nullptr;
  47. return safearray;
  48. }
  49. // Retrieves the pointer address.
  50. // Used to receive SAFEARRAYs as out arguments (and take ownership).
  51. // This function releases any existing references because it will leak
  52. // the existing ref otherwise.
  53. // Usage: GetSafearray(safearray.Receive());
  54. SAFEARRAY** Receive() {
  55. Destroy();
  56. return &safearray_;
  57. }
  58. // Returns the internal pointer. Prefer using operator SAFEARRAY*() instead,
  59. // as that will automatically convert for function calls expecting a raw
  60. // SAFEARRAY*
  61. SAFEARRAY* Get() const { return safearray_; }
  62. // Forbid comparison of ScopedSafearray types. You should never have the same
  63. // SAFEARRAY owned by two different scoped_ptrs.
  64. bool operator==(const ScopedSafearray& safearray2) const = delete;
  65. bool operator!=(const ScopedSafearray& safearray2) const = delete;
  66. private:
  67. SAFEARRAY* safearray_;
  68. DISALLOW_COPY_AND_ASSIGN(ScopedSafearray);
  69. };
  70. } // namespace win
  71. } // namespace base
  72. #endif // BASE_WIN_SCOPED_SAFEARRAY_H_