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 #include "read_lines_core.h"
16
17 #include <unistd.h>
18
19 #include "file_utils.h"
20 #include "filemgmt_libhilog.h"
21 #include "rust_file.h"
22
23 namespace OHOS {
24 namespace FileManagement {
25 namespace ModuleFileIO {
26 using namespace std;
27
CheckOptionArg(Options option)28 static int CheckOptionArg(Options option)
29 {
30 auto encoding = option.encoding;
31 if (encoding != "utf-8") {
32 return EINVAL;
33 }
34
35 return ERRNO_NOERR;
36 }
37
GetFileSize(const string & path,int64_t & offset)38 static int GetFileSize(const string &path, int64_t &offset)
39 {
40 std::unique_ptr<uv_fs_t, decltype(FsUtils::FsReqCleanup) *> readLinesReq = { new uv_fs_t, FsUtils::FsReqCleanup };
41 if (!readLinesReq) {
42 HILOGE("Failed to request heap memory.");
43 return ENOMEM;
44 }
45
46 int ret = uv_fs_stat(nullptr, readLinesReq.get(), path.c_str(), nullptr);
47 if (ret < 0) {
48 HILOGE("Failed to get file stat by path");
49 return ret;
50 }
51
52 offset = static_cast<int64_t>(readLinesReq->statbuf.st_size);
53 return ERRNO_NOERR;
54 }
55
InstantiateReaderIterator(void * iterator,int64_t offset)56 static FsResult<FsReaderIterator *> InstantiateReaderIterator(void *iterator, int64_t offset)
57 {
58 if (iterator == nullptr) {
59 HILOGE("Invalid argument iterator");
60 return FsResult<FsReaderIterator *>::Error(EINVAL);
61 }
62
63 auto readeriterator = FsReaderIterator::Constructor();
64 if (!readeriterator.IsSuccess()) {
65 HILOGE("Failed to instantiate class ReaderIterator");
66 return FsResult<FsReaderIterator *>::Error(UNKNOWN_ERR);
67 }
68
69 auto readerIteratorEntity = readeriterator.GetData().value()->GetReaderIteratorEntity();
70 if (!readerIteratorEntity) {
71 HILOGE("Failed to get readerIteratorEntity");
72 return FsResult<FsReaderIterator *>::Error(UNKNOWN_ERR);
73 }
74 readerIteratorEntity->iterator = iterator;
75 readerIteratorEntity->offset = offset;
76 return FsResult<FsReaderIterator *>::Success(readeriterator.GetData().value());
77 }
78
DoReadLines(const string & path,optional<Options> option)79 FsResult<FsReaderIterator *> ReadLinesCore::DoReadLines(const string &path, optional<Options> option)
80 {
81 if (option.has_value()) {
82 int ret = CheckOptionArg(option.value());
83 if (ret) {
84 HILOGE("Invalid option.encoding parameter");
85 return FsResult<FsReaderIterator *>::Error(ret);
86 }
87 }
88
89 auto iterator = ::ReaderIterator(path.c_str());
90 if (iterator == nullptr) {
91 HILOGE("Failed to read lines of the file, error: %{public}d", errno);
92 return FsResult<FsReaderIterator *>::Error(errno);
93 }
94
95 int64_t offset = 0;
96 int ret = GetFileSize(path, offset);
97 if (ret != 0) {
98 HILOGE("Failed to get size of the file");
99 return FsResult<FsReaderIterator *>::Error(ret);
100 }
101 return InstantiateReaderIterator(iterator, offset);
102 }
103
104 } // namespace ModuleFileIO
105 } // namespace FileManagement
106 } // namespace OHOS