home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / common / filesys.cpp < prev    next >
C/C++ Source or Header  |  2002-09-08  |  14KB  |  488 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        filesys.cpp
  3. // Purpose:     wxFileSystem class - interface for opening files
  4. // Author:      Vaclav Slavik
  5. // Copyright:   (c) 1999 Vaclav Slavik
  6. // CVS-ID:      $Id: filesys.cpp,v 1.36 2002/09/08 00:49:48 VZ Exp $
  7. // Licence:     wxWindows Licence
  8. /////////////////////////////////////////////////////////////////////////////
  9.  
  10. #ifdef __GNUG__
  11. #pragma implementation "filesys.h"
  12. #endif
  13.  
  14. #include "wx/wxprec.h"
  15.  
  16. #ifdef __BORDLANDC__
  17. #pragma hdrstop
  18. #endif
  19.  
  20.  
  21. #if wxUSE_FILESYSTEM
  22.  
  23. #include "wx/wfstream.h"
  24. #include "wx/module.h"
  25. #include "wx/filesys.h"
  26. #include "wx/mimetype.h"
  27. #include "wx/filename.h"
  28.  
  29.  
  30.  
  31. //--------------------------------------------------------------------------------
  32. // wxFileSystemHandler
  33. //--------------------------------------------------------------------------------
  34.  
  35. IMPLEMENT_ABSTRACT_CLASS(wxFileSystemHandler, wxObject)
  36.  
  37.  
  38. #if wxUSE_MIMETYPE
  39. static wxFileTypeInfo *gs_FSMimeFallbacks = NULL;
  40. #endif
  41.  
  42. wxString wxFileSystemHandler::GetMimeTypeFromExt(const wxString& location)
  43. {
  44.     wxString ext, mime;
  45.     wxString loc = GetRightLocation(location);
  46.     char c;
  47.     int l = loc.Length(), l2;
  48.  
  49.     l2 = l;
  50.     for (int i = l-1; i >= 0; i--)
  51.     {
  52.         c = loc[(unsigned int) i];
  53.         if ( c == wxT('#') )
  54.             l2 = i + 1;
  55.         if ( c == wxT('.') )
  56.         {
  57.             ext = loc.Right(l2-i-1);
  58.             break;
  59.         }
  60.         if ( (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':')) )
  61.             return wxEmptyString;
  62.     }
  63.  
  64. #if wxUSE_MIMETYPE
  65.     static bool s_MinimalMimeEnsured = FALSE;
  66.     if (!s_MinimalMimeEnsured) {
  67.         wxTheMimeTypesManager->AddFallbacks(gs_FSMimeFallbacks);
  68.         s_MinimalMimeEnsured = TRUE;
  69.     }
  70.  
  71.     wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
  72.     if ( !ft || !ft -> GetMimeType(&mime) )
  73.     {
  74.         mime = wxEmptyString;
  75.     }
  76.  
  77.     delete ft;
  78.  
  79.     return mime;
  80. #else
  81.     if ( ext.IsSameAs(wxT("htm"), FALSE) || ext.IsSameAs(_T("html"), FALSE) )
  82.         return wxT("text/html");
  83.     if ( ext.IsSameAs(wxT("jpg"), FALSE) || ext.IsSameAs(_T("jpeg"), FALSE) )
  84.         return wxT("image/jpeg");
  85.     if ( ext.IsSameAs(wxT("gif"), FALSE) )
  86.         return wxT("image/gif");
  87.     if ( ext.IsSameAs(wxT("png"), FALSE) )
  88.         return wxT("image/png");
  89.     if ( ext.IsSameAs(wxT("bmp"), FALSE) )
  90.         return wxT("image/bmp");
  91.     return wxEmptyString;
  92. #endif
  93. }
  94.  
  95.  
  96.  
  97. wxString wxFileSystemHandler::GetProtocol(const wxString& location) const
  98. {
  99.     wxString s = wxEmptyString;
  100.     int i, l = location.Length();
  101.     bool fnd;
  102.  
  103.     fnd = FALSE;
  104.     for (i = l-1; (i >= 0) && ((location[i] != wxT('#')) || (!fnd)); i--) {
  105.         if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
  106.     }
  107.     if (!fnd) return wxT("file");
  108.     for (++i; (i < l) && (location[i] != wxT(':')); i++) s << location[i];
  109.     return s;
  110. }
  111.  
  112.  
  113. wxString wxFileSystemHandler::GetLeftLocation(const wxString& location) const
  114. {
  115.     int i;
  116.     bool fnd;
  117.  
  118.     fnd = FALSE;
  119.     for (i = location.Length()-1; i >= 0; i--) {
  120.         if ((location[i] == wxT(':')) && (i != 1 /*win: C:\path*/)) fnd = TRUE;
  121.         else if (fnd && (location[i] == wxT('#'))) return location.Left(i);
  122.     }
  123.     return wxEmptyString;
  124. }
  125.  
  126. wxString wxFileSystemHandler::GetRightLocation(const wxString& location) const
  127. {
  128.     int i, l = location.Length();
  129.     int l2 = l + 1;
  130.     for (i = l-1; (i >= 0) && ((location[i] != wxT(':')) || (i == 1) || (location[i-2] == wxT(':'))); i--) {if (location[i] == wxT('#')) l2 = i + 1;}
  131.     if (i == 0) return wxEmptyString;
  132.     else return location.Mid(i + 1, l2 - i - 2);
  133. }
  134.  
  135. wxString wxFileSystemHandler::GetAnchor(const wxString& location) const
  136. {
  137.     char c;
  138.     int l = location.Length();
  139.  
  140.     for (int i = l-1; i >= 0; i--) {
  141.         c = location[i];
  142.         if (c == wxT('#')) return location.Right(l-i-1);
  143.         else if ((c == wxT('.')) || (c == wxT('/')) || (c == wxT('\\')) || (c == wxT(':'))) return wxEmptyString;
  144.     }
  145.     return wxEmptyString;
  146. }
  147.  
  148.  
  149. wxString wxFileSystemHandler::FindFirst(const wxString& WXUNUSED(spec),
  150.                                         int WXUNUSED(flags))
  151. {
  152.     return wxEmptyString;
  153. }
  154.  
  155. wxString wxFileSystemHandler::FindNext()
  156. {
  157.     return wxEmptyString;
  158. }
  159.  
  160. //--------------------------------------------------------------------------------
  161. // wxLocalFSHandler
  162. //--------------------------------------------------------------------------------
  163.  
  164.  
  165. wxString wxLocalFSHandler::ms_root;
  166.  
  167. bool wxLocalFSHandler::CanOpen(const wxString& location)
  168. {
  169.     return GetProtocol(location) == wxT("file");
  170. }
  171.  
  172. wxFSFile* wxLocalFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
  173. {
  174.     // location has Unix path separators
  175.     wxString right = ms_root + GetRightLocation(location);
  176.     wxFileName fn(right, wxPATH_UNIX);
  177.  
  178.     if (!wxFileExists(fn.GetFullPath()))
  179.         return (wxFSFile*) NULL;
  180.  
  181.     return new wxFSFile(new wxFFileInputStream(fn.GetFullPath()),
  182.                         right,
  183.                         GetMimeTypeFromExt(location),
  184.                         GetAnchor(location),
  185.                         wxDateTime(wxFileModificationTime(fn.GetFullPath())));
  186.  
  187. }
  188.  
  189. wxString wxLocalFSHandler::FindFirst(const wxString& spec, int flags)
  190. {
  191.     wxString right = ms_root + GetRightLocation(spec);
  192.     return wxFindFirstFile(right, flags);
  193. }
  194.  
  195. wxString wxLocalFSHandler::FindNext()
  196. {
  197.     return wxFindNextFile();
  198. }
  199.  
  200.  
  201.  
  202. //-----------------------------------------------------------------------------
  203. // wxFileSystem
  204. //-----------------------------------------------------------------------------
  205.  
  206. IMPLEMENT_DYNAMIC_CLASS(wxFileSystem, wxObject)
  207. IMPLEMENT_ABSTRACT_CLASS(wxFSFile, wxObject)
  208.  
  209.  
  210. wxList wxFileSystem::m_Handlers;
  211.  
  212.  
  213. static wxString MakeCorrectPath(const wxString& path)
  214. {
  215.     wxString p(path);
  216.     wxString r;
  217.     int i, j, cnt;
  218.  
  219.     cnt = p.Length();
  220.     for (i = 0; i < cnt; i++)
  221.       if (p.GetChar(i) == wxT('\\')) p.GetWritableChar(i) = wxT('/'); // Want to be windows-safe
  222.  
  223.     if (p.Left(2) == wxT("./")) { p = p.Mid(2); cnt -= 2; }
  224.  
  225.     if (cnt < 3) return p;
  226.  
  227.     r << p.GetChar(0) << p.GetChar(1);
  228.  
  229.     // skip trailing ../.., if any
  230.     for (i = 2; i < cnt && (p.GetChar(i) == wxT('/') || p.GetChar(i) == wxT('.')); i++) r << p.GetChar(i);
  231.  
  232.     // remove back references: translate dir1/../dir2 to dir2
  233.     for (; i < cnt; i++)
  234.     {
  235.         r << p.GetChar(i);
  236.         if (p.GetChar(i) == wxT('/') && p.GetChar(i-1) == wxT('.') && p.GetChar(i-2) == wxT('.'))
  237.         {
  238.             for (j = r.Length() - 2; j >= 0 && r.GetChar(j) != wxT('/') && r.GetChar(j) != wxT(':'); j--) {}
  239.             if (j >= 0 && r.GetChar(j) != wxT(':'))
  240.             {
  241.                 for (j = j - 1; j >= 0 && r.GetChar(j) != wxT('/') && r.GetChar(j) != wxT(':'); j--) {}
  242.                 r.Remove(j + 1);
  243.             }
  244.         }
  245.     }
  246.  
  247.     for (; i < cnt; i++) r << p.GetChar(i);
  248.  
  249.     return r;
  250. }
  251.  
  252.  
  253. void wxFileSystem::ChangePathTo(const wxString& location, bool is_dir)
  254. {
  255.     int i, pathpos = -1;
  256.  
  257.     m_Path = MakeCorrectPath(location);
  258.  
  259.     if (is_dir)
  260.     {
  261.         if (m_Path.Length() > 0 && m_Path.Last() != wxT('/') && m_Path.Last() != wxT(':'))
  262.             m_Path << wxT('/');
  263.     }
  264.  
  265.     else
  266.     {
  267.         for (i = m_Path.Length()-1; i >= 0; i--)
  268.         {
  269.             if (m_Path[(unsigned int) i] == wxT('/'))
  270.             {
  271.                 if ((i > 1) && (m_Path[(unsigned int) (i-1)] == wxT('/')) && (m_Path[(unsigned int) (i-2)] == wxT(':')))
  272.                 {
  273.                     i -= 2;
  274.                     continue;
  275.                 }
  276.                 else
  277.                 {
  278.                     pathpos = i;
  279.                     break;
  280.                 }
  281.             }
  282.             else if (m_Path[(unsigned int) i] == wxT(':')) {
  283.                 pathpos = i;
  284.                 break;
  285.             }
  286.         }
  287.         if (pathpos == -1)
  288.         {
  289.             for (i = 0; i < (int) m_Path.Length(); i++)
  290.             {
  291.                 if (m_Path[(unsigned int) i] == wxT(':'))
  292.                 {
  293.                     m_Path.Remove(i+1);
  294.                     break;
  295.                 }
  296.             }
  297.             if (i == (int) m_Path.Length())
  298.                 m_Path = wxEmptyString;
  299.         }
  300.         else
  301.         {
  302.             m_Path.Remove(pathpos+1);
  303.         }
  304.     }
  305. }
  306.  
  307.  
  308.  
  309. wxFSFile* wxFileSystem::OpenFile(const wxString& location)
  310. {
  311.     wxString loc = MakeCorrectPath(location);
  312.     unsigned i, ln;
  313.     char meta;
  314.     wxFSFile *s = NULL;
  315.     wxNode *node;
  316.  
  317.     ln = loc.Length();
  318.     meta = 0;
  319.     for (i = 0; i < ln; i++)
  320.     {
  321.         switch (loc[i])
  322.         {
  323.             case wxT('/') : case wxT(':') : case wxT('#') :
  324.                 meta = loc[i];
  325.                 break;
  326.         }
  327.         if (meta != 0) break;
  328.     }
  329.     m_LastName = wxEmptyString;
  330.  
  331.     // try relative paths first :
  332.     if (meta != wxT(':'))
  333.     {
  334.         node = m_Handlers.GetFirst();
  335.         while (node)
  336.         {
  337.             wxFileSystemHandler *h = (wxFileSystemHandler*) node -> GetData();
  338.             if (h->CanOpen(m_Path + loc))
  339.             {
  340.                 s = h->OpenFile(*this, m_Path + loc);
  341.                 if (s) { m_LastName = m_Path + loc; break; }
  342.             }
  343.             node = node->GetNext();
  344.         }
  345.     }
  346.  
  347.     // if failed, try absolute paths :
  348.     if (s == NULL)
  349.     {
  350.         node = m_Handlers.GetFirst();
  351.         while (node)
  352.         {
  353.             wxFileSystemHandler *h = (wxFileSystemHandler*) node->GetData();
  354.             if (h->CanOpen(loc))
  355.             {
  356.                 s = h->OpenFile(*this, loc);
  357.                 if (s) { m_LastName = loc; break; }
  358.             }
  359.             node = node->GetNext();
  360.         }
  361.     }
  362.     return (s);
  363. }
  364.  
  365.  
  366.  
  367. wxString wxFileSystem::FindFirst(const wxString& spec, int flags)
  368. {
  369.     wxNode *node;
  370.     wxString spec2(spec);
  371.  
  372.     m_FindFileHandler = NULL;
  373.  
  374.     for (int i = spec2.Length()-1; i >= 0; i--)
  375.         if (spec2[(unsigned int) i] == wxT('\\')) spec2.GetWritableChar(i) = wxT('/'); // Want to be windows-safe
  376.  
  377.     node = m_Handlers.GetFirst();
  378.     while (node)
  379.     {
  380.         m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
  381.         if (m_FindFileHandler -> CanOpen(m_Path + spec2))
  382.             return m_FindFileHandler -> FindFirst(m_Path + spec2, flags);
  383.         node = node->GetNext();
  384.     }
  385.  
  386.     node = m_Handlers.GetFirst();
  387.     while (node)
  388.     {
  389.         m_FindFileHandler = (wxFileSystemHandler*) node -> GetData();
  390.         if (m_FindFileHandler -> CanOpen(spec2))
  391.             return m_FindFileHandler -> FindFirst(spec2, flags);
  392.         node = node->GetNext();
  393.     }
  394.  
  395.     return wxEmptyString;
  396. }
  397.  
  398.  
  399.  
  400. wxString wxFileSystem::FindNext()
  401. {
  402.     if (m_FindFileHandler == NULL) return wxEmptyString;
  403.     else return m_FindFileHandler -> FindNext();
  404. }
  405.  
  406.  
  407.  
  408. void wxFileSystem::AddHandler(wxFileSystemHandler *handler)
  409. {
  410.     m_Handlers.Append(handler);
  411. }
  412.  
  413.  
  414. void wxFileSystem::CleanUpHandlers()
  415. {
  416.     m_Handlers.DeleteContents(TRUE);
  417.     m_Handlers.Clear();
  418. }
  419.  
  420.  
  421.  
  422.  
  423. ///// Module:
  424.  
  425. class wxFileSystemModule : public wxModule
  426. {
  427.     DECLARE_DYNAMIC_CLASS(wxFileSystemModule)
  428.  
  429.     public:
  430.         virtual bool OnInit()
  431.         {
  432.             wxFileSystem::AddHandler(new wxLocalFSHandler);
  433.  
  434.         #if wxUSE_MIMETYPE
  435.             gs_FSMimeFallbacks = new wxFileTypeInfo[6];
  436.             gs_FSMimeFallbacks[0] =
  437.             wxFileTypeInfo(_T("image/jpeg"),
  438.                            _T(""),
  439.                            _T(""),
  440.                            _T("JPEG image (from fallback)"),
  441.                            _T("jpg"), _T("jpeg"), NULL);
  442.             gs_FSMimeFallbacks[1] =
  443.             wxFileTypeInfo(_T("image/gif"),
  444.                            _T(""),
  445.                            _T(""),
  446.                            _T("GIF image (from fallback)"),
  447.                            _T("gif"), NULL);
  448.             gs_FSMimeFallbacks[2] =
  449.             wxFileTypeInfo(_T("image/png"),
  450.                            _T(""),
  451.                            _T(""),
  452.                            _T("PNG image (from fallback)"),
  453.                            _T("png"), NULL);
  454.             gs_FSMimeFallbacks[3] =
  455.             wxFileTypeInfo(_T("image/bmp"),
  456.                            _T(""),
  457.                            _T(""),
  458.                            _T("windows bitmap image (from fallback)"),
  459.                            _T("bmp"), NULL);
  460.             gs_FSMimeFallbacks[4] =
  461.             wxFileTypeInfo(_T("text/html"),
  462.                            _T(""),
  463.                            _T(""),
  464.                            _T("HTML document (from fallback)"),
  465.                            _T("htm"), _T("html"), NULL);
  466.             gs_FSMimeFallbacks[5] =
  467.             // must terminate the table with this!
  468.             wxFileTypeInfo();
  469.         #endif
  470.             return TRUE;
  471.         }
  472.         virtual void OnExit()
  473.         {
  474.         #if wxUSE_MIMETYPE
  475.             delete [] gs_FSMimeFallbacks;
  476.         #endif
  477.             wxFileSystem::CleanUpHandlers();
  478.         }
  479. };
  480.  
  481. IMPLEMENT_DYNAMIC_CLASS(wxFileSystemModule, wxModule)
  482.  
  483. #endif
  484.   // wxUSE_FILESYSTEM
  485.  
  486.  
  487.  
  488.