xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/var_reg.h (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SANDBOXED_API_VAR_REG_H_
16 #define SANDBOXED_API_VAR_REG_H_
17 
18 #include <algorithm>
19 #include <cstring>
20 #include <iostream>
21 #include <string>
22 #include <type_traits>
23 
24 #include "absl/strings/str_format.h"
25 #include "sandboxed_api/var_abstract.h"
26 
27 namespace sapi::v {
28 
29 // The super-class for Reg. Specified as a class, so it can be used as a
30 // type specifier in methods.
31 class Callable : public Var {
32  public:
33   // Get pointer to the stored data.
34   virtual const void* GetDataPtr() = 0;
35 
36   // Set internal data from ptr.
37   virtual void SetDataFromPtr(const void* ptr, size_t max_sz) = 0;
38 
39   // Get data from internal ptr.
GetDataFromPtr(void * ptr,size_t max_sz)40   void GetDataFromPtr(void* ptr, size_t max_sz) {
41     size_t min_sz = std::min<size_t>(GetSize(), max_sz);
42     memcpy(ptr, GetDataPtr(), min_sz);
43   }
44 
45  protected:
46   Callable() = default;
47 };
48 
49 // class Reg represents register-sized variables.
50 template <typename T>
51 class Reg : public Callable {
52  public:
53   static_assert(std::is_integral_v<T> || std::is_floating_point_v<T> ||
54                     std::is_pointer_v<T> || std::is_enum_v<T>,
55                 "Only register-sized types are allowed as template argument "
56                 "for class Reg.");
57 
58   explicit Reg(const T value = {}) {
59     value_ = value;
60     SetLocal(&value_);
61   }
62 
63   // Getter/Setter for the stored value.
GetValue()64   virtual T GetValue() const { return value_; }
SetValue(T value)65   virtual void SetValue(T value) { value_ = value; }
66 
GetDataPtr()67   const void* GetDataPtr() override {
68     return reinterpret_cast<const void*>(&value_);
69   }
SetDataFromPtr(const void * ptr,size_t max_sz)70   void SetDataFromPtr(const void* ptr, size_t max_sz) override {
71     memcpy(&value_, ptr, std::min(GetSize(), max_sz));
72   }
73 
GetSize()74   size_t GetSize() const override { return sizeof(T); }
75 
76   Type GetType() const override;
77 
78   std::string GetTypeString() const override;
79 
80   std::string ToString() const override;
81 
82  protected:
83   // The stored value.
84   T value_;
85 };
86 
87 template <typename T>
GetType()88 Type Reg<T>::GetType() const {
89   if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
90     return Type::kInt;
91   }
92   if constexpr (std::is_floating_point_v<T>) {
93     return Type::kFloat;
94   }
95   if constexpr (std::is_pointer_v<T>) {
96     return Type::kPointer;
97   }
98   // Not reached
99 }
100 
101 template <typename T>
GetTypeString()102 std::string Reg<T>::GetTypeString() const {
103   if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
104     return "Integer";
105   }
106   if constexpr (std::is_floating_point_v<T>) {
107     return "Floating-point";
108   }
109   if constexpr (std::is_pointer_v<T>) {
110     return "Pointer";
111   }
112   // Not reached
113 }
114 
115 template <typename T>
ToString()116 std::string Reg<T>::ToString() const {
117   if constexpr (std::is_integral_v<T>) {
118     return std::to_string(value_);
119   }
120   if constexpr (std::is_enum_v<T>) {
121     return std::to_string(static_cast<std::underlying_type_t<T>>(value_));
122   }
123   if constexpr (std::is_floating_point_v<T>) {
124     return absl::StrFormat("%.10f", value_);
125   }
126   if constexpr (std::is_pointer<T>::value) {
127     return absl::StrFormat("%p", value_);
128   }
129   // Not reached.
130 }
131 
132 }  // namespace sapi::v
133 
134 #endif  // SANDBOXED_API_VAR_REG_H_
135