15bebb993Sopenharmony_ci/*
25bebb993Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
35bebb993Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
45bebb993Sopenharmony_ci * you may not use this file except in compliance with the License.
55bebb993Sopenharmony_ci * You may obtain a copy of the License at
65bebb993Sopenharmony_ci *
75bebb993Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
85bebb993Sopenharmony_ci *
95bebb993Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
105bebb993Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
115bebb993Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125bebb993Sopenharmony_ci * See the License for the specific language governing permissions and
135bebb993Sopenharmony_ci * limitations under the License.
145bebb993Sopenharmony_ci */
155bebb993Sopenharmony_ci
165bebb993Sopenharmony_ci#include "randomAccessFile_impl.h"
175bebb993Sopenharmony_ci
185bebb993Sopenharmony_ciusing namespace OHOS::CJSystemapi::FileFs;
195bebb993Sopenharmony_ci
205bebb993Sopenharmony_cinamespace OHOS::CJSystemapi {
215bebb993Sopenharmony_cistatic int64_t CalculateOffset(int64_t offset, int64_t fPointer)
225bebb993Sopenharmony_ci{
235bebb993Sopenharmony_ci    if (offset < 0) {
245bebb993Sopenharmony_ci        LOGE("No specified offset provided");
255bebb993Sopenharmony_ci        offset = fPointer;
265bebb993Sopenharmony_ci    } else {
275bebb993Sopenharmony_ci        offset += fPointer;
285bebb993Sopenharmony_ci    }
295bebb993Sopenharmony_ci    return offset;
305bebb993Sopenharmony_ci}
315bebb993Sopenharmony_cistatic int DoWriteRAF(char* buf, size_t len, int fd, int64_t offset)
325bebb993Sopenharmony_ci{
335bebb993Sopenharmony_ci    std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> write_req = {
345bebb993Sopenharmony_ci        new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup };
355bebb993Sopenharmony_ci    if (write_req == nullptr) {
365bebb993Sopenharmony_ci        LOGE("Failed to request heap memory.");
375bebb993Sopenharmony_ci        return ENOMEM;
385bebb993Sopenharmony_ci    }
395bebb993Sopenharmony_ci    LOGI("write buffer is %{public}s", buf);
405bebb993Sopenharmony_ci    uv_buf_t iov = uv_buf_init(buf, len);
415bebb993Sopenharmony_ci    int ret = uv_fs_write(nullptr, write_req.get(), fd, &iov, 1, offset, nullptr);
425bebb993Sopenharmony_ci    return ret;
435bebb993Sopenharmony_ci}
445bebb993Sopenharmony_cistatic int DoReadRAF(char* buf, size_t len, int fd, int64_t offset)
455bebb993Sopenharmony_ci{
465bebb993Sopenharmony_ci    std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> read_req = {
475bebb993Sopenharmony_ci        new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup };
485bebb993Sopenharmony_ci    if (read_req == nullptr) {
495bebb993Sopenharmony_ci        LOGE("Failed to request heap memory.");
505bebb993Sopenharmony_ci        return ENOMEM;
515bebb993Sopenharmony_ci    }
525bebb993Sopenharmony_ci    uv_buf_t iov = uv_buf_init(buf, len);
535bebb993Sopenharmony_ci    int ret = uv_fs_read(nullptr, read_req.get(), fd, &iov, 1, offset, nullptr);
545bebb993Sopenharmony_ci    return ret;
555bebb993Sopenharmony_ci}
565bebb993Sopenharmony_ciRandomAccessFileImpl::RandomAccessFileImpl(std::shared_ptr<
575bebb993Sopenharmony_ci        OHOS::FileManagement::ModuleFileIO::RandomAccessFileEntity> entity)
585bebb993Sopenharmony_ci{
595bebb993Sopenharmony_ci    entity_ = entity;
605bebb993Sopenharmony_ci}
615bebb993Sopenharmony_ciint32_t RandomAccessFileImpl::GetFd()
625bebb993Sopenharmony_ci{
635bebb993Sopenharmony_ci    LOGI("start get fs in cpp");
645bebb993Sopenharmony_ci    if (entity_ == nullptr) {
655bebb993Sopenharmony_ci        LOGE("Failed to creat entity.");
665bebb993Sopenharmony_ci        return -1;
675bebb993Sopenharmony_ci    }
685bebb993Sopenharmony_ci    if (entity_->fd.get() == nullptr) {
695bebb993Sopenharmony_ci        LOGE("Failed to get fd.");
705bebb993Sopenharmony_ci        return -1;
715bebb993Sopenharmony_ci    }
725bebb993Sopenharmony_ci    return entity_->fd.get()->GetFD();
735bebb993Sopenharmony_ci}
745bebb993Sopenharmony_ciint64_t RandomAccessFileImpl::GetFPointer()
755bebb993Sopenharmony_ci{
765bebb993Sopenharmony_ci    return entity_->filePointer;
775bebb993Sopenharmony_ci}
785bebb993Sopenharmony_civoid RandomAccessFileImpl::SetFilePointerSync(int64_t fp)
795bebb993Sopenharmony_ci{
805bebb993Sopenharmony_ci    entity_->filePointer = fp;
815bebb993Sopenharmony_ci    return;
825bebb993Sopenharmony_ci}
835bebb993Sopenharmony_civoid RandomAccessFileImpl::CloseSync()
845bebb993Sopenharmony_ci{
855bebb993Sopenharmony_ci    std::unique_ptr<uv_fs_t, decltype(CommonFunc::FsReqCleanup)*> close_req = {
865bebb993Sopenharmony_ci        new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup };
875bebb993Sopenharmony_ci    if (!close_req) {
885bebb993Sopenharmony_ci        LOGE("Failed to close file with ret: %{public}d", ENOMEM);
895bebb993Sopenharmony_ci        return;
905bebb993Sopenharmony_ci    }
915bebb993Sopenharmony_ci    int ret = uv_fs_close(nullptr, close_req.get(), entity_->fd.get()->GetFD(), nullptr);
925bebb993Sopenharmony_ci    if (ret < 0) {
935bebb993Sopenharmony_ci        LOGE("Failed to close file with ret: %{public}d", ret);
945bebb993Sopenharmony_ci    }
955bebb993Sopenharmony_ci    entity_ = nullptr;
965bebb993Sopenharmony_ci    return;
975bebb993Sopenharmony_ci}
985bebb993Sopenharmony_cistd::tuple<int32_t, int64_t> RandomAccessFileImpl::WriteSync(char* buf, size_t len, int64_t offset)
995bebb993Sopenharmony_ci{
1005bebb993Sopenharmony_ci    int64_t newOffset = CalculateOffset(offset, entity_->filePointer);
1015bebb993Sopenharmony_ci    int writeCode = DoWriteRAF(buf, len, entity_->fd.get()->GetFD(), newOffset);
1025bebb993Sopenharmony_ci    if (writeCode < 0) {
1035bebb993Sopenharmony_ci        LOGE("Failed to read file for %{public}d", writeCode);
1045bebb993Sopenharmony_ci        return {GetErrorCode(-writeCode), 0};
1055bebb993Sopenharmony_ci    }
1065bebb993Sopenharmony_ci    entity_->filePointer = newOffset + writeCode;
1075bebb993Sopenharmony_ci    return {SUCCESS_CODE, writeCode};
1085bebb993Sopenharmony_ci}
1095bebb993Sopenharmony_cistd::tuple<int32_t, int64_t> RandomAccessFileImpl::ReadSync(char* buf, size_t len, int64_t offset)
1105bebb993Sopenharmony_ci{
1115bebb993Sopenharmony_ci    int64_t newOffset = CalculateOffset(offset, entity_->filePointer);
1125bebb993Sopenharmony_ci    int readCode = DoReadRAF(buf, len, entity_->fd.get()->GetFD(), newOffset);
1135bebb993Sopenharmony_ci    if (readCode < 0) {
1145bebb993Sopenharmony_ci        LOGE("Failed to read file for %{public}d", readCode);
1155bebb993Sopenharmony_ci        return {GetErrorCode(-readCode), 0};
1165bebb993Sopenharmony_ci    }
1175bebb993Sopenharmony_ci    entity_->filePointer = newOffset + readCode;
1185bebb993Sopenharmony_ci    return {SUCCESS_CODE, readCode};
1195bebb993Sopenharmony_ci}
1205bebb993Sopenharmony_ci}