4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
14 * Neither the name of the NXP Semiconductor nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
36 #include <condition_variable>
59 int file_overwrite_monitor(std::string filename
, FileBuffer
*p
);
63 //bit 1, data total size known
64 #define FILEBUFFER_FLAG_LOADED_BIT 0x1
65 #define FILEBUFFER_FLAG_KNOWN_SIZE_BIT 0x2
66 #define FILEBUFFER_FLAG_ERROR_BIT 0x4
67 #define FILEBUFFER_FLAG_NEVER_FREE 0x8
68 #define FILEBUFFER_FLAG_PARTIAL_RELOADABLE 0x10
69 #define FILEBUFFER_FLAG_SEG_DONE 0x20
71 #define FILEBUFFER_FLAG_LOADED (FILEBUFFER_FLAG_LOADED_BIT|FILEBUFFER_FLAG_KNOWN_SIZE_BIT) // LOADED must be knownsize
72 #define FILEBUFFER_FLAG_KNOWN_SIZE FILEBUFFER_FLAG_KNOWN_SIZE_BIT
85 CONVERT_PARTIAL
= 0x8,
87 size_t m_input_offset
= 0;
88 size_t m_input_sz
= 0;
89 std::shared_ptr
<FileBuffer
> m_input
;
91 size_t m_actual_size
= 0;
92 size_t m_output_size
= 0;
93 size_t m_output_offset
= 0;
94 virtual int DataConvert() { return -1; };
95 std::vector
<uint8_t> m_data
;
97 std::atomic_int m_dataflags
{0};
98 uint8_t* m_pData
= NULL
;
103 return m_data
.data();
108 class DataBuffer
: public std::enable_shared_from_this
<DataBuffer
>
110 enum class ALLOCATION_WAYS
118 ALLOCATION_WAYS
get_m_allocate_way() const noexcept
{ return m_allocate_way
; }
119 uint8_t* m_pDatabuffer
= NULL
;
120 size_t m_DataSize
= 0;
121 size_t m_MemSize
= 0;
122 std::shared_ptr
<FileBuffer
> m_ref
;
123 ALLOCATION_WAYS m_allocate_way
= ALLOCATION_WAYS::MALLOC
;
128 m_allocate_way
= ALLOCATION_WAYS::MALLOC
;
130 DataBuffer(void* p
, size_t sz
)
132 m_allocate_way
= ALLOCATION_WAYS::MALLOC
;
134 memcpy(data(), p
, sz
);
136 uint8_t* data() { return m_pDatabuffer
; }
137 size_t size() { return m_DataSize
; }
138 int resize(size_t sz
);
139 int ref_other_buffer(std::shared_ptr
<FileBuffer
> p
, size_t offset
, size_t size
);
140 uint8_t& operator[] (size_t index
)
142 assert(m_pDatabuffer
);
143 assert(index
< m_DataSize
);
145 return *(m_pDatabuffer
+ index
);
147 uint8_t& at(size_t index
)
149 return (*this)[index
];
153 if (m_allocate_way
== ALLOCATION_WAYS::MALLOC
)
158 friend class FileBuffer
;
161 class FileBuffer
: public std::enable_shared_from_this
<FileBuffer
>
164 friend class DataBuffer
;
167 friend class FSHttps
;
171 friend class FSCompressStream
;
175 friend class Zip_file_Info
;
176 enum class ALLOCATION_WAYS
185 std::mutex m_data_mutex
;
187 uint8_t *m_pDatabuffer
;
191 std::shared_ptr
<FileBuffer
> m_ref
;
193 int ref_other_buffer(std::shared_ptr
<FileBuffer
> p
, size_t offset
, size_t size
);
195 std::mutex m_async_mutex
;
197 std::map
<size_t, std::shared_ptr
<FragmentBlock
>, std::greater
<size_t>> m_seg_map
;
198 std::mutex m_seg_map_mutex
;
199 std::queue
<size_t> m_offset_request
;
200 size_t m_last_request_offset
= 0;
201 std::condition_variable m_pool_load_cv
;
202 std::mutex m_pool_load_cv_mutex
;
203 std::shared_ptr
<FragmentBlock
> m_last_db
;
204 size_t m_seg_blk_size
= 0x800000;
205 size_t m_totall_buffer_size
= 8 * m_seg_blk_size
;
206 std::atomic_bool m_reset_stream
{ false };
208 //used for continue decompress\loading only
209 std::shared_ptr
<FragmentBlock
> request_new_blk();
210 bool check_offset_in_seg(size_t offset
, std::shared_ptr
<FragmentBlock
> blk
)
212 if (offset
>= blk
->m_output_offset
213 && offset
< blk
->m_output_offset
+ blk
->m_output_size
)
218 std::shared_ptr
<FragmentBlock
> get_map_it(size_t offset
, bool alloc
= false)
221 std::lock_guard
<std::mutex
> lock(m_seg_map_mutex
);
222 auto it
= m_seg_map
.lower_bound(offset
);
223 if ( it
== m_seg_map
.end())
226 auto blk
= it
->second
;
227 if (check_offset_in_seg(offset
, blk
))
231 std::lock_guard
<std::mutex
> lck(blk
->m_mutex
);
232 blk
->m_data
.resize(blk
->m_output_size
);
239 void truncate_old_data_in_pool();
241 std::atomic_int m_dataflags
;
243 std::thread m_aync_thread
;
245 std::atomic_size_t m_avaible_size
;
246 std::condition_variable m_request_cv
;
247 std::mutex m_requext_cv_mutex
;
250 OVERLAPPED m_OverLapped
;
251 REQUEST_OPLOCK_INPUT_BUFFER m_Request
;
252 HANDLE m_file_handle
;
254 std::thread m_file_monitor
;
257 uint64_t m_timesample
;
260 FileBuffer(void*p
, size_t sz
);
263 ALLOCATION_WAYS
get_m_allocate_way() const noexcept
{ return m_allocate_way
; }
265 int64_t request_data(void * data
, size_t offset
, size_t sz
);
266 int request_data(std::vector
<uint8_t> &data
, size_t offset
, size_t sz
);
267 std::shared_ptr
<DataBuffer
> request_data(size_t offset
, size_t sz
);
269 bool IsLoaded() const noexcept
271 return m_dataflags
& FILEBUFFER_FLAG_LOADED_BIT
;
274 bool IsRefable() const noexcept
276 return m_dataflags
& FILEBUFFER_FLAG_NEVER_FREE
;
279 bool IsKnownSize() const noexcept
281 return m_dataflags
& FILEBUFFER_FLAG_KNOWN_SIZE_BIT
;
284 bool IsError() const noexcept
286 return m_dataflags
& FILEBUFFER_FLAG_ERROR_BIT
;
289 int reload(std::string filename
, bool async
= false);
296 std::unique_lock
<std::mutex
> lck(m_requext_cv_mutex
);
297 while (!(m_dataflags
& FILEBUFFER_FLAG_KNOWN_SIZE_BIT
))
298 m_request_cv
.wait(lck
);
304 uint8_t * data() noexcept
306 return m_pDatabuffer
;
309 uint8_t & operator[] (size_t index
)
311 assert(m_pDatabuffer
);
312 assert(index
< m_DataSize
);
314 return *(m_pDatabuffer
+ index
);
317 uint8_t & at(size_t index
)
319 return (*this)[index
];
321 int resize(size_t sz
);
323 int reserve(size_t sz
);
325 int swap(FileBuffer
& a
);
327 int mapfile(const std::string
&filename
, size_t sz
);
333 int64_t request_data_from_segment(void* data
, size_t offset
, size_t sz
);
334 int m_pool_size
= 10;
335 std::string m_filename
;
337 ALLOCATION_WAYS m_allocate_way
= ALLOCATION_WAYS::MALLOC
;
340 std::shared_ptr
<FileBuffer
> get_file_buffer(std::string filename
, bool aysnc
=false);
341 bool check_file_exist(std::string filename
, bool start_async_load
=true);
343 void set_current_dir(const std::string
&dir
);
345 bool IsMBR(std::shared_ptr
<DataBuffer
> p
);
346 size_t ScanTerm(std::shared_ptr
<DataBuffer
> p
, size_t& pos
, size_t offset
= 512, size_t limited
= 0x800000);
347 void clean_up_filemap();