1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "media_parcel.h"
17 #include "media_log.h"
18 
19 namespace {
20 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "MediaParcel"};
21 }
22 
23 namespace OHOS {
24 namespace Media {
DoMarshalling(MessageParcel & parcel,const Format & format)25 static bool DoMarshalling(MessageParcel &parcel, const Format &format)
26 {
27     auto dataMap = format.GetFormatMap();
28     (void)parcel.WriteUint32(dataMap.size());
29     for (auto it = dataMap.begin(); it != dataMap.end(); ++it) {
30         (void)parcel.WriteString(it->first);
31         (void)parcel.WriteUint32(it->second.type);
32         switch (it->second.type) {
33             case FORMAT_TYPE_INT32:
34                 (void)parcel.WriteInt32(it->second.val.int32Val);
35                 break;
36             case FORMAT_TYPE_INT64:
37                 (void)parcel.WriteInt64(it->second.val.int64Val);
38                 break;
39             case FORMAT_TYPE_FLOAT:
40                 (void)parcel.WriteFloat(it->second.val.floatVal);
41                 break;
42             case FORMAT_TYPE_DOUBLE:
43                 (void)parcel.WriteDouble(it->second.val.doubleVal);
44                 break;
45             case FORMAT_TYPE_STRING:
46                 (void)parcel.WriteString(it->second.stringVal);
47                 break;
48             case FORMAT_TYPE_ADDR:
49                 (void)parcel.WriteInt32(static_cast<int32_t>(it->second.size));
50                 (void)parcel.WriteBuffer(reinterpret_cast<const void *>(it->second.addr), it->second.size);
51                 break;
52             default:
53                 MEDIA_LOGE("fail to Marshalling Key: %{public}s", it->first.c_str());
54                 return false;
55         }
56         MEDIA_LOGD("success to Marshalling Key: %{public}s", it->first.c_str());
57     }
58     return true;
59 }
60 
Marshalling(MessageParcel & parcel,const Format & format)61 bool MediaParcel::Marshalling(MessageParcel &parcel, const Format &format)
62 {
63     auto vecMap = format.GetFormatVectorMap();
64     if (!vecMap.empty()) {
65         for (auto it = vecMap.begin(); it != vecMap.end(); ++it) {
66             uint32_t vecSize = static_cast<uint32_t>(it->second.size());
67             (void)parcel.WriteUint32(vecSize);
68             if (vecSize == 0) {
69                 MEDIA_LOGW("Marshal FormatVectorMap, vector is empty!");
70                 (void)parcel.WriteUint32(0);
71             } else {
72                 (void)parcel.WriteString(it->first);
73             }
74 
75             for (uint32_t index = 0; index < vecSize; index++) {
76                 CHECK_AND_RETURN_RET(DoMarshalling(parcel, it->second[index]), false);
77             }
78         }
79     } else {
80         (void)parcel.WriteUint32(0); // vecSize is 0
81         return DoMarshalling(parcel, format);
82     }
83 
84     return true;
85 }
86 
DoUnmarshalling(MessageParcel & parcel,Format & format)87 static bool DoUnmarshalling(MessageParcel &parcel, Format &format)
88 {
89     uint32_t size = parcel.ReadUint32();
90     constexpr uint32_t MAX_PARCEL_SIZE = 256;
91     CHECK_AND_RETURN_RET(size <= MAX_PARCEL_SIZE, false);
92     for (uint32_t index = 0; index < size; index++) {
93         std::string key = parcel.ReadString();
94         uint32_t valType = parcel.ReadUint32();
95         switch (valType) {
96             case FORMAT_TYPE_INT32:
97                 (void)format.PutIntValue(key, parcel.ReadInt32());
98                 break;
99             case FORMAT_TYPE_INT64:
100                 (void)format.PutLongValue(key, parcel.ReadInt64());
101                 break;
102             case FORMAT_TYPE_FLOAT:
103                 (void)format.PutFloatValue(key, parcel.ReadFloat());
104                 break;
105             case FORMAT_TYPE_DOUBLE:
106                 (void)format.PutDoubleValue(key, parcel.ReadDouble());
107                 break;
108             case FORMAT_TYPE_STRING:
109                 (void)format.PutStringValue(key, parcel.ReadString());
110                 break;
111             case FORMAT_TYPE_ADDR: {
112                 auto addrSize = parcel.ReadInt32();
113                 auto addr = parcel.ReadBuffer(static_cast<size_t>(addrSize));
114                 if (addr == nullptr) {
115                     MEDIA_LOGE("fail to ReadBuffer Key: %{public}s", key.c_str());
116                     return false;
117                 }
118                 (void)format.PutBuffer(key, addr, static_cast<size_t>(addrSize));
119                 break;
120             }
121             default:
122                 MEDIA_LOGE("fail to Unmarshalling Key: %{public}s", key.c_str());
123                 return false;
124         }
125         MEDIA_LOGD("success to Unmarshalling Key: %{public}s", key.c_str());
126     }
127 
128     return true;
129 }
130 
Unmarshalling(MessageParcel & parcel,Format & format)131 bool MediaParcel::Unmarshalling(MessageParcel &parcel, Format &format)
132 {
133     uint32_t vecSize = parcel.ReadUint32();
134     if (vecSize != 0) {
135         constexpr uint32_t MAX_PARCEL_SIZE = 256;
136         CHECK_AND_RETURN_RET(vecSize <= MAX_PARCEL_SIZE, false);
137         std::string key = parcel.ReadString();
138         std::vector<Format> vecFormat;
139         for (uint32_t index = 0; index < vecSize; index++) {
140             Format formatItem;
141             if (!DoUnmarshalling(parcel, formatItem)) {
142                 return false;
143             }
144             vecFormat.emplace_back(formatItem);
145         }
146         (void)format.PutFormatVector(key, vecFormat);
147     } else {
148         return DoUnmarshalling(parcel, format);
149     }
150 
151     return true;
152 }
153 } // namespace Media
154 } // namespace OHOS
155