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