1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/fs_mem.cpp
3 // Purpose: in-memory file system
4 // Author: Vaclav Slavik
6 // Copyright: (c) 2000 Vaclav Slavik
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 #include "wx/wxprec.h"
16 #if wxUSE_FILESYSTEM && wxUSE_STREAMS
18 #include "wx/fs_mem.h"
23 #include "wx/wxcrtvararg.h"
29 #include "wx/mstream.h"
31 // represents a file entry in wxMemoryFS
35 wxMemoryFSFile(const void *data
, size_t len
, const wxString
& mime
)
37 m_Data
= new char[len
];
38 memcpy(m_Data
, data
, len
);
44 wxMemoryFSFile(const wxMemoryOutputStream
& stream
, const wxString
& mime
)
46 m_Len
= stream
.GetSize();
47 m_Data
= new char[m_Len
];
48 stream
.CopyTo(m_Data
, m_Len
);
53 virtual ~wxMemoryFSFile()
63 #endif // wxUSE_DATETIME
69 m_Time
= wxDateTime::Now();
70 #endif // wxUSE_DATETIME
73 DECLARE_NO_COPY_CLASS(wxMemoryFSFile
)
79 //--------------------------------------------------------------------------------
81 //--------------------------------------------------------------------------------
84 wxMemoryFSHash
wxMemoryFSHandlerBase::m_Hash
;
87 wxMemoryFSHandlerBase::wxMemoryFSHandlerBase() : wxFileSystemHandler()
91 wxMemoryFSHandlerBase::~wxMemoryFSHandlerBase()
93 // as only one copy of FS handler is supposed to exist, we may silently
94 // delete static data here. (There is no way how to remove FS handler from
95 // wxFileSystem other than releasing _all_ handlers.)
96 WX_CLEAR_HASH_MAP(wxMemoryFSHash
, m_Hash
);
99 bool wxMemoryFSHandlerBase::CanOpen(const wxString
& location
)
101 return GetProtocol(location
) == "memory";
104 wxFSFile
* wxMemoryFSHandlerBase::OpenFile(wxFileSystem
& WXUNUSED(fs
),
105 const wxString
& location
)
107 wxMemoryFSHash::const_iterator i
= m_Hash
.find(GetRightLocation(location
));
108 if ( i
== m_Hash
.end() )
111 const wxMemoryFSFile
* const obj
= i
->second
;
115 new wxMemoryInputStream(obj
->m_Data
, obj
->m_Len
),
121 #endif // wxUSE_DATETIME
125 wxString
wxMemoryFSHandlerBase::FindFirst(const wxString
& spec
, int flags
)
127 if ( (flags
& wxDIR
) && !(flags
& wxFILE
) )
129 // we only store files, not directories, so we don't risk finding
134 if ( spec
.find_first_of("?*") == wxString::npos
)
136 // simple case: there are no wildcard characters so we can return
137 // either 0 or 1 results and we can find the potential match quickly
138 return m_Hash
.count(spec
) ? spec
: wxString();
140 //else: deal with wildcards in FindNext()
142 m_findArgument
= spec
;
143 m_findIter
= m_Hash
.begin();
148 wxString
wxMemoryFSHandlerBase::FindNext()
150 // m_findArgument is used to indicate that search is in progress, we reset
151 // it to empty string after iterating over all elements
152 while ( !m_findArgument
.empty() )
154 // advance m_findIter before checking the value at the current position
155 // as we need to do it anyhow, whether it matches or not
156 const wxMemoryFSHash::const_iterator current
= m_findIter
;
158 if ( ++m_findIter
== m_Hash
.end() )
159 m_findArgument
.clear();
161 if ( current
->first
.Matches(m_findArgument
) )
162 return current
->first
;
168 bool wxMemoryFSHandlerBase::CheckDoesntExist(const wxString
& filename
)
170 if ( m_Hash
.count(filename
) )
172 wxLogError(_("Memory VFS already contains file '%s'!"), filename
);
181 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString
& filename
,
182 const wxString
& textdata
,
183 const wxString
& mimetype
)
185 AddFileWithMimeType(filename
,
186 (const void*) textdata
.mb_str(), textdata
.length(),
192 void wxMemoryFSHandlerBase::AddFileWithMimeType(const wxString
& filename
,
193 const void *binarydata
, size_t size
,
194 const wxString
& mimetype
)
196 if ( !CheckDoesntExist(filename
) )
199 m_Hash
[filename
] = new wxMemoryFSFile(binarydata
, size
, mimetype
);
203 void wxMemoryFSHandlerBase::AddFile(const wxString
& filename
,
204 const wxString
& textdata
)
206 AddFileWithMimeType(filename
, textdata
, wxEmptyString
);
211 void wxMemoryFSHandlerBase::AddFile(const wxString
& filename
,
212 const void *binarydata
, size_t size
)
214 AddFileWithMimeType(filename
, binarydata
, size
, wxEmptyString
);
219 /*static*/ void wxMemoryFSHandlerBase::RemoveFile(const wxString
& filename
)
221 wxMemoryFSHash::iterator i
= m_Hash
.find(filename
);
222 if ( i
== m_Hash
.end() )
224 wxLogError(_("Trying to remove file '%s' from memory VFS, "
225 "but it is not loaded!"),
240 wxMemoryFSHandler::AddFile(const wxString
& filename
,
241 const wxImage
& image
,
244 if ( !CheckDoesntExist(filename
) )
247 wxMemoryOutputStream mems
;
248 if ( image
.Ok() && image
.SaveFile(mems
, type
) )
250 m_Hash
[filename
] = new wxMemoryFSFile
253 wxImage::FindHandler(type
)->GetMimeType()
258 wxLogError(_("Failed to store image '%s' to memory VFS!"), filename
);
263 wxMemoryFSHandler::AddFile(const wxString
& filename
,
264 const wxBitmap
& bitmap
,
267 wxImage img
= bitmap
.ConvertToImage();
268 AddFile(filename
, img
, type
);
271 #endif // wxUSE_IMAGE
276 #endif // wxUSE_FILESYSTEM && wxUSE_FS_ZIP