35#include <wx/filename.h>
37#include <wx/wfstream.h>
40#include "chartdata_input_stream.h"
44wxCompressedFFileInputStream::wxCompressedFFileInputStream(
45 const wxString &fileName) {
47 m_file =
new wxFFile(fileName,
"rb");
50wxCompressedFFileInputStream::~wxCompressedFFileInputStream() {
55size_t wxCompressedFFileInputStream::OnSysRead(
void *buffer,
size_t size) {
56 lzma_action action = LZMA_RUN;
58 strm.next_out = (uint8_t *)buffer;
59 strm.avail_out = size;
62 if (strm.avail_in == 0) {
65 strm.avail_in = m_file->Read(inbuf,
sizeof inbuf);
67 if (m_file->Error())
return 0;
73 lzma_ret ret = lzma_code(&strm, action);
75 if (strm.avail_out == 0 || ret == LZMA_STREAM_END)
76 return size - strm.avail_out;
79 m_lasterror = wxSTREAM_READ_ERROR;
86wxFileOffset wxCompressedFFileInputStream::OnSysSeek(wxFileOffset pos,
89 if (pos == 0 && mode == wxFromStart) {
92 return m_file->Seek(pos, mode);
95 return wxInvalidOffset;
98wxFileOffset wxCompressedFFileInputStream::OnSysTell()
const {
99 return strm.total_out;
102void wxCompressedFFileInputStream::init_lzma() {
103 lzma_stream s = LZMA_STREAM_INIT;
104 memcpy(&strm, &s,
sizeof s);
105 lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
107 if (ret != LZMA_OK) m_lasterror = wxSTREAM_READ_ERROR;
110ChartDataNonSeekableInputStream::ChartDataNonSeekableInputStream(
111 const wxString &fileName) {
112 if (fileName.Upper().EndsWith(
"XZ"))
113 m_stream =
new wxCompressedFFileInputStream(fileName);
115 m_stream =
new wxFFileInputStream(fileName);
118ChartDataNonSeekableInputStream::~ChartDataNonSeekableInputStream() {
122size_t ChartDataNonSeekableInputStream::OnSysRead(
void *buffer,
size_t size) {
123 m_stream->Read(buffer, size);
124 return m_stream->LastRead();
127wxFileOffset ChartDataNonSeekableInputStream::OnSysSeek(wxFileOffset pos,
129 return m_stream->SeekI(pos, mode);
132wxFileOffset ChartDataNonSeekableInputStream::OnSysTell()
const {
133 return m_stream->TellI();
136ChartDataInputStream::ChartDataInputStream(
const wxString &fileName) {
137 if (fileName.Upper().EndsWith(
"XZ")) {
140 wxFileName::CreateTempFileName(wxFileName(fileName).GetFullName());
141 wxCompressedFFileInputStream stream(fileName);
142 wxFFileOutputStream tmp(m_tempfilename);
147 stream.Read(buffer,
sizeof buffer);
148 len = stream.LastRead();
149 tmp.Write(buffer, len);
150 }
while (len ==
sizeof buffer);
155 m_stream =
new wxFFileInputStream(m_tempfilename);
157 m_stream =
new wxFFileInputStream(fileName);
160ChartDataInputStream::~ChartDataInputStream() {
164 if (!m_tempfilename.empty()) wxRemoveFile(m_tempfilename);
167size_t ChartDataInputStream::OnSysRead(
void *buffer,
size_t size) {
168 m_stream->Read(buffer, size);
169 return m_stream->LastRead();
172wxFileOffset ChartDataInputStream::OnSysSeek(wxFileOffset pos,
174 return m_stream->SeekI(pos, mode);
177wxFileOffset ChartDataInputStream::OnSysTell()
const {
178 return m_stream->TellI();
181bool DecompressXZFile(
const wxString &input_path,
const wxString &output_path) {
182 if (!wxFileExists(input_path)) {
185 wxCompressedFFileInputStream in(input_path);
186 wxFFileOutputStream out(output_path);
191 in.Read(buffer,
sizeof buffer);
193 out.Write(buffer, len);
194 }
while (len ==
sizeof buffer);
196 return in.GetLastError() != wxSTREAM_READ_ERROR;
201bool DecompressXZFile(
const wxString &input_path,
const wxString &output_path) {
202 wxLogMessage(_T(
"Failed to decompress: ") + input_path);
203 wxLogMessage(_T(
"OpenCPN compiled without liblzma support"));