1 /*
2 * Copyright (C) 2025 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_itypes_utils.h"
17
18 #include <sstream>
19
20 #include "media_log.h"
21
22 namespace OHOS::Media::IPC::ITypeMediaUtil {
23 // Maximum value of IPC shared memory
24 static const size_t MAX_IPC_SIZE = 128 * 1024 * 1024;
25
26 template <typename T>
WriteBasicTypeToStream(std::ostringstream & oss,const T & value)27 bool WriteBasicTypeToStream(std::ostringstream &oss, const T &value)
28 {
29 oss.write(reinterpret_cast<const char *>(&value), sizeof(value));
30 return oss.good();
31 }
32
WriteStringToStream(std::ostringstream & oss,const std::string & str)33 bool WriteStringToStream(std::ostringstream &oss, const std::string &str)
34 {
35 // write string length
36 size_t len = str.length();
37 if (!WriteBasicTypeToStream(oss, len)) {
38 return false;
39 }
40 // write string data
41 if (len > 0) {
42 oss.write(str.data(), len);
43 }
44 return oss.good();
45 }
46
WriteStrVecToStream(std::ostringstream & oss,const std::vector<std::string> & strVec)47 bool WriteStrVecToStream(std::ostringstream &oss, const std::vector<std::string> &strVec)
48 {
49 // write vector size
50 size_t len = strVec.size();
51 if (!WriteBasicTypeToStream(oss, len)) {
52 return false;
53 }
54 for (const auto &str : strVec) {
55 if (!WriteStringToStream(oss, str)) {
56 return false;
57 }
58 }
59 return oss.good();
60 }
61
62 template <typename T>
ReadStreamToBasicType(std::istringstream & iss,T & value)63 bool ReadStreamToBasicType(std::istringstream &iss, T &value)
64 {
65 iss.read(reinterpret_cast<char *>(&value), sizeof(value));
66 return iss.good();
67 }
68
ReadStreamToString(std::istringstream & iss,std::string & str)69 bool ReadStreamToString(std::istringstream &iss, std::string &str)
70 {
71 // Get string length
72 size_t len;
73 if (!ReadStreamToBasicType(iss, len)) {
74 return false;
75 }
76 // Get string content
77 if (len > 0) {
78 str.resize(len, '\0');
79 iss.read(str.data(), len);
80 }
81 return iss.good();
82 }
83
ReadStreamToStrVec(std::istringstream & iss,std::vector<std::string> & strVec)84 bool ReadStreamToStrVec(std::istringstream &iss, std::vector<std::string> &strVec)
85 {
86 // Get vec length
87 size_t len;
88 if (!ReadStreamToBasicType(iss, len)) {
89 return false;
90 }
91 for (size_t i = 0; i < len; i++) {
92 std::string str;
93 if (!ReadStreamToString(iss, str)) {
94 return false;
95 }
96 strVec.push_back(str);
97 }
98 return iss.good();
99 }
100
MarshalStrVec(const std::vector<std::string> & strVec,MessageParcel & parcel)101 bool MarshalStrVec(const std::vector<std::string> &strVec, MessageParcel &parcel)
102 {
103 std::ostringstream oss;
104 if (!WriteStrVecToStream(oss, strVec)) {
105 MEDIA_ERR_LOG("WriteStrVecToStream failed.");
106 return false;
107 }
108 std::string str = oss.str();
109 size_t size = str.length();
110 if (size < 1 || size > MAX_IPC_SIZE) {
111 MEDIA_ERR_LOG("The length of strVec converted to string is invalid.");
112 return false;
113 }
114 if (!parcel.WriteUint32(static_cast<uint32_t>(size))) {
115 MEDIA_ERR_LOG("Write size failed.");
116 return false;
117 }
118 return parcel.WriteRawData(reinterpret_cast<const void *>(str.data()), size);
119 }
120
UnmarshalStrVec(std::vector<std::string> & strVec,MessageParcel & parcel)121 bool UnmarshalStrVec(std::vector<std::string> &strVec, MessageParcel &parcel)
122 {
123 size_t size = static_cast<size_t>(parcel.ReadUint32());
124 if (size < 1 || size > MAX_IPC_SIZE) {
125 MEDIA_ERR_LOG("The length of strVec converted to string is invalid.");
126 return false;
127 }
128 const char *buffer = reinterpret_cast<const char *>(parcel.ReadRawData(size));
129 if (buffer == nullptr) {
130 MEDIA_ERR_LOG("ReadRawData failed.");
131 return false;
132 }
133 std::istringstream iss(std::string(buffer, size));
134 return ReadStreamToStrVec(iss, strVec);
135 }
136 } // namespace OHOS::Media::IPC::ITypeMediaUtil
137