• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "common_func.h"
17 
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 
24 #include "../common/log.h"
25 #include "../common/napi/n_class.h"
26 #include "../common/napi/n_func_arg.h"
27 #include "../common/napi/n_val.h"
28 #include "../common/uni_error.h"
29 
30 namespace OHOS {
31 namespace DistributedFS {
32 namespace ModuleFileIO {
33 using namespace std;
34 
GetActualBuf(napi_env env,void * rawBuf,int64_t bufLen,NVal op)35 static tuple<bool, void *, int> GetActualBuf(napi_env env, void *rawBuf, int64_t bufLen, NVal op)
36 {
37     bool succ = false;
38     void *realBuf = nullptr;
39     int64_t opOffset = 0;
40     if (op.HasProp("offset")) {
41         tie(succ, opOffset) = op.GetProp("offset").ToInt64();
42         if (!succ || opOffset < 0) {
43             UniError(EINVAL).ThrowErr(env, "Invalid option.offset, positive integer is desired");
44             return { false, nullptr, opOffset };
45         } else if (opOffset > bufLen) {
46             UniError(EINVAL).ThrowErr(env, "Invalid option.offset, buffer limit exceeded");
47             return { false, nullptr, opOffset };
48         } else {
49             realBuf = static_cast<uint8_t *>(rawBuf) + opOffset;
50         }
51     } else {
52         realBuf = rawBuf;
53     }
54 
55     return { true, realBuf, opOffset };
56 }
57 
GetActualLen(napi_env env,int64_t bufLen,int64_t bufOff,NVal op)58 static tuple<bool, size_t> GetActualLen(napi_env env, int64_t bufLen, int64_t bufOff, NVal op)
59 {
60     bool succ = false;
61     int64_t retLen;
62 
63     if (op.HasProp("length")) {
64         int64_t opLength;
65         tie(succ, opLength) = op.GetProp("length").ToInt64();
66         if (!succ) {
67             UniError(EINVAL).ThrowErr(env, "Invalid option.length, expect integer");
68             return { false, 0 };
69         }
70         if (opLength < 0) {
71             retLen = bufLen - bufOff;
72         } else if (opLength + bufOff > bufLen) {
73             UniError(EINVAL).ThrowErr(env, "Invalid option.length, buffer limit exceeded");
74             return { false, 0 };
75         } else {
76             retLen = opLength;
77         }
78     } else {
79         retLen = bufLen - bufOff;
80     }
81 
82     return { true, retLen };
83 }
84 
GetCopyPathArg(napi_env env,napi_value srcPath,napi_value dstPath)85 tuple<bool, unique_ptr<char[]>, unique_ptr<char[]>> CommonFunc::GetCopyPathArg(napi_env env,
86     napi_value srcPath,
87     napi_value dstPath)
88 {
89     bool succ = false;
90     unique_ptr<char[]> src;
91     tie(succ, src, ignore) = NVal(env, srcPath).ToUTF8String();
92     if (!succ) {
93         return { false, nullptr, nullptr };
94     }
95 
96     unique_ptr<char[]> dest;
97     tie(succ, dest, ignore) = NVal(env, dstPath).ToUTF8String();
98     if (!succ) {
99         return { false, nullptr, nullptr };
100     }
101     return make_tuple(succ, move(src), move(dest));
102 }
103 
GetReadArg(napi_env env,napi_value readBuf,napi_value option)104 tuple<bool, void *, int64_t, bool, int64_t, int> CommonFunc::GetReadArg(napi_env env,
105                                                                         napi_value readBuf,
106                                                                         napi_value option)
107 {
108     bool succ = false;
109     void *retBuf = nullptr;
110     int64_t retLen;
111     bool posAssigned = false;
112     int64_t position;
113 
114     NVal txt(env, readBuf);
115     void *buf = nullptr;
116     int64_t bufLen;
117     int offset = 0;
118     tie(succ, buf, bufLen) = txt.ToArraybuffer();
119     if (!succ) {
120         UniError(EINVAL).ThrowErr(env, "Invalid read buffer, expect arraybuffer");
121         return { false, nullptr, 0, posAssigned, position, offset };
122     }
123 
124     NVal op = NVal(env, option);
125     tie(succ, retBuf, offset) = GetActualBuf(env, buf, bufLen, op);
126     if (!succ) {
127         return { false, nullptr, 0, posAssigned, position, offset };
128     }
129 
130     int64_t bufOff = static_cast<uint8_t *>(retBuf) - static_cast<uint8_t *>(buf);
131     tie(succ, retLen) = GetActualLen(env, bufLen, bufOff, op);
132     if (!succ) {
133         return { false, nullptr, 0, posAssigned, position, offset };
134     }
135 
136     tie(succ, position) = op.GetProp("position").ToInt64();
137     if (succ && position >= 0) {
138         posAssigned = true;
139     }
140     return { true, retBuf, retLen, posAssigned, position, offset };
141 }
142 
DecodeString(napi_env env,NVal jsStr,NVal encoding)143 static tuple<bool, unique_ptr<char[]>, int64_t> DecodeString(napi_env env, NVal jsStr, NVal encoding)
144 {
145     unique_ptr<char[]> buf;
146     if (!jsStr.TypeIs(napi_string)) {
147         return { false, nullptr, 0 };
148     }
149 
150     bool succ = false;
151     if (!encoding) {
152         return jsStr.ToUTF8String();
153     }
154 
155     unique_ptr<char[]> encodingBuf;
156     tie(succ, encodingBuf, ignore) = encoding.ToUTF8String();
157     if (!succ) {
158         return { false, nullptr, 0 };
159     }
160     string encodingStr(encodingBuf.release());
161     if (encodingStr == "utf-8") {
162         return jsStr.ToUTF8String();
163     } else if (encodingStr == "utf-16") {
164         return jsStr.ToUTF16String();
165     } else {
166         return { false, nullptr, 0 };
167     }
168 }
169 
170 // Is everthing ok? Do we need to free memory? What's the three args required by fwrite? Where to start writing?
GetWriteArg(napi_env env,napi_value argWBuf,napi_value argOption)171 tuple<bool, unique_ptr<char[]>, void *, int64_t, bool, int64_t> CommonFunc::GetWriteArg(napi_env env,
172                                                                                         napi_value argWBuf,
173                                                                                         napi_value argOption)
174 {
175     void *retBuf = nullptr;
176     int64_t retLen;
177     bool hasPos = false;
178     int64_t retPos;
179 
180     /* To get write buffer */
181     bool succ = false;
182     void *buf = nullptr;
183     int64_t bufLen;
184     NVal op(env, argOption);
185     NVal jsBuffer(env, argWBuf);
186     unique_ptr<char[]> bufferGuard;
187     tie(succ, bufferGuard, bufLen) = DecodeString(env, jsBuffer, op.GetProp("encoding"));
188     if (!succ) {
189         tie(succ, buf, bufLen) = NVal(env, argWBuf).ToArraybuffer();
190         if (!succ) {
191             UniError(EINVAL).ThrowErr(env, "Illegal write buffer or encoding");
192             return { false, nullptr, nullptr, 0, hasPos, retPos };
193         }
194     } else {
195         buf = bufferGuard.get();
196     }
197 
198     tie(succ, retBuf, ignore) = GetActualBuf(env, buf, bufLen, op);
199     if (!succ) {
200         return { false, nullptr, nullptr, 0, hasPos, retPos };
201     }
202 
203     int64_t bufOff = static_cast<uint8_t *>(retBuf) - static_cast<uint8_t *>(buf);
204     tie(succ, retLen) = GetActualLen(env, bufLen, bufOff, op);
205     if (!succ) {
206         return { false, nullptr, nullptr, 0, hasPos, retPos };
207     }
208 
209     /* To parse options - Where to begin writing */
210     if (op.HasProp("position")) {
211         int32_t position = 0;
212         tie(succ, position) = op.GetProp("position").ToInt32();
213         if (!succ || position < 0) {
214             UniError(EINVAL).ThrowErr(env, "option.position shall be positive number");
215             return { false, nullptr, nullptr, 0, hasPos, retPos };
216         }
217         hasPos = true;
218         retPos = position;
219     } else {
220         retPos = INVALID_POSITION;
221     }
222     return { true, move(bufferGuard), retBuf, retLen, hasPos, retPos };
223 }
224 } // namespace ModuleFileIO
225 } // namespace DistributedFS
226 } // namespace OHOS
227