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 }