xref: /aosp_15_r20/external/cronet/base/mac/scoped_authorizationref.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_MAC_SCOPED_AUTHORIZATIONREF_H_
6 #define BASE_MAC_SCOPED_AUTHORIZATIONREF_H_
7 
8 #include <Security/Authorization.h>
9 
10 #include <utility>
11 
12 #include "base/base_export.h"
13 #include "base/check.h"
14 
15 // `ScopedAuthorizationRef` maintains ownership of an `AuthorizationRef`.  It is
16 // patterned after the `unique_ptr` interface.
17 
18 namespace base::mac {
19 
20 class BASE_EXPORT ScopedAuthorizationRef {
21  public:
22   explicit ScopedAuthorizationRef(AuthorizationRef authorization = nullptr)
authorization_(authorization)23       : authorization_(authorization) {}
24 
25   ScopedAuthorizationRef(const ScopedAuthorizationRef&) = delete;
26   ScopedAuthorizationRef& operator=(const ScopedAuthorizationRef&) = delete;
27 
ScopedAuthorizationRef(ScopedAuthorizationRef && that)28   ScopedAuthorizationRef(ScopedAuthorizationRef&& that)
29       : authorization_(std::exchange(that.authorization_, nullptr)) {}
30   ScopedAuthorizationRef& operator=(ScopedAuthorizationRef&& that) {
31     authorization_ = std::exchange(that.authorization_, nullptr);
32     return *this;
33   }
34 
~ScopedAuthorizationRef()35   ~ScopedAuthorizationRef() {
36     if (authorization_) {
37       FreeInternal();
38     }
39   }
40 
41   void reset(AuthorizationRef authorization = nullptr) {
42     if (authorization_ != authorization) {
43       if (authorization_) {
44         FreeInternal();
45       }
46       authorization_ = authorization;
47     }
48   }
49 
50   bool operator==(AuthorizationRef that) const {
51     return authorization_ == that;
52   }
53 
54   bool operator!=(AuthorizationRef that) const {
55     return authorization_ != that;
56   }
57 
AuthorizationRef()58   operator AuthorizationRef() const {
59     return authorization_;
60   }
61 
62   explicit operator bool() const { return authorization_ != nullptr; }
63 
64   // This is to be used only to take ownership of objects that are created
65   // by pass-by-pointer create functions. To enforce this, require that the
66   // object be reset to NULL before this may be used.
InitializeInto()67   [[nodiscard]] AuthorizationRef* InitializeInto() {
68     DCHECK(!authorization_);
69     return &authorization_;
70   }
71 
get()72   AuthorizationRef get() const {
73     return authorization_;
74   }
75 
76   // ScopedAuthorizationRef::release() is like std::unique_ptr<>::release. It is
77   // NOT a wrapper for AuthorizationFree(). To force a ScopedAuthorizationRef
78   // object to call AuthorizationFree(), use ScopedAuthorizationRef::reset().
release()79   [[nodiscard]] AuthorizationRef release() {
80     AuthorizationRef temp = authorization_;
81     authorization_ = nullptr;
82     return temp;
83   }
84 
85  private:
86   // Calling AuthorizationFree, defined in Security.framework, from an inline
87   // function, results in link errors when linking dynamically with
88   // libbase.dylib. So wrap the call in an un-inlined method. This method
89   // doesn't check if |authorization_| is null; that check should be in the
90   // inlined callers.
91   void FreeInternal();
92 
93   AuthorizationRef authorization_;
94 };
95 
96 }  // namespace base::mac
97 
98 #endif  // BASE_MAC_SCOPED_AUTHORIZATIONREF_H_
99