1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16#define LOG_TAG "HidlSupport" 17 18#include <hidl/HidlSupport.h> 19 20#include <unordered_map> 21 22#include <android-base/logging.h> 23#include <android-base/parseint.h> 24 25namespace android { 26namespace hardware { 27 28namespace details { 29bool debuggable() { 30#ifdef LIBHIDL_TARGET_DEBUGGABLE 31 return true; 32#else 33 return false; 34#endif 35} 36} // namespace details 37 38hidl_handle::hidl_handle() { 39 mHandle = nullptr; 40 mOwnsHandle = false; 41} 42 43hidl_handle::~hidl_handle() { 44 freeHandle(); 45} 46 47hidl_handle::hidl_handle(const native_handle_t *handle) { 48 mHandle = handle; 49 mOwnsHandle = false; 50} 51 52// copy constructor. 53hidl_handle::hidl_handle(const hidl_handle &other) { 54 mOwnsHandle = false; 55 *this = other; 56} 57 58// move constructor. 59hidl_handle::hidl_handle(hidl_handle &&other) { 60 mOwnsHandle = false; 61 *this = std::move(other); 62} 63 64// assignment operators 65hidl_handle &hidl_handle::operator=(const hidl_handle &other) { 66 if (this == &other) { 67 return *this; 68 } 69 freeHandle(); 70 if (other.mHandle != nullptr) { 71 mHandle = native_handle_clone(other.mHandle); 72 if (mHandle == nullptr) { 73 LOG(FATAL) << "Failed to clone native_handle in hidl_handle."; 74 } 75 mOwnsHandle = true; 76 } else { 77 mHandle = nullptr; 78 mOwnsHandle = false; 79 } 80 return *this; 81} 82 83hidl_handle &hidl_handle::operator=(const native_handle_t *native_handle) { 84 freeHandle(); 85 mHandle = native_handle; 86 mOwnsHandle = false; 87 return *this; 88} 89 90hidl_handle &hidl_handle::operator=(hidl_handle &&other) { 91 if (this != &other) { 92 freeHandle(); 93 mHandle = other.mHandle; 94 mOwnsHandle = other.mOwnsHandle; 95 other.mHandle = nullptr; 96 other.mOwnsHandle = false; 97 } 98 return *this; 99} 100 101void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) { 102 freeHandle(); 103 mHandle = handle; 104 mOwnsHandle = shouldOwn; 105} 106 107const native_handle_t* hidl_handle::operator->() const { 108 return mHandle; 109} 110 111// implicit conversion to const native_handle_t* 112hidl_handle::operator const native_handle_t *() const { 113 return mHandle; 114} 115 116// explicit conversion 117const native_handle_t *hidl_handle::getNativeHandle() const { 118 return mHandle; 119} 120 121void hidl_handle::freeHandle() { 122 if (mOwnsHandle && mHandle != nullptr) { 123 // This can only be true if: 124 // 1. Somebody called setTo() with shouldOwn=true, so we know the handle 125 // wasn't const to begin with. 126 // 2. Copy/assignment from another hidl_handle, in which case we have 127 // cloned the handle. 128 // 3. Move constructor from another hidl_handle, in which case the original 129 // hidl_handle must have been non-const as well. 130 native_handle_t *handle = const_cast<native_handle_t*>( 131 static_cast<const native_handle_t*>(mHandle)); 132 native_handle_close(handle); 133 native_handle_delete(handle); 134 mHandle = nullptr; 135 } 136} 137 138static const char *const kEmptyString = ""; 139 140hidl_string::hidl_string() 141 : mBuffer(kEmptyString), 142 mSize(0), 143 mOwnsBuffer(false) { 144} 145 146hidl_string::~hidl_string() { 147 clear(); 148} 149 150hidl_string::hidl_string(const char *s) : hidl_string() { 151 if (s == nullptr) { 152 return; 153 } 154 155 copyFrom(s, strlen(s)); 156} 157 158hidl_string::hidl_string(const char *s, size_t length) : hidl_string() { 159 copyFrom(s, length); 160} 161 162hidl_string::hidl_string(const hidl_string &other): hidl_string() { 163 copyFrom(other.c_str(), other.size()); 164} 165 166hidl_string::hidl_string(const std::string &s) : hidl_string() { 167 copyFrom(s.c_str(), s.size()); 168} 169 170hidl_string::hidl_string(hidl_string &&other): hidl_string() { 171 moveFrom(std::forward<hidl_string>(other)); 172} 173 174hidl_string &hidl_string::operator=(hidl_string &&other) { 175 if (this != &other) { 176 clear(); 177 moveFrom(std::forward<hidl_string>(other)); 178 } 179 return *this; 180} 181 182hidl_string &hidl_string::operator=(const hidl_string &other) { 183 if (this != &other) { 184 clear(); 185 copyFrom(other.c_str(), other.size()); 186 } 187 188 return *this; 189} 190 191hidl_string &hidl_string::operator=(const char *s) { 192 clear(); 193 194 if (s == nullptr) { 195 return *this; 196 } 197 198 copyFrom(s, strlen(s)); 199 return *this; 200} 201 202hidl_string &hidl_string::operator=(const std::string &s) { 203 clear(); 204 copyFrom(s.c_str(), s.size()); 205 return *this; 206} 207 208hidl_string::operator std::string() const { 209 return std::string(mBuffer, mSize); 210} 211 212std::ostream& operator<<(std::ostream& os, const hidl_string& str) { 213 os << str.c_str(); 214 return os; 215} 216 217void hidl_string::copyFrom(const char *data, size_t size) { 218 // assume my resources are freed. 219 220 if (size > UINT32_MAX) { 221 LOG(FATAL) << "string size can't exceed 2^32 bytes."; 222 } 223 char *buf = (char *)malloc(size + 1); 224 memcpy(buf, data, size); 225 buf[size] = '\0'; 226 mBuffer = buf; 227 228 mSize = static_cast<uint32_t>(size); 229 mOwnsBuffer = true; 230} 231 232void hidl_string::moveFrom(hidl_string &&other) { 233 // assume my resources are freed. 234 235 mBuffer = std::move(other.mBuffer); 236 mSize = other.mSize; 237 mOwnsBuffer = other.mOwnsBuffer; 238 239 other.mOwnsBuffer = false; 240 other.clear(); 241} 242 243void hidl_string::clear() { 244 if (mOwnsBuffer && (mBuffer != kEmptyString)) { 245 free(const_cast<char *>(static_cast<const char *>(mBuffer))); 246 } 247 248 mBuffer = kEmptyString; 249 mSize = 0; 250 mOwnsBuffer = false; 251} 252 253void hidl_string::setToExternal(const char *data, size_t size) { 254 if (size > UINT32_MAX) { 255 LOG(FATAL) << "string size can't exceed 2^32 bytes."; 256 } 257 clear(); 258 259 mBuffer = data; 260 mSize = static_cast<uint32_t>(size); 261 mOwnsBuffer = false; 262} 263 264const char *hidl_string::c_str() const { 265 return mBuffer; 266} 267 268size_t hidl_string::size() const { 269 return mSize; 270} 271 272bool hidl_string::empty() const { 273 return mSize == 0; 274} 275 276} // namespace hardware 277} // namespace android 278 279 280