test/wxtest_physfs.cpp
changeset 878 6d65c5e0049a
child 956 3da716cfe09f
equal deleted inserted replaced
877:99c2fd8e689d 878:6d65c5e0049a
       
     1 /**
       
     2  * Test program for PhysicsFS, using wxWidgets. May only work on Unix.
       
     3  *
       
     4  * Please see the file LICENSE.txt in the source's root directory.
       
     5  *
       
     6  *  This file written by Ryan C. Gordon.
       
     7  */
       
     8 
       
     9 #if ( (defined(__MACH__)) && (defined(__APPLE__)) )
       
    10 #define PLATFORM_MACOSX 1
       
    11 #include <Carbon/Carbon.h>
       
    12 #endif
       
    13 
       
    14 #include <stdio.h>
       
    15 #include <stdlib.h>
       
    16 #include <string.h>
       
    17 #include <time.h>
       
    18 #include <errno.h>
       
    19 
       
    20 #include <wx/wx.h>
       
    21 #include <wx/treectrl.h>
       
    22 
       
    23 #include "physfs.h"
       
    24 
       
    25 #define TEST_VER_MAJOR  1
       
    26 #define TEST_VER_MINOR  1
       
    27 #define TEST_VER_PATCH  1
       
    28 
       
    29 //static PHYSFS_uint32 do_buffer_size = 0;
       
    30 
       
    31 enum WxTestPhysfsMenuCommands
       
    32 {
       
    33     // start with standard menu items, since using the wxIDs will map them
       
    34     //  to sane things in the platform's UI (gnome icons in GTK+, moves the
       
    35     //  about and quit items to the Apple menu on Mac OS X, etc).
       
    36     MENUCMD_About = wxID_ABOUT,
       
    37     MENUCMD_Quit = wxID_EXIT,
       
    38 
       
    39     // non-standard menu items go here.
       
    40     MENUCMD_Init = wxID_HIGHEST,
       
    41     MENUCMD_Deinit,
       
    42     MENUCMD_AddArchive,
       
    43     MENUCMD_Mount,
       
    44     MENUCMD_Remove,
       
    45     MENUCMD_GetCDs,
       
    46     MENUCMD_SetWriteDir,
       
    47     MENUCMD_PermitSymLinks,
       
    48     MENUCMD_SetSaneConfig,
       
    49     MENUCMD_MkDir,
       
    50     MENUCMD_Delete,
       
    51     MENUCMD_Cat,
       
    52     MENUCMD_SetBuffer,
       
    53     MENUCMD_StressBuffer,
       
    54     MENUCMD_Append,
       
    55     MENUCMD_Write,
       
    56     MENUCMD_GetLastError,
       
    57 
       
    58 /*
       
    59     { "getdirsep",      cmd_getdirsep,      0, NULL                         },
       
    60     { "getsearchpath",  cmd_getsearchpath,  0, NULL                         },
       
    61     { "getbasedir",     cmd_getbasedir,     0, NULL                         },
       
    62     { "getuserdir",     cmd_getuserdir,     0, NULL                         },
       
    63     { "getwritedir",    cmd_getwritedir,    0, NULL                         },
       
    64     { "getrealdir",     cmd_getrealdir,     1, "<fileToFind>"               },
       
    65     { "exists",         cmd_exists,         1, "<fileToCheck>"              },
       
    66     { "isdir",          cmd_isdir,          1, "<fileToCheck>"              },
       
    67     { "issymlink",      cmd_issymlink,      1, "<fileToCheck>"              },
       
    68     { "filelength",     cmd_filelength,     1, "<fileToCheck>"              },
       
    69     { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>"            },
       
    70 */
       
    71 };
       
    72 
       
    73 
       
    74 class WxTestPhysfsFrame : public wxFrame
       
    75 {
       
    76 public:
       
    77     WxTestPhysfsFrame(const wxChar *argv0);
       
    78 
       
    79     void rebuildTree();
       
    80 
       
    81     void onMenuInit(wxCommandEvent &evt);
       
    82     void onMenuDeinit(wxCommandEvent &evt);
       
    83     void onMenuAddArchive(wxCommandEvent &evt);
       
    84     void onMenuGetCDs(wxCommandEvent &evt);
       
    85     void onMenuPermitSymLinks(wxCommandEvent &evt);
       
    86 
       
    87 private:
       
    88     wxTreeCtrl *fileTree;
       
    89     wxTreeItemId stateItem;
       
    90     wxTreeItemId fsItem;
       
    91 
       
    92     int err(int success);
       
    93     void fillFileSystemTree(const char *path, const wxTreeItemId &item);
       
    94     void doInit(const char *argv0);
       
    95     void doDeinit();
       
    96 
       
    97     DECLARE_EVENT_TABLE()
       
    98 };
       
    99 
       
   100 BEGIN_EVENT_TABLE(WxTestPhysfsFrame, wxFrame)
       
   101     EVT_MENU(MENUCMD_Init, WxTestPhysfsFrame::onMenuInit)
       
   102     EVT_MENU(MENUCMD_Deinit, WxTestPhysfsFrame::onMenuDeinit)
       
   103     EVT_MENU(MENUCMD_AddArchive, WxTestPhysfsFrame::onMenuAddArchive)
       
   104     EVT_MENU(MENUCMD_GetCDs, WxTestPhysfsFrame::onMenuGetCDs)
       
   105     EVT_MENU(MENUCMD_PermitSymLinks, WxTestPhysfsFrame::onMenuPermitSymLinks)
       
   106 END_EVENT_TABLE()
       
   107 
       
   108 
       
   109 
       
   110 // This is the the Application itself.
       
   111 class WxTestPhysfsApp : public wxApp
       
   112 {
       
   113 public:
       
   114     WxTestPhysfsApp() : mainWindow(NULL) { /* no-op. */ }
       
   115     virtual bool OnInit();
       
   116 
       
   117 private:
       
   118     WxTestPhysfsFrame *mainWindow;
       
   119 };
       
   120 
       
   121 DECLARE_APP(WxTestPhysfsApp)
       
   122 
       
   123 
       
   124 static inline char *newstr(const char *str)
       
   125 {
       
   126     char *retval = NULL;
       
   127     if (str != NULL)
       
   128     {
       
   129         retval = new char[strlen(str) + 1];
       
   130         strcpy(retval, str);
       
   131     } // if
       
   132     return retval;
       
   133 } // newstr
       
   134 
       
   135 static char *newutf8(const wxString &wxstr)
       
   136 {
       
   137     #if wxUSE_UNICODE
       
   138     size_t len = wxstr.Len() + 1;
       
   139     char *utf8text = new char[len * 6];
       
   140     wxConvUTF8.WC2MB(utf8text, wxstr, len);
       
   141     return utf8text;
       
   142     #else
       
   143     return newstr(wxstr);
       
   144     #endif
       
   145 } // newutf8
       
   146 
       
   147 
       
   148 WxTestPhysfsFrame::WxTestPhysfsFrame(const wxChar *argv0)
       
   149     : wxFrame(NULL, -1, wxT("WxTestPhysfs"))
       
   150 {
       
   151     this->CreateStatusBar();
       
   152 
       
   153     wxMenuBar *menuBar = new wxMenuBar;
       
   154 
       
   155     wxMenu *stuffMenu = new wxMenu;
       
   156     stuffMenu->Append(MENUCMD_Init, wxT("&Init"));
       
   157     stuffMenu->Append(MENUCMD_Deinit, wxT("&Deinit"));
       
   158     stuffMenu->Append(MENUCMD_AddArchive, wxT("&Add Archive"));
       
   159     stuffMenu->Append(MENUCMD_Mount, wxT("&Mount Archive"));
       
   160     stuffMenu->Append(MENUCMD_Remove, wxT("&Remove Archive"));
       
   161     stuffMenu->Append(MENUCMD_GetCDs, wxT("&Get CD-ROM drives"));
       
   162     stuffMenu->Append(MENUCMD_SetWriteDir, wxT("&Set Write Dir"));
       
   163     stuffMenu->Append(MENUCMD_SetSaneConfig, wxT("Set Sane &Config"));
       
   164     stuffMenu->Append(MENUCMD_MkDir, wxT("M&kDir"));
       
   165     stuffMenu->Append(MENUCMD_Delete, wxT("D&elete"));
       
   166     stuffMenu->Append(MENUCMD_Cat, wxT("&Cat"));
       
   167     stuffMenu->Append(MENUCMD_SetBuffer, wxT("Set &Buffer"));
       
   168     stuffMenu->Append(MENUCMD_StressBuffer, wxT("Stress &Test Buffer"));
       
   169     stuffMenu->Append(MENUCMD_Append, wxT("&Append"));
       
   170     stuffMenu->Append(MENUCMD_Write, wxT("&Write"));
       
   171     stuffMenu->Append(MENUCMD_Write, wxT("&Update getLastError"));
       
   172     stuffMenu->AppendCheckItem(MENUCMD_PermitSymLinks, wxT("&Permit symlinks"));
       
   173     menuBar->Append(stuffMenu, wxT("&Stuff"));
       
   174 
       
   175     //wxMenu *helpMenu = new wxMenu;
       
   176     //helpMenu->Append(MENUCMD_About, wxT("&About\tF1"));
       
   177     //menuBar->Append(helpMenu, wxT("&Help"));
       
   178 
       
   179     this->SetMenuBar(menuBar);
       
   180 
       
   181     this->fileTree = new wxTreeCtrl(this, -1);
       
   182 
       
   183     // The sizer just makes sure that fileTree owns whole client area.
       
   184     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
       
   185     sizer->Add(this->fileTree, 1, wxALL | wxEXPAND | wxALIGN_CENTRE);
       
   186     sizer->SetItemMinSize(this->fileTree, 1, 1);
       
   187     this->SetSizer(sizer);
       
   188 
       
   189     char *utf8argv0 = newutf8(wxString(argv0));
       
   190     this->doInit(utf8argv0);
       
   191     delete[] utf8argv0;
       
   192 } // WxTestPhysfsFrame::WxTestPhysfsFrame
       
   193 
       
   194 
       
   195 int WxTestPhysfsFrame::err(int success)
       
   196 {
       
   197     if (success)
       
   198         this->SetStatusText(wxT(""));
       
   199     else
       
   200         this->SetStatusText(wxString(PHYSFS_getLastError(), wxConvUTF8));
       
   201     return success;
       
   202 } // WxTestPhysfsFrame::err
       
   203 
       
   204 
       
   205 void WxTestPhysfsFrame::fillFileSystemTree(const char *path,
       
   206                                            const wxTreeItemId &item)
       
   207 {
       
   208     char **rc = PHYSFS_enumerateFiles(path);
       
   209     char **i;
       
   210     wxTreeItemId id;
       
   211 
       
   212     if (rc == NULL)
       
   213     {
       
   214         const wxString quote(wxT("'"));
       
   215         wxString str(wxT("Enumeration error: "));
       
   216         str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
       
   217         id = this->fileTree->AppendItem(item, str);
       
   218         this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
       
   219     } // if
       
   220     else
       
   221     {
       
   222         for (i = rc; *i != NULL; i++)
       
   223         {
       
   224             id = this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
       
   225             const int len = strlen(path) + strlen(*i) + 2;
       
   226             char *fname = new char[len];
       
   227             const char *origdir = path;
       
   228             if (strcmp(origdir, "/") == 0)
       
   229                 origdir = "";
       
   230             snprintf(fname, len, "%s/%s", origdir, *i);
       
   231 
       
   232             if (PHYSFS_isDirectory(fname))
       
   233             {
       
   234                 this->fileTree->SetItemTextColour(id, wxColour(0, 0, 255));
       
   235                 this->fillFileSystemTree(fname, id);
       
   236             } // if
       
   237 
       
   238             else if (PHYSFS_isSymbolicLink(fname))
       
   239             {
       
   240                 this->fileTree->SetItemTextColour(id, wxColour(0, 255, 0));
       
   241             } // else if
       
   242 
       
   243             else  // ...file.
       
   244             {
       
   245             } // else
       
   246 
       
   247             delete[] fname;
       
   248         } // for
       
   249 
       
   250         PHYSFS_freeList(rc);
       
   251     } // else
       
   252 } // fillFileSystemTree
       
   253 
       
   254 
       
   255 void WxTestPhysfsFrame::rebuildTree()
       
   256 {
       
   257     const wxString dot(wxT("."));
       
   258     const wxString quote(wxT("'"));
       
   259     wxTreeItemId item;
       
   260     wxString str;
       
   261     const char *cstr = NULL;
       
   262     const bool wasInit = PHYSFS_isInit() ? true : false;
       
   263 
       
   264     this->fileTree->DeleteAllItems();
       
   265     wxTreeItemId root = this->fileTree->AddRoot(wxT("PhysicsFS"));
       
   266     this->stateItem = this->fileTree->AppendItem(root, wxT("Library state"));
       
   267 
       
   268     str = wxT("Initialized: ");
       
   269     str << ((wasInit) ? wxT("true") : wxT("false"));
       
   270     this->fileTree->AppendItem(this->stateItem, str);
       
   271 
       
   272     this->fileTree->Expand(this->stateItem);
       
   273     this->fileTree->Expand(root);
       
   274 
       
   275     // Fill in version information...
       
   276 
       
   277     PHYSFS_Version ver;
       
   278     item = this->stateItem;
       
   279     str = wxT("wxtest_physfs version: ");
       
   280     str << TEST_VER_MAJOR << dot << TEST_VER_MINOR << dot << TEST_VER_PATCH;
       
   281     this->fileTree->AppendItem(item, str);
       
   282     PHYSFS_VERSION(&ver);
       
   283     str = wxT("Compiled against PhysicsFS version: ");
       
   284     str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
       
   285     this->fileTree->AppendItem(item, str);
       
   286     PHYSFS_getLinkedVersion(&ver);
       
   287     str = wxT("Linked against PhysicsFS version: ");
       
   288     str << (int) ver.major << dot << (int) ver.minor << dot << ver.patch;
       
   289     this->fileTree->AppendItem(item, str);
       
   290 
       
   291     if (!wasInit)
       
   292         return;   // nothing else to do before initialization...
       
   293 
       
   294     str = wxT("Symbolic links permitted: ");
       
   295     str << ((PHYSFS_symbolicLinksPermitted()) ? wxT("true") : wxT("false"));
       
   296     this->fileTree->AppendItem(this->stateItem, str);
       
   297 
       
   298     str = wxT("Native directory separator: ");
       
   299     str << quote << wxString(PHYSFS_getDirSeparator(), wxConvUTF8) << quote;
       
   300     this->fileTree->AppendItem(this->stateItem, str);
       
   301 
       
   302     // Fill in supported archives...
       
   303 
       
   304     item = this->fileTree->AppendItem(this->stateItem, wxT("Archivers"));
       
   305     const PHYSFS_ArchiveInfo **arcs = PHYSFS_supportedArchiveTypes();
       
   306     if (*arcs == NULL)
       
   307         this->fileTree->AppendItem(item, wxT("(none)"));
       
   308     else
       
   309     {
       
   310         const PHYSFS_ArchiveInfo **i;
       
   311         for (i = arcs; *i != NULL; i++)
       
   312         {
       
   313             const wxString ext((*i)->extension, wxConvUTF8);
       
   314             const wxString desc((*i)->description, wxConvUTF8);
       
   315             const wxString auth((*i)->author, wxConvUTF8);
       
   316             const wxString url((*i)->url, wxConvUTF8);
       
   317             wxTreeItemId arcitem = this->fileTree->AppendItem(item, ext);
       
   318             this->fileTree->AppendItem(arcitem, desc);
       
   319             this->fileTree->AppendItem(arcitem, auth);
       
   320             this->fileTree->AppendItem(arcitem, url);
       
   321         } // for
       
   322     } // else
       
   323 
       
   324 
       
   325     // Fill in the standard paths...
       
   326 
       
   327     item = this->fileTree->AppendItem(this->stateItem, wxT("Paths"));
       
   328     str = wxT("Base directory: ");
       
   329     str << quote << wxString(PHYSFS_getBaseDir(), wxConvUTF8) << quote;
       
   330     this->fileTree->AppendItem(item, str);
       
   331     str = wxT("User directory: ");
       
   332     str << quote << wxString(PHYSFS_getUserDir(), wxConvUTF8) << quote;
       
   333     this->fileTree->AppendItem(item, str);
       
   334     str = wxT("Write directory: ");
       
   335     if ((cstr = PHYSFS_getWriteDir()) == NULL)
       
   336         str << wxT("(NULL)");
       
   337     else
       
   338         str << quote << wxString(cstr ? cstr : "(NULL)", wxConvUTF8) << quote;
       
   339     this->fileTree->AppendItem(item, str);
       
   340     //str = wxT("Preference directory: ");
       
   341     //str << wxString(PHYSFS_getUserDir(), wxConvUTF8);
       
   342     //this->fileTree->AppendItem(item, str);
       
   343 
       
   344     // Fill in the CD-ROMs...
       
   345 
       
   346     item = this->fileTree->AppendItem(this->stateItem, wxT("CD-ROMs"));
       
   347     char **cds = PHYSFS_getCdRomDirs();
       
   348     if (cds == NULL)
       
   349     {
       
   350         str = wxT("Error: ");
       
   351         str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
       
   352         wxTreeItemId id = this->fileTree->AppendItem(item, str);
       
   353         this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
       
   354     } // if
       
   355     else
       
   356     {
       
   357         if (*cds == NULL)
       
   358             this->fileTree->AppendItem(item, wxT("(none)"));
       
   359         else
       
   360         {
       
   361             char **i;
       
   362             for (i = cds; *i != NULL; i++)
       
   363                 this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
       
   364         } // else
       
   365         PHYSFS_freeList(cds);
       
   366     } // else
       
   367 
       
   368     // Fill in search path...
       
   369 
       
   370     item = this->fileTree->AppendItem(this->stateItem, wxT("Search path"));
       
   371     char **sp = PHYSFS_getSearchPath();
       
   372     if (sp == NULL)
       
   373     {
       
   374         str = wxT("Error: ");
       
   375         str << quote << wxString(PHYSFS_getLastError(), wxConvUTF8) << quote;
       
   376         wxTreeItemId id = this->fileTree->AppendItem(item, str);
       
   377         this->fileTree->SetItemTextColour(id, wxColour(255, 0, 0));
       
   378     } // if
       
   379     else
       
   380     {
       
   381         if (*sp == NULL)
       
   382             this->fileTree->AppendItem(item, wxT("(none)"));
       
   383         else
       
   384         {
       
   385             char **i;
       
   386             for (i = sp; *i != NULL; i++)
       
   387                 this->fileTree->AppendItem(item, wxString(*i, wxConvUTF8));
       
   388         } // else
       
   389         PHYSFS_freeList(sp);
       
   390     } // else
       
   391 
       
   392     // Now fill in the filesystem...
       
   393 
       
   394     this->fsItem = this->fileTree->AppendItem(root, wxT("Filesystem"));
       
   395     this->fillFileSystemTree("/", this->fsItem);
       
   396     this->fileTree->Expand(this->fsItem);
       
   397 } // WxTestPhysfsFrame::rebuildTree
       
   398 
       
   399 
       
   400 void WxTestPhysfsFrame::doInit(const char *argv0)
       
   401 {
       
   402     if (!this->err(PHYSFS_init(argv0)))
       
   403         ::wxMessageBox(wxT("PHYSFS_init() failed!"), wxT("wxTestPhysfs"));
       
   404     this->rebuildTree();
       
   405 } // WxTestPhysfsFrame::doInit
       
   406 
       
   407 
       
   408 void WxTestPhysfsFrame::doDeinit()
       
   409 {
       
   410     if (!this->err(PHYSFS_deinit()))
       
   411         ::wxMessageBox(wxT("PHYSFS_deinit() failed!"), wxT("wxTestPhysfs"));
       
   412     this->rebuildTree();
       
   413 } // WxTestPhysfsFrame::doDeinit
       
   414 
       
   415 
       
   416 void WxTestPhysfsFrame::onMenuInit(wxCommandEvent &evt)
       
   417 {
       
   418     wxString argv0(wxGetApp().argv[0] == NULL ? wxT("") : wxGetApp().argv[0]);
       
   419     wxString str(wxGetTextFromUser(wxT("PHYSFS_init"),
       
   420                  wxT("argv[0]? (cancel for NULL)"), argv0));
       
   421     char *cstr = str.IsEmpty() ? NULL : newutf8(str);
       
   422     this->doInit(cstr);
       
   423     delete[] cstr;
       
   424 } // WxTestPhysfsFrame::onMenuInit
       
   425 
       
   426 
       
   427 void WxTestPhysfsFrame::onMenuDeinit(wxCommandEvent &evt)
       
   428 {
       
   429     this->doDeinit();
       
   430 } // WxTestPhysfsFrame::onMenuDeinit
       
   431 
       
   432 
       
   433 void WxTestPhysfsFrame::onMenuAddArchive(wxCommandEvent &evt)
       
   434 {
       
   435     wxString arc = wxFileSelector(wxT("Choose archive to add"));
       
   436     if (!arc.IsEmpty())
       
   437     {
       
   438         char *cstr = newutf8(arc);
       
   439         // !!! FIXME: add to start/end?
       
   440         if (!this->err(PHYSFS_addToSearchPath(cstr, 1)))
       
   441             ::wxMessageBox(wxT("PHYSFS_addToSearchPath() failed!"), wxT("wxTestPhysfs"));
       
   442         delete[] cstr;
       
   443         this->rebuildTree();
       
   444     } // if
       
   445 } // WxTestPhysfsFrame::onMenuAddArchive
       
   446 
       
   447 
       
   448 void WxTestPhysfsFrame::onMenuGetCDs(wxCommandEvent &evt)
       
   449 {
       
   450     this->rebuildTree();  // This will call PHYSFS_getCdRomDirs()...
       
   451 } // WxTestPhysfsFrame::onMenuGetCDs
       
   452 
       
   453 
       
   454 void WxTestPhysfsFrame::onMenuPermitSymLinks(wxCommandEvent &evt)
       
   455 {
       
   456     PHYSFS_permitSymbolicLinks(evt.IsChecked() ? 1 : 0);
       
   457     this->rebuildTree();
       
   458 } // WxTestPhysfsFrame::onMenuPermitSymLinks
       
   459 
       
   460 
       
   461 
       
   462 IMPLEMENT_APP(WxTestPhysfsApp)
       
   463 
       
   464 bool WxTestPhysfsApp::OnInit()
       
   465 {
       
   466     #if PLATFORM_MACOSX
       
   467     // This lets a stdio app become a GUI app. Otherwise, you won't get
       
   468     //  GUI events from the system and other things will fail to work.
       
   469     // Putting the app in an application bundle does the same thing.
       
   470     //  TransformProcessType() is a 10.3+ API. SetFrontProcess() is 10.0+.
       
   471     if (TransformProcessType != NULL)  // check it as a weak symbol.
       
   472     {
       
   473         ProcessSerialNumber psn = { 0, kCurrentProcess };
       
   474         TransformProcessType(&psn, kProcessTransformToForegroundApplication);
       
   475         SetFrontProcess(&psn);
       
   476     } // if
       
   477     #endif
       
   478 
       
   479     this->mainWindow = new WxTestPhysfsFrame(this->argv[0]);
       
   480     this->mainWindow->Show(true);
       
   481     SetTopWindow(this->mainWindow);
       
   482     return true;
       
   483 } // WxTestPhysfsApp::OnInit
       
   484 
       
   485 // end of wxtest_physfs.cpp ...
       
   486