• 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 <cstdio>
17 #include "pkg_manager.h"
18 #include "pkg_utils.h"
19 #include "securec.h"
20 
21 #ifdef __APPLE__
22 #define off64_t off_t
23 #define fopen64 fopen
24 #define ftello64 ftello
25 #define fseeko64 fseek
26 #endif
27 
28 namespace Hpackage {
GetFileName() const29 const std::string PkgStreamImpl::GetFileName() const
30 {
31     return fileName_;
32 }
33 
ConvertPkgStream(PkgManager::StreamPtr stream)34 PkgStreamPtr PkgStreamImpl::ConvertPkgStream(PkgManager::StreamPtr stream)
35 {
36     return (PkgStreamPtr)stream;
37 }
38 
AddRef()39 void PkgStreamImpl::AddRef()
40 {
41     refCount_++;
42 }
43 
DelRef()44 void PkgStreamImpl::DelRef()
45 {
46     refCount_--;
47 }
48 
IsRef() const49 bool PkgStreamImpl::IsRef() const
50 {
51     return refCount_ == 0;
52 }
53 
PostDecodeProgress(int type,size_t writeDataLen,const void * context) const54 void PkgStreamImpl::PostDecodeProgress(int type, size_t writeDataLen, const void *context) const
55 {
56     if (pkgManager_ != nullptr) {
57         pkgManager_->PostDecodeProgress(type, writeDataLen, context);
58     }
59 }
60 
~FileStream()61 FileStream::~FileStream()
62 {
63     if (stream_ != nullptr) {
64         fflush(stream_);
65         fclose(stream_);
66         stream_ = nullptr;
67     }
68 }
69 
Read(const PkgBuffer & data,size_t start,size_t needRead,size_t & readLen)70 int32_t FileStream::Read(const PkgBuffer &data, size_t start, size_t needRead, size_t &readLen)
71 {
72     if (stream_ == nullptr) {
73         PKG_LOGE("Invalid stream");
74         return PKG_INVALID_STREAM;
75     }
76     if (data.length < needRead) {
77         PKG_LOGE("Invalid stream");
78         return PKG_INVALID_STREAM;
79     }
80     readLen = 0;
81     if (fseeko64(stream_, start, SEEK_SET) != 0) {
82         PKG_LOGE("read data fail");
83         return PKG_INVALID_STREAM;
84     }
85     if (start > GetFileLength()) {
86         PKG_LOGE("Invalid start");
87         return PKG_INVALID_STREAM;
88     }
89     readLen = fread(data.buffer, 1, needRead, stream_);
90     if (readLen == 0) {
91         PKG_LOGE("read data fail");
92         return PKG_INVALID_STREAM;
93     }
94     return PKG_SUCCESS;
95 }
96 
Write(const PkgBuffer & data,size_t size,size_t start)97 int32_t FileStream::Write(const PkgBuffer &data, size_t size, size_t start)
98 {
99     if (streamType_ != PkgStreamType_Write) {
100         PKG_LOGE("Invalid stream type");
101         return PKG_INVALID_STREAM;
102     }
103     if (stream_ == nullptr) {
104         PKG_LOGE("Invalid stream");
105         return PKG_INVALID_STREAM;
106     }
107     if (fseeko64(stream_, start, SEEK_SET) != 0) {
108         PKG_LOGE("write data fail");
109         return PKG_INVALID_STREAM;
110     }
111     size_t len = fwrite(data.buffer, size, 1, stream_);
112     if (len != 1) {
113         PKG_LOGE("Write buffer fail");
114         return PKG_INVALID_STREAM;
115     }
116     PostDecodeProgress(POST_TYPE_DECODE_PKG, size, nullptr);
117     return PKG_SUCCESS;
118 }
119 
GetFileLength()120 size_t FileStream::GetFileLength()
121 {
122     if (stream_ == nullptr) {
123         PKG_LOGE("Invalid stream");
124         return 0;
125     }
126     if (fileLength_ == 0) {
127         if (Seek(0, SEEK_END) != 0) {
128             PKG_LOGE("Invalid stream");
129             return -1;
130         }
131         off64_t ret = ftello64(stream_);
132         if (ret < 0) {
133             PKG_LOGE("ftell64 failed");
134             return PKG_INVALID_STREAM;
135         }
136         fileLength_ = static_cast<size_t>(ret);
137         if (fseek(stream_, 0, SEEK_SET) != 0) {
138             PKG_LOGE("fseek failed");
139             return PKG_INVALID_STREAM;
140         }
141     }
142     return fileLength_;
143 }
144 
Seek(long int offset,int whence)145 int32_t FileStream::Seek(long int offset, int whence)
146 {
147     if (stream_ == nullptr) {
148         PKG_LOGE("Invalid stream");
149         return PKG_INVALID_STREAM;
150     }
151     return fseek(stream_, offset, whence);
152 }
153 
Flush(size_t size)154 int32_t FileStream::Flush(size_t size)
155 {
156     if (stream_ == nullptr) {
157         PKG_LOGE("Invalid stream");
158         return PKG_INVALID_STREAM;
159     }
160     if (fileLength_ == 0) {
161         fileLength_ = size;
162     }
163     if (fseek(stream_, 0, SEEK_END) != 0) {
164         PKG_LOGE("fseek failed");
165         return PKG_INVALID_STREAM;
166     }
167     off64_t ret = ftello64(stream_);
168     if (ret < 0) {
169         PKG_LOGE("ftell64 failed");
170         return PKG_INVALID_STREAM;
171     }
172     fileLength_ = static_cast<size_t>(ret);
173     if (size != fileLength_) {
174         PKG_LOGE("Flush size %zu local size:%zu", size, fileLength_);
175     }
176     if (fflush(stream_) != 0) {
177         PKG_LOGE("Invalid stream");
178         return PKG_INVALID_STREAM;
179     }
180     return PKG_SUCCESS;
181 }
182 
~MemoryMapStream()183 MemoryMapStream::~MemoryMapStream()
184 {
185     if (memMap_ == nullptr) {
186         PKG_LOGE("Invalid memory map");
187         return;
188     }
189     if (streamType_ == PkgStreamType_MemoryMap) {
190         ReleaseMemory(memMap_, memSize_);
191     }
192 }
193 
Read(const PkgBuffer & data,size_t start,size_t needRead,size_t & readLen)194 int32_t MemoryMapStream::Read(const PkgBuffer &data, size_t start, size_t needRead, size_t &readLen)
195 {
196     if (memMap_ == nullptr) {
197         PKG_LOGE("Invalid memory map");
198         return PKG_INVALID_STREAM;
199     }
200     if (start > memSize_) {
201         PKG_LOGE("Invalid start");
202         return PKG_INVALID_STREAM;
203     }
204     if (data.length < needRead) {
205         PKG_LOGE("Invalid start");
206         return PKG_INVALID_STREAM;
207     }
208 
209     MemoryMapStream::Seek(start, SEEK_SET);
210     size_t copyLen = GetFileLength() - start;
211     readLen = ((copyLen > needRead) ? needRead : copyLen);
212     if (memcpy_s(data.buffer, needRead, memMap_ + currOffset_, readLen) != EOK) {
213         PKG_LOGE("Memcpy failed size:%zu, start:%zu copyLen:%zu %zu", needRead, start, copyLen, readLen);
214         return PKG_NONE_MEMORY;
215     }
216     return PKG_SUCCESS;
217 }
218 
Write(const PkgBuffer & data,size_t size,size_t start)219 int32_t MemoryMapStream::Write(const PkgBuffer &data, size_t size, size_t start)
220 {
221     if (memMap_ == nullptr) {
222         PKG_LOGE("Invalid memory map");
223         return PKG_INVALID_STREAM;
224     }
225     if (start > memSize_) {
226         PKG_LOGE("Invalid start");
227         return PKG_INVALID_STREAM;
228     }
229 
230     currOffset_ = start;
231     size_t copyLen = memSize_ - start;
232     if (copyLen < size) {
233         PKG_LOGE("Write fail copyLen %zu, %zu", copyLen, size);
234         return PKG_INVALID_STREAM;
235     }
236     int32_t ret = memcpy_s(memMap_ + currOffset_, memSize_ - currOffset_, data.buffer, size);
237     if (ret != PKG_SUCCESS) {
238         PKG_LOGE("Write fail");
239         return PKG_INVALID_STREAM;
240     }
241     PostDecodeProgress(POST_TYPE_DECODE_PKG, size, nullptr);
242     return PKG_SUCCESS;
243 }
244 
Seek(long int offset,int whence)245 int32_t MemoryMapStream::Seek(long int offset, int whence)
246 {
247     if (whence == SEEK_SET) {
248         if (offset < 0) {
249             PKG_LOGE("Invalid offset");
250             return PKG_INVALID_STREAM;
251         }
252         if (static_cast<size_t>(offset) > memSize_) {
253             PKG_LOGE("Invalid offset");
254             return PKG_INVALID_STREAM;
255         }
256         currOffset_ = static_cast<size_t>(offset);
257     } else if (whence == SEEK_CUR) {
258         if (static_cast<size_t>(offset) > (memSize_ - currOffset_)) {
259             PKG_LOGE("Invalid offset");
260             return PKG_INVALID_STREAM;
261         }
262         currOffset_ += static_cast<size_t>(offset);
263     } else {
264         if (offset > 0) {
265             PKG_LOGE("Invalid offset");
266             return PKG_INVALID_STREAM;
267         }
268         auto memSize = static_cast<long long>(memSize_);
269         if (memSize + offset < 0) {
270             PKG_LOGE("Invalid offset");
271             return PKG_INVALID_STREAM;
272         }
273         currOffset_ = static_cast<size_t>(memSize + offset);
274     }
275     return PKG_SUCCESS;
276 }
277 } // namespace Hpackage
278