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 "parcel/common.hh"
18 #include "parcel/log_private.hh"
19 #include "parcel/parcel.hh"
20 #include "parcel/parcel_implementation.hh"
21 #include "parcel/parcelable.hh"
23 namespace tizen_base {
25 Parcel::Impl::Impl(Parcel* parent) : parent_(parent) {
28 Parcel::Impl::~Impl() = default;
30 void Parcel::Impl::Write(const void* buf, uint32_t size) {
31 auto* p = reinterpret_cast<const uint8_t*>(buf);
32 std::copy(p, p + size, std::back_inserter(data_));
35 int Parcel::Impl::Read(void* buf, uint32_t size) {
36 if (data_.size() == 0)
37 return TIZEN_ERROR_NO_DATA;
39 if (reader_ + size > data_.size())
40 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
42 auto* p = reinterpret_cast<uint8_t*>(buf);
43 std::copy(&data_[reader_], &data_[reader_] + size, p);
45 set_last_result(TIZEN_ERROR_NONE);
46 return TIZEN_ERROR_NONE;
49 const std::vector<uint8_t>& Parcel::Impl::GetRaw() {
53 void Parcel::Impl::ResetReader() {
57 void Parcel::Impl::Clear() {
62 void Parcel::Impl::Reset(const void* buf, uint32_t size) {
67 bool Parcel::Impl::IsEmpty() {
68 return data_.size() == 0;
71 void Parcel::Impl::WriteSize(uint32_t size) {
72 auto* p = reinterpret_cast<uint8_t*>(&size);
73 std::copy(p, p + sizeof(size), std::back_inserter(data_));
77 void Parcel::Impl::Write(T d) {
78 auto* p = reinterpret_cast<uint8_t*>(&d);
79 std::copy(p, p + sizeof(T), std::back_inserter(data_));
82 int Parcel::Impl::ReadSize(uint32_t* size) {
83 if (data_.size() == 0)
84 return TIZEN_ERROR_NO_DATA;
86 if (reader_ + sizeof(uint32_t) > data_.size())
87 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
89 auto* p = reinterpret_cast<uint8_t*>(size);
90 std::copy(&data_[reader_], &data_[reader_] + sizeof(uint32_t), p);
91 reader_ += sizeof(uint32_t);
92 return TIZEN_ERROR_NONE;
96 int Parcel::Impl::Read(T* d) {
97 uint32_t size = sizeof(T);
98 if (reader_ + size > data_.size())
99 return TIZEN_ERROR_ILLEGAL_BYTE_SEQ;
101 auto* p = reinterpret_cast<uint8_t*>(d);
102 std::copy(&data_[reader_], &data_[reader_] + size, p);
104 return TIZEN_ERROR_NONE;
107 Parcel::Parcel() : impl_(new Impl(this)) {
110 Parcel::Parcel(const void* buf, uint32_t size) : impl_(new Impl(this)) {
111 impl_->Write(buf, size);
114 Parcel::~Parcel() = default;
116 Parcel::Parcel(const Parcel& p)
117 : impl_(new Impl(this)) {
118 std::copy(p.impl_->data_.begin(), p.impl_->data_.end(),
119 std::back_inserter(impl_->data_));
120 impl_->reader_ = p.impl_->reader_;
123 Parcel& Parcel::operator = (const Parcel& p) {
125 std::copy(p.impl_->data_.begin(), p.impl_->data_.end(),
126 std::back_inserter(impl_->data_));
127 impl_->reader_ = p.impl_->reader_;
132 Parcel::Parcel(Parcel&& p) noexcept {
133 impl_ = std::move(p.impl_);
134 impl_->parent_ = this;
137 Parcel& Parcel::operator = (Parcel&& p) noexcept {
139 impl_->data_ = std::move(p.impl_->data_);
140 impl_->reader_ = p.impl_->reader_;
141 p.impl_->reader_ = 0;
146 bool Parcel::IsEmpty() const noexcept {
147 return impl_->IsEmpty();
150 void Parcel::Write(const void* buf, uint32_t size) {
151 impl_->Write(buf, size);
154 int Parcel::Read(void* buf, uint32_t size) {
155 return impl_->Read(buf, size);
158 void Parcel::WriteBool(bool val) {
159 impl_->Write<bool>(val);
162 void Parcel::WriteByte(char val) {
163 impl_->Write<char>(val);
166 void Parcel::WriteUInt16(uint16_t val) {
167 impl_->Write<uint16_t>(val);
170 void Parcel::WriteUInt32(uint32_t val) {
171 impl_->Write<uint32_t>(val);
174 void Parcel::WriteUInt64(uint64_t val) {
175 impl_->Write<uint64_t>(val);
178 void Parcel::WriteInt16(int16_t val) {
179 impl_->Write<int16_t>(val);
182 void Parcel::WriteInt32(int32_t val) {
183 impl_->Write<int32_t>(val);
186 void Parcel::WriteInt64(int64_t val) {
187 impl_->Write<int64_t>(val);
190 void Parcel::WriteFloat(float val) {
191 impl_->Write<float>(val);
194 void Parcel::WriteDouble(double val) {
195 impl_->Write<double>(val);
198 void Parcel::WriteString(const std::string& str) {
199 impl_->WriteSize(str.length() + 1);
200 impl_->Write(str.c_str(), str.length() + 1);
203 void Parcel::WriteCString(const char* str) {
204 impl_->WriteSize(strlen(str) + 1);
205 impl_->Write(str, strlen(str) + 1);
208 int Parcel::ReadBool(bool* val) {
209 return impl_->Read<bool>(val);
212 int Parcel::ReadByte(char* val) {
213 return impl_->Read<char>(val);
216 int Parcel::ReadUInt16(uint16_t* val) {
217 return impl_->Read<uint16_t>(val);
220 int Parcel::ReadUInt32(uint32_t* val) {
221 return impl_->Read<uint32_t>(val);
224 int Parcel::ReadUInt64(uint64_t* val) {
225 return impl_->Read<uint64_t>(val);
228 int Parcel::ReadInt16(int16_t* val) {
229 return impl_->Read<int16_t>(val);
232 int Parcel::ReadInt32(int32_t* val) {
233 return impl_->Read<int32_t>(val);
236 int Parcel::ReadInt64(int64_t* val) {
237 return impl_->Read<int64_t>(val);
240 int Parcel::ReadFloat(float* val) {
241 return impl_->Read<float>(val);
244 int Parcel::ReadDouble(double* val) {
245 return impl_->Read<double>(val);
248 std::string Parcel::ReadString() {
250 int ret = impl_->ReadSize(&len);
251 if (ret != TIZEN_ERROR_NONE) {
252 set_last_result(ret);
256 char* str = new (std::nothrow) char [len];
257 if (str == nullptr) {
258 set_last_result(TIZEN_ERROR_OUT_OF_MEMORY);
262 auto ptr = std::unique_ptr<char[]>(str);
263 ret = impl_->Read(str, len);
264 if (ret != TIZEN_ERROR_NONE) {
265 set_last_result(ret);
269 set_last_result(TIZEN_ERROR_NONE);
270 return std::string(str);
273 int Parcel::ReadCString(char** str) {
275 int ret = impl_->ReadSize(&len);
276 if (ret != TIZEN_ERROR_NONE)
279 char* val = static_cast<char*>(calloc(len, sizeof(char)));
281 return TIZEN_ERROR_OUT_OF_MEMORY;
283 ret = impl_->Read(val, len);
284 if (ret != TIZEN_ERROR_NONE) {
290 return TIZEN_ERROR_NONE;
293 const std::vector<uint8_t>& Parcel::GetRaw() {
294 return impl_->GetRaw();
297 void Parcel::ResetReader() {
298 impl_->ResetReader();
301 void Parcel::Clear() {
305 void Parcel::Reset(const void* buf, uint32_t size) {
306 impl_->Reset(buf, size);
309 void Parcel::WriteParcelable(const Parcelable& parcelable) {
310 parcelable.WriteToParcel(this);
313 int Parcel::ReadParcelable(Parcelable* parcelable) {
314 parcelable->ReadFromParcel(this);
315 return TIZEN_ERROR_NONE;
318 } // naemspace tizen_base