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 #include "lseek.h"
16 #include <cstring>
17 #include <tuple>
18 #include <unistd.h>
19 
20 #include "../../common/napi/n_async/n_async_work_callback.h"
21 #include "../../common/napi/n_async/n_async_work_promise.h"
22 #include "../../common/napi/n_func_arg.h"
23 namespace OHOS {
24 namespace DistributedFS {
25 namespace ModuleFileIO {
26 using namespace std;
27 
GetLseekArg(napi_env env,const NFuncArg & funcArg)28 static tuple<bool, int, int, int> GetLseekArg(napi_env env, const NFuncArg &funcArg)
29 {
30     auto [resGetFirstArg, fd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32();
31     if (!resGetFirstArg) {
32         UniError(EINVAL).ThrowErr(env, "Invalid fd");
33         return { false, -1, -1, -1 };
34     }
35 
36     auto [resGetSecondArg, offset] = NVal(env, funcArg[NARG_POS::SECOND]).ToInt32();
37     if (!resGetSecondArg) {
38         UniError(EINVAL).ThrowErr(env, "Invalid offset");
39         return { false, -1, -1, -1 };
40     }
41 
42     auto [resGetThirdArg, whence] = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32();
43     if (!resGetThirdArg) {
44         UniError(EINVAL).ThrowErr(env, "Invalid whence");
45         return { false, -1, -1, -1 };
46     }
47 
48     return { true, fd, offset, whence };
49 }
50 
Sync(napi_env env,napi_callback_info info)51 napi_value Lseek::Sync(napi_env env, napi_callback_info info)
52 {
53     NFuncArg funcArg(env, info);
54     if (!funcArg.InitArgs(NARG_CNT::THREE)) {
55         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
56         return nullptr;
57     }
58 
59     auto [resGetLseekArg, fd, offset, whence] = GetLseekArg(env, funcArg);
60     if (!resGetLseekArg) {
61         return nullptr;
62     }
63 
64     int ret = lseek(fd, offset, whence);
65     if (ret == -1) {
66         UniError(errno).ThrowErr(env);
67         return nullptr;
68     }
69 
70     return NVal::CreateInt64(env, ret).val_;
71 }
72 
Async(napi_env env,napi_callback_info info)73 napi_value Lseek::Async(napi_env env, napi_callback_info info)
74 {
75     NFuncArg funcArg(env, info);
76     if (!funcArg.InitArgs(NARG_CNT::THREE, NARG_CNT::FOUR)) {
77         UniError(EINVAL).ThrowErr(env, "Number of arguments unmatched");
78         return nullptr;
79     }
80 
81     auto [resGetLseekArg, fd, offset, whence] = GetLseekArg(env, funcArg);
82     if (!resGetLseekArg) {
83         return nullptr;
84     }
85 
86     auto arg = make_shared<int32_t>();
87     auto cbExec = [fd = fd, offset = offset, whence = whence, arg](napi_env env) -> UniError {
88         int ret = lseek(fd, offset, whence);
89         *arg = ret;
90         if (ret == -1) {
91             return UniError(errno);
92         } else {
93             return UniError(ERRNO_NOERR);
94         }
95     };
96 
97     auto cbComplCallback = [arg](napi_env env, UniError err) -> NVal {
98         if (err) {
99             return { env, err.GetNapiErr(env) };
100         }
101         return { NVal::CreateInt64(env, *arg) };
102     };
103 
104     size_t argc = funcArg.GetArgc();
105     const string procedureName = "FileIOLseek";
106     NVal thisVar(env, funcArg.GetThisVar());
107     if (argc == NARG_CNT::THREE) {
108         return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplCallback).val_;
109     } else {
110         NVal cb(env, funcArg[NARG_POS::FOURTH]);
111         return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplCallback).val_;
112     }
113 }
114 } // namespace ModuleFileIO
115 } // namespace DistributedFS
116 } // namespace OHOS