1 /*
2  * Copyright (c) 2024 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 "randomAccessFile_impl.h"
17 
18 using namespace OHOS::CJSystemapi::FileFs;
19 
20 namespace OHOS::CJSystemapi {
CalculateOffset(int64_t offset,int64_t fPointer)21 static int64_t CalculateOffset(int64_t offset, int64_t fPointer)
22 {
23     if (offset < 0) {
24         LOGE("No specified offset provided");
25         offset = fPointer;
26     } else {
27         offset += fPointer;
28     }
29     return offset;
30 }
DoWriteRAF(char * buf,size_t len,int fd,int64_t offset)31 static int DoWriteRAF(char* buf, size_t len, int fd, int64_t offset)
32 {
33     std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> write_req = {
34         new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup };
35     if (write_req == nullptr) {
36         LOGE("Failed to request heap memory.");
37         return ENOMEM;
38     }
39     LOGI("write buffer is %{public}s", buf);
40     uv_buf_t iov = uv_buf_init(buf, len);
41     int ret = uv_fs_write(nullptr, write_req.get(), fd, &iov, 1, offset, nullptr);
42     return ret;
43 }
DoReadRAF(char * buf,size_t len,int fd,int64_t offset)44 static int DoReadRAF(char* buf, size_t len, int fd, int64_t offset)
45 {
46     std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> read_req = {
47         new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup };
48     if (read_req == nullptr) {
49         LOGE("Failed to request heap memory.");
50         return ENOMEM;
51     }
52     uv_buf_t iov = uv_buf_init(buf, len);
53     int ret = uv_fs_read(nullptr, read_req.get(), fd, &iov, 1, offset, nullptr);
54     return ret;
55 }
RandomAccessFileImpl(std::shared_ptr<OHOS::FileManagement::ModuleFileIO::RandomAccessFileEntity> entity)56 RandomAccessFileImpl::RandomAccessFileImpl(std::shared_ptr<
57         OHOS::FileManagement::ModuleFileIO::RandomAccessFileEntity> entity)
58 {
59     entity_ = entity;
60 }
GetFd()61 int32_t RandomAccessFileImpl::GetFd()
62 {
63     LOGI("start get fs in cpp");
64     if (entity_ == nullptr) {
65         LOGE("Failed to creat entity.");
66         return -1;
67     }
68     if (entity_->fd.get() == nullptr) {
69         LOGE("Failed to get fd.");
70         return -1;
71     }
72     return entity_->fd.get()->GetFD();
73 }
GetFPointer()74 int64_t RandomAccessFileImpl::GetFPointer()
75 {
76     return entity_->filePointer;
77 }
SetFilePointerSync(int64_t fp)78 void RandomAccessFileImpl::SetFilePointerSync(int64_t fp)
79 {
80     entity_->filePointer = fp;
81     return;
82 }
CloseSync()83 void RandomAccessFileImpl::CloseSync()
84 {
85     std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> close_req = {
86         new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup };
87     if (!close_req) {
88         LOGE("Failed to close file with ret: %{public}d", ENOMEM);
89         return;
90     }
91     int ret = uv_fs_close(nullptr, close_req.get(), entity_->fd.get()->GetFD(), nullptr);
92     if (ret < 0) {
93         LOGE("Failed to close file with ret: %{public}d", ret);
94     }
95     entity_ = nullptr;
96     return;
97 }
WriteSync(char * buf,size_t len,int64_t offset)98 std::tuple<int32_t, int64_t> RandomAccessFileImpl::WriteSync(char* buf, size_t len, int64_t offset)
99 {
100     int64_t newOffset = CalculateOffset(offset, entity_->filePointer);
101     int writeCode = DoWriteRAF(buf, len, entity_->fd.get()->GetFD(), newOffset);
102     if (writeCode < 0) {
103         LOGE("Failed to read file for %{public}d", writeCode);
104         return {GetErrorCode(-writeCode), 0};
105     }
106     entity_->filePointer = newOffset + writeCode;
107     return {SUCCESS_CODE, writeCode};
108 }
ReadSync(char * buf,size_t len,int64_t offset)109 std::tuple<int32_t, int64_t> RandomAccessFileImpl::ReadSync(char* buf, size_t len, int64_t offset)
110 {
111     int64_t newOffset = CalculateOffset(offset, entity_->filePointer);
112     int readCode = DoReadRAF(buf, len, entity_->fd.get()->GetFD(), newOffset);
113     if (readCode < 0) {
114         LOGE("Failed to read file for %{public}d", readCode);
115         return {GetErrorCode(-readCode), 0};
116     }
117     entity_->filePointer = newOffset + readCode;
118     return {SUCCESS_CODE, readCode};
119 }
120 }