2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "include/bundle_cpp.h"
18 #include "parcel/common.hh"
19 #include "parcel/log_private.hh"
20 #include "parcel/parcel.hh"
21 #include "parcel/parcel_implementation.hh"
22 #include "parcel/parcelable.hh"
24 namespace tizen_base {
26 Parcel::Impl::Impl(Parcel* parent) : parent_(parent) {
29 Parcel::Impl::~Impl() = default;
31 void Parcel::Impl::Write(const void* buf, uint32_t size) {
32 auto* p = reinterpret_cast<const uint8_t*>(buf);
33 std::copy(p, p + size, std::back_inserter(data_));
36 int Parcel::Impl::Read(void* buf, uint32_t size) {
37 if (data_.size() == 0)
38 return TIZEN_ERROR_NO_DATA;
40 if (reader_ + size > data_.size())
41 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
43 auto* p = reinterpret_cast<uint8_t*>(buf);
44 std::copy(&data_[reader_], &data_[reader_] + size, p);
46 set_last_result(TIZEN_ERROR_NONE);
47 return TIZEN_ERROR_NONE;
50 const std::vector<uint8_t>& Parcel::Impl::GetRaw() {
54 void Parcel::Impl::ResetReader() {
58 void Parcel::Impl::Clear() {
63 void Parcel::Impl::Reset(const void* buf, uint32_t size) {
68 bool Parcel::Impl::IsEmpty() {
69 return data_.size() == 0;
72 void Parcel::Impl::WriteSize(uint32_t size) {
73 auto* p = reinterpret_cast<uint8_t*>(&size);
74 std::copy(p, p + sizeof(size), std::back_inserter(data_));
78 void Parcel::Impl::Write(T d) {
80 auto* p = reinterpret_cast<uint8_t*>(&d);
81 std::copy(p, p + sizeof(T), std::back_inserter(data_));
84 int Parcel::Impl::ReadSize(uint32_t* size) {
85 if (data_.size() == 0)
86 return TIZEN_ERROR_NO_DATA;
88 if (reader_ + sizeof(uint32_t) > data_.size())
89 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
91 auto* p = reinterpret_cast<uint8_t*>(size);
92 std::copy(&data_[reader_], &data_[reader_] + sizeof(uint32_t), p);
93 reader_ += sizeof(uint32_t);
94 return TIZEN_ERROR_NONE;
98 int Parcel::Impl::Read(T* d) {
100 int ret = ReadSize(&size);
101 if (ret != TIZEN_ERROR_NONE)
104 if (size == 0 || size != sizeof(T))
105 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
107 if (reader_ + size > data_.size())
108 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
110 auto* p = reinterpret_cast<uint8_t*>(d);
111 std::copy(&data_[reader_], &data_[reader_] + size, p);
113 return TIZEN_ERROR_NONE;
116 Parcel::Parcel() : impl_(new Impl(this)) {
119 Parcel::Parcel(const void* buf, uint32_t size) : impl_(new Impl(this)) {
120 impl_->Write(buf, size);
123 Parcel::~Parcel() = default;
125 Parcel::Parcel(const Parcel& p)
126 : impl_(new Impl(this)) {
127 std::copy(p.impl_->data_.begin(), p.impl_->data_.end(),
128 std::back_inserter(impl_->data_));
129 impl_->reader_ = p.impl_->reader_;
132 Parcel& Parcel::operator = (const Parcel& p) {
134 std::copy(p.impl_->data_.begin(), p.impl_->data_.end(),
135 std::back_inserter(impl_->data_));
136 impl_->reader_ = p.impl_->reader_;
141 Parcel::Parcel(Parcel&& p) noexcept {
142 impl_ = std::move(p.impl_);
143 impl_->parent_ = this;
146 Parcel& Parcel::operator = (Parcel&& p) noexcept {
148 impl_->data_ = std::move(p.impl_->data_);
149 impl_->reader_ = p.impl_->reader_;
150 p.impl_->reader_ = 0;
155 bool Parcel::IsEmpty() const noexcept {
156 return impl_->IsEmpty();
159 void Parcel::Write(const void* buf, uint32_t size) {
160 impl_->Write(buf, size);
163 int Parcel::Read(void* buf, uint32_t size) {
164 return impl_->Read(buf, size);
167 void Parcel::WriteBool(bool val) {
168 impl_->Write<bool>(val);
171 void Parcel::WriteByte(char val) {
172 impl_->Write<char>(val);
175 void Parcel::WriteUInt16(uint16_t val) {
176 impl_->Write<uint16_t>(val);
179 void Parcel::WriteUInt32(uint32_t val) {
180 impl_->Write<uint32_t>(val);
183 void Parcel::WriteUInt64(uint64_t val) {
184 impl_->Write<uint64_t>(val);
187 void Parcel::WriteInt16(int16_t val) {
188 impl_->Write<int16_t>(val);
191 void Parcel::WriteInt32(int32_t val) {
192 impl_->Write<int32_t>(val);
195 void Parcel::WriteInt64(int64_t val) {
196 impl_->Write<int64_t>(val);
199 void Parcel::WriteFloat(float val) {
200 impl_->Write<float>(val);
203 void Parcel::WriteDouble(double val) {
204 impl_->Write<double>(val);
207 void Parcel::WriteString(const std::string& str) {
208 impl_->WriteSize(str.length() + 1);
209 impl_->Write(str.c_str(), str.length() + 1);
212 void Parcel::WriteCString(const char* str) {
213 impl_->WriteSize(strlen(str) + 1);
214 impl_->Write(str, strlen(str) + 1);
217 void Parcel::WriteCBundle(bundle* b) {
218 bundle_raw* raw = nullptr;
220 bundle_encode(b, &raw, &len);
221 auto ptr = std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free);
223 auto* p = reinterpret_cast<void*>(raw);
224 impl_->WriteSize(len + 1);
225 impl_->Write(p, len + 1);
228 void Parcel::WriteBundle(const Bundle& b) {
229 auto raw = const_cast<Bundle&>(b).ToRaw();
230 auto* p = reinterpret_cast<void*>(raw.first.get());
231 impl_->WriteSize(raw.second + 1);
232 impl_->Write(p, raw.second + 1);
235 int Parcel::ReadBool(bool* val) {
236 return impl_->Read<bool>(val);
239 int Parcel::ReadByte(char* val) {
240 return impl_->Read<char>(val);
243 int Parcel::ReadUInt16(uint16_t* val) {
244 return impl_->Read<uint16_t>(val);
247 int Parcel::ReadUInt32(uint32_t* val) {
248 return impl_->Read<uint32_t>(val);
251 int Parcel::ReadUInt64(uint64_t* val) {
252 return impl_->Read<uint64_t>(val);
255 int Parcel::ReadInt16(int16_t* val) {
256 return impl_->Read<int16_t>(val);
259 int Parcel::ReadInt32(int32_t* val) {
260 return impl_->Read<int32_t>(val);
263 int Parcel::ReadInt64(int64_t* val) {
264 return impl_->Read<int64_t>(val);
267 int Parcel::ReadFloat(float* val) {
268 return impl_->Read<float>(val);
271 int Parcel::ReadDouble(double* val) {
272 return impl_->Read<double>(val);
275 std::string Parcel::ReadString() {
277 int ret = impl_->ReadSize(&len);
278 if (ret != TIZEN_ERROR_NONE) {
279 set_last_result(ret);
283 char* str = new (std::nothrow) char [len];
284 if (str == nullptr) {
285 set_last_result(TIZEN_ERROR_OUT_OF_MEMORY);
289 auto ptr = std::unique_ptr<char[]>(str);
290 ret = impl_->Read(str, len);
291 if (ret != TIZEN_ERROR_NONE) {
292 set_last_result(ret);
296 set_last_result(TIZEN_ERROR_NONE);
297 return std::string(str);
300 int Parcel::ReadCString(char** str) {
302 int ret = impl_->ReadSize(&len);
303 if (ret != TIZEN_ERROR_NONE)
306 char* val = static_cast<char*>(calloc(len, sizeof(char)));
308 return TIZEN_ERROR_OUT_OF_MEMORY;
310 ret = impl_->Read(val, len);
311 if (ret != TIZEN_ERROR_NONE) {
317 return TIZEN_ERROR_NONE;
320 int Parcel::ReadCBundle(bundle** b) {
322 int ret = impl_->ReadSize(&len);
323 if (ret != TIZEN_ERROR_NONE)
326 uint8_t* raw = new (std::nothrow) uint8_t [len];
328 return TIZEN_ERROR_OUT_OF_MEMORY;
330 auto ptr = std::unique_ptr<uint8_t[]>(raw);
331 ret = impl_->Read(raw, len);
332 if (ret != TIZEN_ERROR_NONE)
335 *b = bundle_decode(reinterpret_cast<bundle_raw*>(raw), len);
337 return get_last_result();
339 return TIZEN_ERROR_NONE;
342 Bundle Parcel::ReadBundle() {
344 int ret = impl_->ReadSize(&len);
345 if (ret != TIZEN_ERROR_NONE) {
346 set_last_result(ret);
350 uint8_t* raw = new (std::nothrow) uint8_t [len];
351 if (raw == nullptr) {
352 set_last_result(TIZEN_ERROR_OUT_OF_MEMORY);
356 auto ptr = std::unique_ptr<uint8_t[]>(raw);
357 ret = impl_->Read(raw, len);
358 if (ret != TIZEN_ERROR_NONE) {
359 set_last_result(ret);
363 bundle* b = bundle_decode(reinterpret_cast<bundle_raw*>(raw), len);
367 set_last_result(TIZEN_ERROR_NONE);
368 return Bundle(b, false, true);
371 const std::vector<uint8_t>& Parcel::GetRaw() {
372 return impl_->GetRaw();
375 void Parcel::ResetReader() {
376 impl_->ResetReader();
379 void Parcel::Clear() {
383 void Parcel::Reset(const void* buf, uint32_t size) {
384 impl_->Reset(buf, size);
387 void Parcel::WriteParcelable(const Parcelable& parcelable) {
388 impl_->Write<int32_t>(1);
389 parcelable.WriteToParcel(this);
392 int Parcel::ReadParcelable(Parcelable* parcelable) {
393 int32_t has_parcelable = 0;
394 int ret = impl_->Read<int32_t>(&has_parcelable);
395 if (ret != TIZEN_ERROR_NONE)
398 if (has_parcelable != 1)
399 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
401 parcelable->ReadFromParcel(this);
402 return TIZEN_ERROR_NONE;
405 } // naemspace tizen_base