This keyword is not expanded by Git which means it's not replaced with the correct revision value in the releases made using git-based scripts and it's confusing to have lines with unexpanded "$Id$" in the released files. As expanding them with Git is not that simple (it could be done with git archive and export-subst attribute) and there are not many benefits in having them in the first place, just remove all these lines. If nothing else, this will make an eventual transition to Git simpler. Closes #14487. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
280 lines
7.1 KiB
C++
280 lines
7.1 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/common/fs_mem.cpp
|
|
// Purpose: in-memory file system
|
|
// Author: Vaclav Slavik
|
|
// Copyright: (c) 2000 Vaclav Slavik
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_FILESYSTEM && wxUSE_STREAMS
|
|
|
|
#include "wx/fs_mem.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/intl.h"
|
|
#include "wx/log.h"
|
|
#include "wx/wxcrtvararg.h"
|
|
#if wxUSE_GUI
|
|
#include "wx/image.h"
|
|
#endif // wxUSE_GUI
|
|
#endif
|
|
|
|
#include "wx/mstream.h"
|
|
|
|
// represents a file entry in wxMemoryFS
|
|
class wxMemoryFSFile
|
|
{
|
|
public:
|
|
wxMemoryFSFile(const void *data, size_t len, const wxString& mime)
|
|
{
|
|
m_Data = new char[len];
|
|
memcpy(m_Data, data, len);
|
|
m_Len = len;
|
|
m_MimeType = mime;
|
|
InitTime();
|
|
}
|
|
|
|
wxMemoryFSFile(const wxMemoryOutputStream& stream, const wxString& mime)
|
|
{
|
|
m_Len = stream.GetSize();
|
|
m_Data = new char[m_Len];
|
|
stream.CopyTo(m_Data, m_Len);
|
|
m_MimeType = mime;
|
|
InitTime();
|
|
}
|
|
|
|
virtual ~wxMemoryFSFile()
|
|
{
|
|
delete[] m_Data;
|
|
}
|
|
|
|
char *m_Data;
|
|
size_t m_Len;
|
|
wxString m_MimeType;
|
|
#if wxUSE_DATETIME
|
|
wxDateTime m_Time;
|
|
#endif // wxUSE_DATETIME
|
|
|
|
private:
|
|
void InitTime()
|
|
{
|
|
#if wxUSE_DATETIME
|
|
m_Time = wxDateTime::Now();
|
|
#endif // wxUSE_DATETIME
|
|
}
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxMemoryFSFile);
|
|
};
|
|
|
|
#if wxUSE_BASE
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
// wxMemoryFSHandler
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
|
wxMemoryFSHash wxMemoryFSHandlerBase::m_Hash;
|
|
|
|
|
|
wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
|
|
{
|
|
}
|
|
|
|
wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase()
|
|
{
|
|
// as only one copy of FS handler is supposed to exist, we may silently
|
|
// delete static data here. (There is no way how to remove FS handler from
|
|
// wxFileSystem other than releasing _all_ handlers.)
|
|
WX_CLEAR_HASH_MAP(wxMemoryFSHash, m_Hash);
|
|
}
|
|
|
|
bool wxMemoryFSHandlerBase::CanOpen(const wxString& location)
|
|
{
|
|
return GetProtocol(location) == "memory";
|
|
}
|
|
|
|
wxFSFile * wxMemoryFSHandlerBase::OpenFile(wxFileSystem& WXUNUSED(fs),
|
|
const wxString& location)
|
|
{
|
|
wxMemoryFSHash::const_iterator i = m_Hash.find(GetRightLocation(location));
|
|
if ( i == m_Hash.end() )
|
|
return NULL;
|
|
|
|
const wxMemoryFSFile * const obj = i->second;
|
|
|
|
return new wxFSFile
|
|
(
|
|
new wxMemoryInputStream(obj->m_Data, obj->m_Len),
|
|
location,
|
|
obj->m_MimeType,
|
|
GetAnchor(location)
|
|
#if wxUSE_DATETIME
|
|
, obj->m_Time
|
|
#endif // wxUSE_DATETIME
|
|
);
|
|
}
|
|
|
|
wxString wxMemoryFSHandlerBase::FindFirst(const wxString& url, int flags)
|
|
{
|
|
if ( (flags & wxDIR) && !(flags & wxFILE) )
|
|
{
|
|
// we only store files, not directories, so we don't risk finding
|
|
// anything
|
|
return wxString();
|
|
}
|
|
|
|
const wxString spec = GetRightLocation(url);
|
|
if ( spec.find_first_of("?*") == wxString::npos )
|
|
{
|
|
// simple case: there are no wildcard characters so we can return
|
|
// either 0 or 1 results and we can find the potential match quickly
|
|
return m_Hash.count(spec) ? url : wxString();
|
|
}
|
|
//else: deal with wildcards in FindNext()
|
|
|
|
m_findArgument = spec;
|
|
m_findIter = m_Hash.begin();
|
|
|
|
return FindNext();
|
|
}
|
|
|
|
wxString wxMemoryFSHandlerBase::FindNext()
|
|
{
|
|
// m_findArgument is used to indicate that search is in progress, we reset
|
|
// it to empty string after iterating over all elements
|
|
while ( !m_findArgument.empty() )
|
|
{
|
|
// test for the match before (possibly) clearing m_findArgument below
|
|
const bool found = m_findIter->first.Matches(m_findArgument);
|
|
|
|
// advance m_findIter first as we need to do it anyhow, whether it
|
|
// matches or not
|
|
const wxMemoryFSHash::const_iterator current = m_findIter;
|
|
|
|
if ( ++m_findIter == m_Hash.end() )
|
|
m_findArgument.clear();
|
|
|
|
if ( found )
|
|
return "memory:" + current->first;
|
|
}
|
|
|
|
return wxString();
|
|
}
|
|
|
|
bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString& filename)
|
|
{
|
|
if ( m_Hash.count(filename) )
|
|
{
|
|
wxLogError(_("Memory VFS already contains file '%s'!"), filename);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/*static*/
|
|
void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
|
|
const wxString& textdata,
|
|
const wxString& mimetype)
|
|
{
|
|
const wxCharBuffer buf(textdata.To8BitData());
|
|
|
|
AddFileWithMimeType(filename, buf.data(), buf.length(), mimetype);
|
|
}
|
|
|
|
|
|
/*static*/
|
|
void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString& filename,
|
|
const void *binarydata, size_t size,
|
|
const wxString& mimetype)
|
|
{
|
|
if ( !CheckDoesntExist(filename) )
|
|
return;
|
|
|
|
m_Hash[filename] = new wxMemoryFSFile(binarydata, size, mimetype);
|
|
}
|
|
|
|
/*static*/
|
|
void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
|
|
const wxString& textdata)
|
|
{
|
|
AddFileWithMimeType(filename, textdata, wxEmptyString);
|
|
}
|
|
|
|
|
|
/*static*/
|
|
void wxMemoryFSHandlerBase::AddFile(const wxString& filename,
|
|
const void *binarydata, size_t size)
|
|
{
|
|
AddFileWithMimeType(filename, binarydata, size, wxEmptyString);
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString& filename)
|
|
{
|
|
wxMemoryFSHash::iterator i = m_Hash.find(filename);
|
|
if ( i == m_Hash.end() )
|
|
{
|
|
wxLogError(_("Trying to remove file '%s' from memory VFS, "
|
|
"but it is not loaded!"),
|
|
filename);
|
|
return;
|
|
}
|
|
|
|
delete i->second;
|
|
m_Hash.erase(i);
|
|
}
|
|
|
|
#endif // wxUSE_BASE
|
|
|
|
#if wxUSE_GUI
|
|
|
|
#if wxUSE_IMAGE
|
|
/*static*/ void
|
|
wxMemoryFSHandler::AddFile(const wxString& filename,
|
|
const wxImage& image,
|
|
wxBitmapType type)
|
|
{
|
|
if ( !CheckDoesntExist(filename) )
|
|
return;
|
|
|
|
wxMemoryOutputStream mems;
|
|
if ( image.IsOk() && image.SaveFile(mems, type) )
|
|
{
|
|
m_Hash[filename] = new wxMemoryFSFile
|
|
(
|
|
mems,
|
|
wxImage::FindHandler(type)->GetMimeType()
|
|
);
|
|
}
|
|
else
|
|
{
|
|
wxLogError(_("Failed to store image '%s' to memory VFS!"), filename);
|
|
}
|
|
}
|
|
|
|
/*static*/ void
|
|
wxMemoryFSHandler::AddFile(const wxString& filename,
|
|
const wxBitmap& bitmap,
|
|
wxBitmapType type)
|
|
{
|
|
wxImage img = bitmap.ConvertToImage();
|
|
AddFile(filename, img, type);
|
|
}
|
|
|
|
#endif // wxUSE_IMAGE
|
|
|
|
#endif // wxUSE_GUI
|
|
|
|
|
|
#endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP
|