// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SANDBOXED_API_VAR_REG_H_ #define SANDBOXED_API_VAR_REG_H_ #include #include #include #include #include #include "absl/strings/str_format.h" #include "sandboxed_api/var_abstract.h" namespace sapi::v { // The super-class for Reg. Specified as a class, so it can be used as a // type specifier in methods. class Callable : public Var { public: // Get pointer to the stored data. virtual const void* GetDataPtr() = 0; // Set internal data from ptr. virtual void SetDataFromPtr(const void* ptr, size_t max_sz) = 0; // Get data from internal ptr. void GetDataFromPtr(void* ptr, size_t max_sz) { size_t min_sz = std::min(GetSize(), max_sz); memcpy(ptr, GetDataPtr(), min_sz); } protected: Callable() = default; }; // class Reg represents register-sized variables. template class Reg : public Callable { public: static_assert(std::is_integral_v || std::is_floating_point_v || std::is_pointer_v || std::is_enum_v, "Only register-sized types are allowed as template argument " "for class Reg."); explicit Reg(const T value = {}) { value_ = value; SetLocal(&value_); } // Getter/Setter for the stored value. virtual T GetValue() const { return value_; } virtual void SetValue(T value) { value_ = value; } const void* GetDataPtr() override { return reinterpret_cast(&value_); } void SetDataFromPtr(const void* ptr, size_t max_sz) override { memcpy(&value_, ptr, std::min(GetSize(), max_sz)); } size_t GetSize() const override { return sizeof(T); } Type GetType() const override; std::string GetTypeString() const override; std::string ToString() const override; protected: // The stored value. T value_; }; template Type Reg::GetType() const { if constexpr (std::is_integral_v || std::is_enum_v) { return Type::kInt; } if constexpr (std::is_floating_point_v) { return Type::kFloat; } if constexpr (std::is_pointer_v) { return Type::kPointer; } // Not reached } template std::string Reg::GetTypeString() const { if constexpr (std::is_integral_v || std::is_enum_v) { return "Integer"; } if constexpr (std::is_floating_point_v) { return "Floating-point"; } if constexpr (std::is_pointer_v) { return "Pointer"; } // Not reached } template std::string Reg::ToString() const { if constexpr (std::is_integral_v) { return std::to_string(value_); } if constexpr (std::is_enum_v) { return std::to_string(static_cast>(value_)); } if constexpr (std::is_floating_point_v) { return absl::StrFormat("%.10f", value_); } if constexpr (std::is_pointer::value) { return absl::StrFormat("%p", value_); } // Not reached. } } // namespace sapi::v #endif // SANDBOXED_API_VAR_REG_H_