31#include <wx/filename.h>
33#include <wx/wfstream.h>
40wxCompressedFFileInputStream::wxCompressedFFileInputStream(
41 const wxString &fileName) {
43 m_file =
new wxFFile(fileName,
"rb");
46wxCompressedFFileInputStream::~wxCompressedFFileInputStream() {
51size_t wxCompressedFFileInputStream::OnSysRead(
void *buffer,
size_t size) {
52 lzma_action action = LZMA_RUN;
54 strm.next_out = (uint8_t *)buffer;
55 strm.avail_out = size;
58 if (strm.avail_in == 0) {
61 strm.avail_in = m_file->Read(inbuf,
sizeof inbuf);
63 if (m_file->Error())
return 0;
69 lzma_ret ret = lzma_code(&strm, action);
71 if (strm.avail_out == 0 || ret == LZMA_STREAM_END)
72 return size - strm.avail_out;
75 m_lasterror = wxSTREAM_READ_ERROR;
82wxFileOffset wxCompressedFFileInputStream::OnSysSeek(wxFileOffset pos,
85 if (pos == 0 && mode == wxFromStart) {
88 return m_file->Seek(pos, mode);
91 return wxInvalidOffset;
94wxFileOffset wxCompressedFFileInputStream::OnSysTell()
const {
95 return strm.total_out;
98void wxCompressedFFileInputStream::init_lzma() {
99 lzma_stream s = LZMA_STREAM_INIT;
100 memcpy(&strm, &s,
sizeof s);
101 lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
103 if (ret != LZMA_OK) m_lasterror = wxSTREAM_READ_ERROR;
106ChartDataNonSeekableInputStream::ChartDataNonSeekableInputStream(
107 const wxString &fileName) {
108 if (fileName.Upper().EndsWith(
"XZ"))
109 m_stream =
new wxCompressedFFileInputStream(fileName);
111 m_stream =
new wxFFileInputStream(fileName);
114ChartDataNonSeekableInputStream::~ChartDataNonSeekableInputStream() {
118size_t ChartDataNonSeekableInputStream::OnSysRead(
void *buffer,
size_t size) {
119 m_stream->Read(buffer, size);
120 return m_stream->LastRead();
123wxFileOffset ChartDataNonSeekableInputStream::OnSysSeek(wxFileOffset pos,
125 return m_stream->SeekI(pos, mode);
128wxFileOffset ChartDataNonSeekableInputStream::OnSysTell()
const {
129 return m_stream->TellI();
132ChartDataInputStream::ChartDataInputStream(
const wxString &fileName) {
133 if (fileName.Upper().EndsWith(
"XZ")) {
136 wxFileName::CreateTempFileName(wxFileName(fileName).GetFullName());
137 wxCompressedFFileInputStream stream(fileName);
138 wxFFileOutputStream tmp(m_tempfilename);
143 stream.Read(buffer,
sizeof buffer);
144 len = stream.LastRead();
145 tmp.Write(buffer, len);
146 }
while (len ==
sizeof buffer);
151 m_stream =
new wxFFileInputStream(m_tempfilename);
153 m_stream =
new wxFFileInputStream(fileName);
156ChartDataInputStream::~ChartDataInputStream() {
160 if (!m_tempfilename.empty()) wxRemoveFile(m_tempfilename);
163size_t ChartDataInputStream::OnSysRead(
void *buffer,
size_t size) {
164 m_stream->Read(buffer, size);
165 return m_stream->LastRead();
168wxFileOffset ChartDataInputStream::OnSysSeek(wxFileOffset pos,
170 return m_stream->SeekI(pos, mode);
173wxFileOffset ChartDataInputStream::OnSysTell()
const {
174 return m_stream->TellI();
177bool DecompressXZFile(
const wxString &input_path,
const wxString &output_path) {
178 if (!wxFileExists(input_path)) {
181 wxCompressedFFileInputStream in(input_path);
182 wxFFileOutputStream out(output_path);
187 in.Read(buffer,
sizeof buffer);
189 out.Write(buffer, len);
190 }
while (len ==
sizeof buffer);
192 return in.GetLastError() != wxSTREAM_READ_ERROR;
197bool DecompressXZFile(
const wxString &input_path,
const wxString &output_path) {
198 wxLogMessage(
"Failed to decompress: " + input_path);
199 wxLogMessage(
"OpenCPN compiled without liblzma support");