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");