• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "pkg_stream.h"
16 #include <cerrno>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <memory>
20 #include "pkg_manager.h"
21 #include "pkg_manager_impl.h"
22 #include "pkg_utils.h"
23 #include "securec.h"
24 
25 namespace hpackage {
GetFileName() const26 const std::string PkgStreamImpl::GetFileName() const
27 {
28     return fileName_;
29 }
30 
ConvertPkgStream(PkgManager::StreamPtr stream)31 PkgStreamPtr PkgStreamImpl::ConvertPkgStream(PkgManager::StreamPtr stream)
32 {
33     return (PkgStreamPtr)stream;
34 }
35 
AddRef()36 void PkgStreamImpl::AddRef()
37 {
38     refCount_++;
39 }
40 
DelRef()41 void PkgStreamImpl::DelRef()
42 {
43     refCount_--;
44 }
45 
IsRef() const46 bool PkgStreamImpl::IsRef() const
47 {
48     return refCount_ == 0;
49 }
50 
PostDecodeProgress(int type,size_t writeDataLen,const void * context)51 void PkgStreamImpl::PostDecodeProgress(int type, size_t writeDataLen, const void *context)
52 {
53     if (pkgManager_ != nullptr) {
54         pkgManager_->PostDecodeProgress(type, writeDataLen, context);
55     }
56 }
57 
~FileStream()58 FileStream::~FileStream()
59 {
60     if (stream_ != nullptr) {
61         fflush(stream_);
62         fclose(stream_);
63         stream_ = nullptr;
64     }
65 }
66 
Read(const PkgBuffer & data,size_t offset,size_t needRead,size_t & readLen)67 int32_t FileStream::Read(const PkgBuffer &data, size_t offset, size_t needRead, size_t &readLen)
68 {
69     PKG_CHECK(stream_ != nullptr, return PKG_INVALID_STREAM, "Invalid stream");
70     PKG_CHECK(data.length >= needRead, return PKG_INVALID_STREAM, "Invalid stream");
71     readLen = 0;
72     size_t len = GetFileLength();
73     fseek(stream_, offset, SEEK_SET);
74     PKG_CHECK(offset <= len, return PKG_INVALID_STREAM, "Invalid offset");
75     len = fread(data.buffer, 1, needRead, stream_);
76     readLen = len;
77     return PKG_SUCCESS;
78 }
79 
Write(const PkgBuffer & data,size_t size,size_t offset)80 int32_t FileStream::Write(const PkgBuffer &data, size_t size, size_t offset)
81 {
82     PKG_CHECK(streamType_ == PkgStreamType_Write, return PKG_INVALID_STREAM, "Invalid stream type");
83     PKG_CHECK(stream_ != nullptr, return PKG_INVALID_STREAM, "Invalid stream");
84     fseek(stream_, offset, SEEK_SET);
85     size_t len = fwrite(data.buffer, size, 1, stream_);
86     PKG_CHECK(len == 1, return PKG_INVALID_STREAM, "Write buffer fail");
87     PostDecodeProgress(POST_TYPE_DECODE_PKG, size, nullptr);
88     return PKG_SUCCESS;
89 }
90 
GetFileLength()91 size_t FileStream::GetFileLength()
92 {
93     PKG_CHECK(stream_ != nullptr, return 0, "Invalid stream");
94     if (fileLength_ == 0) {
95         PKG_CHECK(Seek(0, SEEK_END) == 0, return -1, "Invalid stream");
96         off_t pos = ftello(stream_);
97         if (pos < 0) {
98             PKG_LOGE("Failed to get file length, err = %d", errno);
99             return 0;
100         }
101         fileLength_ = static_cast<size_t>(pos);
102         fseek(stream_, 0, SEEK_SET);
103     }
104     return fileLength_;
105 }
106 
Seek(long int offset,int whence)107 int32_t FileStream::Seek(long int offset, int whence)
108 {
109     PKG_CHECK(stream_ != nullptr, return PKG_INVALID_STREAM, "Invalid stream");
110     return fseek(stream_, offset, whence);
111 }
112 
Flush(size_t size)113 int32_t FileStream::Flush(size_t size)
114 {
115     PKG_CHECK(stream_ != nullptr, return PKG_INVALID_STREAM, "Invalid stream");
116     if (fileLength_ == 0) {
117         fileLength_ = size;
118     }
119     PKG_CHECK(fflush(stream_) == 0, return PKG_INVALID_STREAM, "Invalid stream");
120     return PKG_SUCCESS;
121 }
122 
~MemoryMapStream()123 MemoryMapStream::~MemoryMapStream()
124 {
125     PKG_CHECK(memMap_ != nullptr, return, "Invalid memory map");
126     if (streamType_ == PkgStreamType_MemoryMap) {
127         ReleaseMemory(memMap_, memSize_);
128     }
129 }
130 
Read(const PkgBuffer & data,size_t start,size_t needRead,size_t & readLen)131 int32_t MemoryMapStream::Read(const PkgBuffer &data, size_t start, size_t needRead, size_t &readLen)
132 {
133     PKG_CHECK(memMap_ != nullptr, return PKG_INVALID_STREAM, "Invalid memory map");
134     PKG_CHECK(start <= memSize_, return PKG_INVALID_STREAM, "Invalid start");
135     PKG_CHECK(data.length >= needRead, return PKG_INVALID_STREAM, "Invalid start");
136 
137     MemoryMapStream::Seek(start, SEEK_SET);
138     size_t copyLen = GetFileLength() - start;
139     readLen = ((copyLen > needRead) ? needRead : copyLen);
140     PKG_CHECK(!memcpy_s(data.buffer, needRead, memMap_ + currOffset_, readLen), return PKG_NONE_MEMORY,
141         "Memcpy failed size:%zu, start:%zu copyLen:%zu %zu", needRead, start, copyLen, readLen);
142     return PKG_SUCCESS;
143 }
144 
Write(const PkgBuffer & data,size_t size,size_t start)145 int32_t MemoryMapStream::Write(const PkgBuffer &data, size_t size, size_t start)
146 {
147     PKG_CHECK(memMap_ != nullptr, return PKG_INVALID_STREAM, "Invalid memory map");
148     PKG_CHECK(start <= memSize_, return PKG_INVALID_STREAM, "Invalid start");
149 
150     currOffset_ = start;
151     size_t copyLen = memSize_ - start;
152     PKG_CHECK(copyLen >= size, return PKG_INVALID_STREAM, "Write fail copyLen %zu, %zu", copyLen, size);
153     int32_t ret = memcpy_s(memMap_ + currOffset_, memSize_ - currOffset_, data.buffer, size);
154     PKG_CHECK(ret == PKG_SUCCESS, return PKG_INVALID_STREAM, "Write fail");
155     PostDecodeProgress(POST_TYPE_DECODE_PKG, size, nullptr);
156     return PKG_SUCCESS;
157 }
158 
Seek(long int offset,int whence)159 int32_t MemoryMapStream::Seek(long int offset, int whence)
160 {
161     if (whence == SEEK_SET) {
162         PKG_CHECK(offset >= 0, return PKG_INVALID_STREAM, "Invalid offset");
163         PKG_CHECK(static_cast<size_t>(offset) <= memSize_, return PKG_INVALID_STREAM, "Invalid offset");
164         currOffset_ = offset;
165     } else if (whence == SEEK_CUR) {
166         PKG_CHECK(static_cast<size_t>(offset) <= (memSize_ - currOffset_), return PKG_INVALID_STREAM,
167             "Invalid offset");
168         currOffset_ += offset;
169     } else {
170         PKG_CHECK(offset <= 0, return PKG_INVALID_STREAM, "Invalid offset");
171         PKG_CHECK((memSize_ + offset) <= memSize_, return PKG_INVALID_STREAM, "Invalid offset");
172         PKG_CHECK((memSize_ + offset) >= 0, return PKG_INVALID_STREAM, "Invalid offset");
173         currOffset_ = memSize_ + offset;
174     }
175     return PKG_SUCCESS;
176 }
177 } // namespace hpackage
178