• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "read_core.h"
17 
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <tuple>
21 #include <unistd.h>
22 
23 #include "file_utils.h"
24 #include "filemgmt_libfs.h"
25 #include "filemgmt_libhilog.h"
26 
27 namespace OHOS::FileManagement::ModuleFileIO {
28 using namespace std;
29 
ValidReadArg(ArrayBuffer & arrayBuffer,const optional<ReadOptions> & options)30 static tuple<bool, void *, size_t, int64_t> ValidReadArg(ArrayBuffer &arrayBuffer, const optional<ReadOptions> &options)
31 {
32     size_t retLen = 0;
33     int64_t offset = -1;
34     bool succ = false;
35     void *buf = arrayBuffer.buf;
36     size_t bufLen = arrayBuffer.length;
37 
38     if (bufLen > UINT_MAX) {
39         HILOGE("Invalid arraybuffer");
40         return { false, nullptr, retLen, offset };
41     }
42     optional<size_t> lengthOp = nullopt;
43     optional<int64_t> offsetOp = nullopt;
44     if (options.has_value()) {
45         ReadOptions op = options.value();
46         lengthOp = op.length;
47         offsetOp = op.offset;
48     }
49     tie(succ, retLen) = FsUtils::GetActualLen(bufLen, 0, lengthOp);
50     if (!succ) {
51         HILOGE("Failed to get actual length");
52         return { false, nullptr, retLen, offset };
53     }
54     if (offsetOp.has_value()) {
55         offset = offsetOp.value();
56         if (offset < 0) {
57             HILOGE("option.offset shall be positive number");
58             return { false, nullptr, retLen, offset };
59         }
60     }
61     return { true, buf, retLen, offset };
62 }
63 
DoRead(const int32_t & fd,ArrayBuffer & arrayBuffer,const optional<ReadOptions> & options)64 FsResult<int64_t> ReadCore::DoRead(const int32_t &fd, ArrayBuffer &arrayBuffer, const optional<ReadOptions> &options)
65 {
66     if (fd < 0) {
67         HILOGE("Invalid fd");
68         return FsResult<int64_t>::Error(EINVAL);
69     }
70 
71     auto [succ, buf, len, offset] = ValidReadArg(arrayBuffer, options);
72     if (!succ) {
73         return FsResult<int64_t>::Error(EINVAL);
74     }
75 
76     uv_buf_t buffer = uv_buf_init(static_cast<char *>(buf), static_cast<uint32_t>(len));
77     unique_ptr<uv_fs_t, decltype(FsUtils::FsReqCleanup) *> readReq = { new uv_fs_t, FsUtils::FsReqCleanup };
78     if (!readReq) {
79         HILOGE("Failed to request heap memory.");
80         return FsResult<int64_t>::Error(ENOMEM);
81     }
82     int ret = uv_fs_read(nullptr, readReq.get(), fd, &buffer, 1, offset, nullptr);
83     if (ret < 0) {
84         HILOGE("Failed to read file for %{public}d", ret);
85         return FsResult<int64_t>::Error(ret);
86     }
87 
88     return FsResult<int64_t>::Success(static_cast<int64_t>(ret));
89 }
90 
91 } // namespace OHOS::FileManagement::ModuleFileIO