Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

io_manager.C

Go to the documentation of this file.
00001 // io_manager.C
00002 
00003 #include "io_manager.H"
00004 #include "std/file.H"
00005 
00006 /*****************************************************************
00007  * IOManager
00008  *****************************************************************/
00009 
00010 /////////////////////////////////////
00011 // Static Variable Initialization
00012 /////////////////////////////////////
00013 TAGlist *      IOManager::_io_tags = NULL;
00014 IOManager *    IOManager::_instance = NULL;
00015 
00016 /////////////////////////////////////
00017 // tags()
00018 /////////////////////////////////////
00019 CTAGlist &
00020 IOManager::tags() const
00021 {
00022    if (!_io_tags) {
00023       _io_tags = new TAGlist;
00024  
00025       *_io_tags += new TAG_meth<IOManager>(
00026          "basename",
00027          &IOManager::put_basename,
00028          &IOManager::get_basename,
00029          1);
00030    }
00031    return *_io_tags;
00032 }
00033 
00034 /////////////////////////////////////
00035 // get_basename()
00036 /////////////////////////////////////
00037 void
00038 IOManager::get_basename (TAGformat &d) 
00039 {
00040    assert(state_() == STATE_SCENE_LOAD);
00041 
00042    str_ptr str;
00043    *d >> str; 
00044 
00045    if (str == "NULL_STR") 
00046    {
00047       _basename = NULL_STR;
00048       err_mesg(ERR_LEV_SPAM, "IOManager::get_basename() - Loaded NULL string.");
00049    }
00050    else
00051    {
00052       _basename = str;
00053       err_mesg(ERR_LEV_SPAM, "IOManager::get_basename() - Loaded string: '%s'", **str);
00054    }
00055    
00056 }
00057 
00058 /////////////////////////////////////
00059 // put_basename()
00060 /////////////////////////////////////
00061 void
00062 IOManager::put_basename (TAGformat &d) const
00063 {
00064    assert(state_() == STATE_SCENE_SAVE);
00065 
00066    d.id();
00067    if (_basename == NULL_STR)
00068    {
00069       err_mesg(ERR_LEV_SPAM, "IOManager::put_basename() - Wrote NULL string.");
00070       *d << str_ptr("NULL_STR");
00071    }
00072    else
00073    {
00074       *d << _basename;
00075       err_mesg(ERR_LEV_SPAM, "IOManager::put_basename() - Wrote string: '%s'", **_basename);
00076    }
00077    d.end_id();
00078 }
00079 
00080 /////////////////////////////////////
00081 // Constructor
00082 /////////////////////////////////////
00083 
00084 IOManager::IOManager() : 
00085    _basename(NULL_STR),
00086    _cached_cwd_plus_basename(NULL_STR),
00087    _old_cwd(NULL_STR),
00088    _old_basename(NULL_STR)
00089 {  
00090    assert(!_instance); 
00091 
00092    preload_obs();
00093    postload_obs();
00094    presave_obs();
00095    postsave_obs();
00096 
00097    _state.add(STATE_IDLE);
00098 
00099    err_mesg(ERR_LEV_SPAM, "IOManager::IOManager() - Instantiated."); 
00100 }
00101 
00102 /////////////////////////////////////
00103 // Destructor
00104 /////////////////////////////////////
00105 IOManager::~IOManager() 
00106 { 
00107    //XXX - Never bother to clean up _instance...
00108    
00109    assert(0);
00110 
00111    //unobs_preload();
00112    //unobs_postload();
00113    //unobs_presave();
00114    //unobs_postsave();
00115 }
00116 
00117 /////////////////////////////////////
00118 // notify_preload
00119 /////////////////////////////////////
00120 void      
00121 IOManager::notify_preload(
00122    NetStream     &s,
00123    load_status_t &load_status,
00124    bool           from_file,
00125    bool           full_scene
00126    )
00127 {
00128 
00129    bool ret;
00130    str_ptr path,file,ext;
00131    str_ptr cpath,cfile,cext;
00132 
00133    //Actually, this never happens, nevertheless...
00134    if (!from_file) 
00135    {
00136       err_mesg(ERR_LEV_INFO, "IOManager::notify_preload() - *WARNING* Loading from non-file source. Aborting..."); 
00137       return;
00138    }
00139 
00140 
00141    switch(state_())
00142    {
00143       //If we're not already doing some kind of IO, 
00144       //fire up the desired state...
00145       case STATE_IDLE:
00146          _state.add((full_scene)?(STATE_SCENE_LOAD):(STATE_PARTIAL_LOAD));
00147          err_mesg(ERR_LEV_INFO, "IOManager::notify_preload() - Loading '%s'... [Source: '%s']",
00148             ((full_scene)?("entire scene"):("scene update")), **s.name());
00149       break;
00150       //If we're already saving a entire scene, we might encounter
00151       //and enmbedded partial load when we are loading and
00152       //saving the scene update files...
00153       case STATE_SCENE_SAVE:
00154          assert(!full_scene);
00155          _state.add(STATE_PARTIAL_LOAD);
00156          err_mesg(ERR_LEV_INFO,
00157             "IOManager::notify_preload() - Loading 'scene update' for subsequent save... [Source: '%s']",
00158                **s.name());
00159       break;
00160      //No other states should reach this callback...
00161       case STATE_PARTIAL_SAVE:
00162       case STATE_SCENE_LOAD:
00163       case STATE_PARTIAL_LOAD:
00164       default:
00165          assert(0);
00166       break;
00167    }
00168 
00169    if (load_status != LOADobs::LOAD_ERROR_NONE)
00170    {
00171       err_mesg(ERR_LEV_INFO, 
00172          "IOManager::notify_preload() - *WARNING* Load procedure already in error state. Aborting...");
00173       return;
00174    }
00175 
00176    if (state_() == STATE_SCENE_LOAD)
00177    {
00178       //About to load an entire new scene...The given stream
00179       //will be interpreted as is.  However, external data files,
00180       //like .npr or .sm files must have the right cwd set.
00181       //We'll extract that information from the path part of the
00182       //stream's name, since that should have been set to the 
00183       //fullpath used to open the file-based stream!
00184 
00185       //Clear the scene ...
00186       //XXX - This is hacky, and needs a clearner method...
00187       // XXX - following is commented out. Referencing draw lib from net lib
00188       //       breaks the link for stand-along apps in the mesh and convert
00189       //       directories. Draw_int::do_clear() is now called instead from
00190       //       Draw_int::do_load():
00191 //       if (Draw_int::get_instance())
00192 //          Draw_int::get_instance()->do_clear();
00193 
00194       //Blank the basename, since old-style files won't have a new name to load...
00195       //This will be prefixed to all attempts at loading external data files...
00196       _basename = NULL_STR;
00197 
00198       //Blank out the last successful saved or loaded "cwd+basename prefix"
00199       _cached_cwd_plus_basename = NULL_STR;
00200       
00201       //Save the old cwd in case of failure
00202       if ((_old_cwd = getcwd_()) == NULL_STR)
00203       {
00204          err_msg(
00205             "IOManager::notify_preload() - *WARNING* Couldn't save current working directory. Aborting...");
00206          load_status = LOADobs::LOAD_ERROR_CWD;
00207       }
00208       //Now, set new cwd...
00209       //Stream name should be the filename for file streams.
00210       //Extract path, file and extension... Abort on failure...
00211       else if (!split_filename(s.name(),path,file,ext))
00212       {
00213          err_msg(
00214             "IOManager::notify_preload() - *WARNING* Couldn't derive a path from stream target: '%s'. Aborting...", 
00215                **s.name());
00216          load_status = LOADobs::LOAD_ERROR_CWD;
00217       }
00218       else
00219       {
00220          //Actually change to the new cwd (Guaranteed to succeed by split_filename)
00221          ret = chdir_(path); assert(ret);
00222          err_mesg(ERR_LEV_SPAM, 
00223             "IOManager::notify_preload() - Set new current working directory: '%s'.", **path);
00224       }
00225    }
00226    else //STATE_PARTIAL_LOAD
00227    {
00228       //About to load a partial scene (or update, or something...)
00229 
00230       //These loads should occur in the cached cwd defined by
00231       //the last full scene loaded (to which this load is
00232       //an update).  Let's compare...
00233       
00234       if (!split_filename(_cached_cwd_plus_basename,cpath,cfile,cext))
00235       {
00236          err_msg(
00237             "IOManager::notify_preload() - *WARNING* Couldn't derive a path from cached path prefix: '%s'. Aborting...",
00238                **_cached_cwd_plus_basename);
00239          load_status = LOADobs::LOAD_ERROR_CWD;
00240       }
00241       else if (!split_filename(s.name(),path,file,ext))
00242       {
00243          err_msg(
00244             "IOManager::notify_preload() - *WARNING* Couldn't derive a path from stream target: '%s'. Aborting...",
00245                **s.name());
00246          load_status = LOADobs::LOAD_ERROR_CWD;
00247       }
00248       else if (path != cpath)
00249       {
00250          err_msg(
00251             "IOManager::notify_preload() - *WARNING* Scene update load path doesn't match cached working directory. Aborting...");
00252          load_status = LOADobs::LOAD_ERROR_CWD;
00253       }
00254       else
00255       {
00256          err_mesg(ERR_LEV_SPAM, 
00257             "IOManager::notify_preload() - Maintaining cached working directory: '%s'.", **path);
00258       }
00259    }
00260 }
00261 
00262 
00263 /////////////////////////////////////
00264 // notify_postload
00265 /////////////////////////////////////
00266 void      
00267 IOManager::notify_postload(
00268    NetStream     &s,
00269    load_status_t &load_status,
00270    bool           from_file,
00271    bool           full_scene
00272    )
00273 {
00274    str_ptr path;
00275 
00276    //Actually, this never happens, nevertheless...
00277    if (!from_file) 
00278    {
00279       err_mesg(ERR_LEV_INFO, "IOManager::notify_postload() - *WARNING* Loading from non-file source. Aborting..."); 
00280       assert(state_() == STATE_IDLE);
00281       return;
00282    }
00283 
00284    assert(state_() == ((full_scene)?(STATE_SCENE_LOAD):(STATE_PARTIAL_LOAD)) );
00285 
00286    //Successful load!
00287    if (load_status == LOADobs::LOAD_ERROR_NONE)
00288    {
00289       if (state_() == STATE_SCENE_LOAD)
00290       {
00291          //New scene loaded...
00292 
00293          //Keep the new cwd
00294 
00295          //Keep the new basename (NULL_STR, or loaded from file)
00296 
00297          //Set the _cached_cwd_plus_basename so updates can
00298          //use this to prefix external file references...
00299 
00300          if ((path = getcwd_()) == NULL_STR)
00301          {
00302             err_msg(
00303                "IOManager::notify_postload() - *WARNING* Couldn't cache current working directory. Aborting...");
00304             load_status = LOADobs::LOAD_ERROR_CWD;
00305          }
00306          else
00307          {
00308             _cached_cwd_plus_basename = path + "/" + _basename + ((_basename!=NULL_STR)?("--"):(NULL_STR));
00309             
00310             //err_msg(
00311             //   "IOManager::notify_postload() - ...completed 'entire scene' load. [Source: '%s']", **s.name());
00312             err_mesg(ERR_LEV_INFO, 
00313                "IOManager::notify_postload() - ...completed 'entire scene' load.");
00314             err_mesg(ERR_LEV_INFO, 
00315                "IOManager::notify_postload() - Caching this file load/save prefix: '%s'",
00316                   **_cached_cwd_plus_basename);
00317          }
00318       }
00319       else //STATE_PARTIAL_LOAD
00320       {
00321          //Scene update loaded!
00322          
00323          //Keep old _basename
00324          
00325          //Keep old _cached_cwd_plus_basename 
00326          //err_mesg(ERR_LEV_INFO, 
00327          //   "IOManager::notify_postload() - ...completed 'scene update' load. [Source: '%s']", **s.name());
00328          err_mesg(ERR_LEV_INFO, 
00329             "IOManager::notify_postload() - ...completed 'scene update' load.");
00330 
00331       }
00332    }
00333    //Failed load!
00334    else
00335    {
00336       if (state_() == STATE_SCENE_LOAD)
00337       {
00338          //New scene failed to loaded...
00339 
00340          _basename = NULL_STR;
00341          _cached_cwd_plus_basename = NULL_STR;
00342 
00343          err_msg(
00344             "IOManager::notify_postload() - ...failed 'entire scene' load. [Source: '%s']", **s.name());
00345 
00346          if (_old_cwd != NULL_STR)
00347          {
00348             if (chdir_(_old_cwd))
00349             {
00350                err_mesg(ERR_LEV_INFO, 
00351                   "IOManager::notify_postload() - Restored old current working directory: '%s'", 
00352                      **_old_cwd);
00353             }
00354             else
00355             {
00356                err_msg(
00357                   "IOManager::notify_postload() - *Warning* Failed restoring old current working directory: '%s'",
00358                      **_old_cwd);
00359                //XXX - Set this?!
00360                load_status = LOADobs::LOAD_ERROR_CWD;
00361             }
00362          }
00363          else
00364          {
00365             err_msg(
00366                "IOManager::notify_postload() - *Warning* No saved current working directory to restore.");
00367          }
00368       }
00369       else //STATE_PARTIAL_LOAD
00370       {
00371          //Scene update failed!
00372          
00373          //Keep old _basename (shouldn't have changed)
00374 
00375          //Keep old _cached_cwd_plus_basename 
00376          err_msg(
00377             "IOManager::notify_postload() - ...failed 'scene update' load. [Source: '%s']", **s.name());
00378       }
00379    }
00380    _state.pop();
00381    assert(_state.num() > 0);
00382 }
00383 
00384 /////////////////////////////////////
00385 // notify_presave
00386 /////////////////////////////////////
00387 void      
00388 IOManager::notify_presave(
00389    NetStream     &s,
00390    save_status_t &save_status,
00391    bool           to_file,
00392    bool           full_scene
00393    )
00394 {
00395    bool ret;
00396    str_ptr path,file,ext;
00397 
00398    //Actually, this never happens, nevertheless...
00399    if (!to_file) 
00400    {
00401       err_mesg(ERR_LEV_INFO, "IOManager::notify_presave() - *WARNING* Saving to non-file source. Aborting..."); 
00402       return;
00403    }
00404 
00405    switch(state_())
00406    {
00407       //If we're not already doing some kind of IO, 
00408       //we only expect a full scene save...
00409       case STATE_IDLE:
00410          assert(full_scene);
00411          _state.add(STATE_SCENE_SAVE);
00412          err_mesg(ERR_LEV_INFO, 
00413             "IOManager::notify_presave() - Saving 'entire scene'... [Dest: '%s']",
00414                **s.name());
00415       break;
00416       //If we're already saving a full scene, we might encounter
00417       //and enmbedded partial save when we are loading and
00418       //resaving the scene update files...
00419       case STATE_SCENE_SAVE:
00420          assert(!full_scene);
00421          _state.add(STATE_PARTIAL_SAVE);
00422          err_mesg(ERR_LEV_INFO, 
00423             "IOManager::notify_presave() - Saving 'scene update'... [Dest: '%s']",
00424                **s.name());
00425       break;
00426       //No other states should reach this callback...
00427       case STATE_PARTIAL_SAVE:
00428       case STATE_SCENE_LOAD:
00429       case STATE_PARTIAL_LOAD:
00430       default:
00431          assert(0);
00432       break;
00433    }
00434 
00435 
00436    if (save_status != SAVEobs::SAVE_ERROR_NONE)
00437    {
00438       err_mesg(ERR_LEV_INFO, 
00439          "IOManager::notify_presave() - *WARNING* Save procedure already in error state. Aborting...");
00440       return;
00441    }
00442 
00443    if (state_() == STATE_SCENE_SAVE)
00444    {
00445       //About to save new scene... Given stream is used to serialize
00446       //the scene.  But external files like .npr and .sm need the
00447       //right cwd to be set so they get saved to the right place.  
00448       //The cwd and basename prefix attached to all external files will 
00449       //be derived from the path and filename (sans extension)
00450       //that was used to open the stream...
00451 
00452 
00453       //Keep the last successful saved or loaded "cwd+basename prefix"
00454       //because we'll want to load old scene update files from this location
00455       //and then re-save to the new cwd+basename...
00456       
00457       //_cached_cwd_plus_basename unchanged
00458 
00459       //Save old cwd and basename in case of save failure...
00460       _old_basename = _basename;
00461       if ((_old_cwd = getcwd_()) == NULL_STR)
00462       {
00463          err_msg(
00464             "IOManager::notify_presave() - *WARNING* Couldn't save current working directory. Aborting...");
00465          save_status = SAVEobs::SAVE_ERROR_CWD;
00466       }
00467       else
00468       {
00469 
00470          //Now, set new cwd and basename...
00471 
00472          //Stream name should be the filename for file streams.
00473          //Extract path, file and extension... Abort on failure...
00474          if (!split_filename(s.name(),path,file,ext))
00475          {
00476             err_msg(
00477                "IOManager::notify_presave() - *WARNING* Couldn't derive valid path from target: '%s'. Aborting...", 
00478                   **s.name());
00479             save_status = SAVEobs::SAVE_ERROR_CWD;
00480          }
00481          else
00482          {
00483             //Actually change to the new cwd (Guaranteed to succeed by split_filename)
00484             _basename = file;
00485             err_mesg(ERR_LEV_INFO, 
00486                "IOManager::notify_presave() - Set new current basename file prefix: '%s'.", **file);
00487             
00488             ret = chdir_(path); assert(ret);
00489 
00490             err_mesg(ERR_LEV_INFO, 
00491               "IOManager::notify_presave() - Set new current working directory: '%s'.", **path);
00492          }
00493       }
00494    }
00495    else //STATE_PARTIAL_SAVE
00496    {
00497       //About to save a scene update...
00498 
00499       //These scene update saves should occur in same cwd as defined by
00500       //the currently occuring full save There should, therefore, be not path
00501       //component to the filename... Check this!
00502 
00503       if (!split_filename(s.name(),path,file,ext))
00504       {
00505          err_msg(
00506             "IOManager::notify_presave() - *WARNING* Couldn't derive valid path from target: '%s'. Aborting...", 
00507                **s.name());
00508          save_status = SAVEobs::SAVE_ERROR_CWD;
00509       }
00510       else if (path != getcwd_())
00511       {
00512          err_msg(
00513             "IOManager::notify_presave() - *WARNING* Path for 'scene update' doesn't match current working directory. Aborting...");
00514          save_status = SAVEobs::SAVE_ERROR_CWD;
00515       }
00516       else
00517       {
00518          err_mesg(ERR_LEV_INFO, 
00519            "IOManager::notify_presave() - Maintaing working directory: '%s'.", **path);
00520       }
00521 
00522    }
00523 }
00524 
00525 /////////////////////////////////////
00526 // notify_postsave
00527 /////////////////////////////////////
00528 void      
00529 IOManager::notify_postsave(
00530    NetStream     &s,
00531    save_status_t &save_status,
00532    bool           to_file,
00533    bool           full_scene
00534    )
00535 {
00536  
00537    str_ptr path;
00538 
00539    //Actually, this never happens, nevertheless...
00540    if (!to_file) 
00541    {
00542       err_mesg(ERR_LEV_INFO, "IOManager::notify_postsave() - *WARNING* Saving to non-file source. Aborting..."); 
00543       assert(state_() == STATE_IDLE);
00544       return;
00545    }
00546 
00547    assert(state_() == ((full_scene)?(STATE_SCENE_SAVE):(STATE_PARTIAL_SAVE)));
00548 
00549    //Successful save!
00550    if (save_status == SAVEobs::SAVE_ERROR_NONE)
00551    {
00552       if (state_() == STATE_SCENE_SAVE)
00553       {
00554          //New scene saveed...
00555 
00556          //Keep the new cwd
00557 
00558          //Keep the new basename (derived from stream's filename)
00559 
00560          //Set the _cached_cwd_plus_basename so scene updates can load
00561          //using this to prefix in all external file references...
00562 
00563          if ((path = getcwd_()) == NULL_STR)
00564          {
00565             err_msg(
00566                "IOManager::notify_postsave() - *WARNING* Couldn't cache current working directory. Aborting...");
00567             save_status = SAVEobs::SAVE_ERROR_CWD;
00568          }
00569          else
00570          {
00571             _cached_cwd_plus_basename = path + "/" + _basename + ((_basename!=NULL_STR)?("--"):(NULL_STR));
00572             //err_msg(
00573             //   "IOManager::notify_postsave() - ...completed 'entire scene' save. [Dest: '%s']", **s.name());
00574             err_mesg(ERR_LEV_INFO, 
00575                "IOManager::notify_postsave() - ...completed 'entire scene' save.");
00576             err_mesg(ERR_LEV_INFO, 
00577                "IOManager::notify_postsave() - Caching this file load/save prefix: '%s'",
00578                   **_cached_cwd_plus_basename);
00579          }
00580       }
00581       else //STATE_PARTIAL_SAVE
00582       {
00583          //Scene update saveed!
00584          
00585          //Keep old _basename
00586          
00587          //Keep old _cached_cwd_plus_basename 
00588          //err_mesg(ERR_LEV_INFO, 
00589          //   "IOManager::notify_postsave() - ...completed 'scene update' save. [Dest: '%s']", **s.name());
00590          err_mesg(ERR_LEV_INFO, 
00591             "IOManager::notify_postsave() - ...completed 'scene update' save.");
00592       }
00593    }
00594 
00595    //Failed save! (Including due to failure directly above...)
00596    if (save_status != SAVEobs::SAVE_ERROR_NONE)
00597    {
00598       if (state_() == STATE_SCENE_SAVE)
00599       {
00600          //Scene failed to save...
00601 
00602          //Keep the last successful saved or loaded "cwd+basename prefix"
00603          //because we'll still want to copy old scene update files from this location
00604          //until a successful save provides a new location...
00605          
00606          //_cached_cwd_plus_basename;
00607 
00608          //Restore old basename prefix
00609          _basename = _old_basename;
00610 
00611          err_msg(
00612             "IOManager::notify_postsave() - ...failed 'entire scene' save. [Dest: '%s']", **s.name());
00613 
00614          //Restore old cwd
00615          if (_old_cwd != NULL_STR)
00616          {
00617             if (chdir_(_old_cwd))
00618             {
00619                err_mesg(ERR_LEV_INFO, 
00620                   "IOManager::notify_postsave() - Restoring old current working directory: '%s'",
00621                      **_old_cwd);
00622             }
00623             else
00624             {
00625                err_msg(
00626                   "IOManager::notify_postsave() - *Warning* Failed restoring old current working directory: '%s'",
00627                      **_old_cwd);
00628                 //XXX - Set this?!
00629                save_status = SAVEobs::SAVE_ERROR_CWD;
00630             }
00631          }
00632          else
00633          {
00634             err_msg(
00635                "IOManager::notify_postsave() - *Warning* No saved current working directory to restore.");
00636          }
00637       }
00638       else //STATE_PARTIAL_SAVE
00639       {
00640          //Failed cene update save!
00641          
00642          //Keep old _basename
00643          
00644          //Keep old _cached_cwd_plus_basename 
00645 
00646          err_msg(
00647             "IOManager::notify_postsave() - ...failed 'scene update' save. [Dest: '%s']", **s.name());
00648       }
00649    }
00650    _state.pop();
00651    assert(_state.num() > 0);
00652 }
00653 
00654 
00655 /////////////////////////////////////
00656 // load_prefix_()
00657 /////////////////////////////////////
00658 str_ptr
00659 IOManager::load_prefix_()
00660 {
00661    str_ptr ret;
00662 
00663    switch(state_())
00664    {
00665       //If we're not currently doing anything, just use the cwd...
00666       case STATE_IDLE:
00667          ret = cwd_();
00668       break;
00669       //Full scenes load from the cwd+basename
00670       case STATE_SCENE_LOAD:
00671          ret = current_prefix_();
00672       break;
00673       //Scenes updates load from the cached_cwd+basename
00674       case STATE_PARTIAL_LOAD:
00675          ret = cached_prefix_();
00676       break;
00677       //We shouldn't be asking in this state...      
00678       case STATE_SCENE_SAVE:
00679       case STATE_PARTIAL_SAVE:
00680       default:
00681          assert(0);
00682       break;
00683    }
00684    return ret;
00685 }
00686 
00687 /////////////////////////////////////
00688 // save_prefix_()
00689 /////////////////////////////////////
00690 str_ptr
00691 IOManager::save_prefix_()
00692 {
00693    str_ptr ret;
00694 
00695    switch(state_())
00696    {
00697       //If we're not currently doing anything, just use the cwd...
00698       case STATE_IDLE:
00699          ret = cwd_();
00700       break;
00701       //All saves prefix with the cwd+basename
00702       case STATE_SCENE_SAVE:
00703       case STATE_PARTIAL_SAVE:
00704          ret = current_prefix_();
00705       break;
00706       //We shouldn't be asking if these are the state...
00707       case STATE_SCENE_LOAD:
00708       case STATE_PARTIAL_LOAD:
00709       default:
00710          assert(0);
00711       break;
00712    }
00713    return ret;
00714 }
00715 
00716 /////////////////////////////////////
00717 // cwd_()
00718 /////////////////////////////////////
00719 str_ptr
00720 IOManager::cwd_()
00721 {
00722    str_ptr ret;
00723 
00724    ret = getcwd_();
00725    if (ret != NULL_STR) ret = ret + "/";
00726 
00727    //XXX - If root directory, will end up with double slashes.
00728    //      Usually harmless, but should fix...
00729 
00730    return ret;
00731 }
00732 
00733 /////////////////////////////////////
00734 // current_prefix_() 
00735 /////////////////////////////////////
00736 str_ptr
00737 IOManager::current_prefix_()
00738 {
00739    str_ptr ret;
00740 
00741    ret = cwd_();
00742    if (_basename != NULL_STR) ret = ret + _basename + "--";
00743 
00744    return ret;
00745 }
00746 
00747 /////////////////////////////////////
00748 // cached_prefix_()
00749 /////////////////////////////////////
00750 str_ptr
00751 IOManager::cached_prefix_()
00752 {
00753    return _cached_cwd_plus_basename;
00754 }
00755 
00756 /////////////////////////////////////
00757 // split_filename()
00758 /////////////////////////////////////
00759 bool      
00760 IOManager::split_filename(
00761    Cstr_ptr &fullpath, 
00762    str_ptr  &path, 
00763    str_ptr  &file,
00764    str_ptr  &ext)
00765 {
00766    bool result;
00767 
00768    //Divide an incoming filename, with optional
00769    //absolute or relative path component,
00770    //into an absolute path, filename and file extension strings.
00771    
00772    //Relative paths are resolved against the cwd
00773 
00774    //Absoute path "path + '/' + file + extension" will
00775    //be equivalent to resolving full_filenamne against the cwd
00776 
00777    //The path component must exist... 
00778    //Returns false on failure and path, file, ext undefined
00779 
00780    //Save this before mucking about...
00781    str_ptr old_cwd = getcwd_();     
00782    if (old_cwd == NULL_STR) 
00783    {
00784       err_mesg(ERR_LEV_SPAM, 
00785          "IOManager::split_filename() - *WARNING* Couldn't save old current working directory!!");
00786    }
00787 
00788    //Grab char version of the fullpath str_ptr
00789    const char *c_fullpath = **fullpath;
00790 
00791    //Make room for the 3 strings
00792    char *c_path = new char[strlen(c_fullpath)+2]; assert(c_path);
00793    char *c_file = new char[strlen(c_fullpath)+2]; assert(c_file);
00794    char *c_ext  = new char[strlen(c_fullpath)+2]; assert(c_ext);
00795 
00796 
00797    //
00798    //First, grab the path part...
00799    strcpy(c_path,c_fullpath);
00800 
00801    //Find the last occurance of fwd or rev slash
00802    char *c_path_slash = max( strrchr(c_path,'/'), strrchr(c_path,'\\') );
00803 
00804    //No slash = no path ... Use CWD
00805    if (!c_path_slash)
00806    {
00807       strcpy(c_path,".");
00808    }
00809    //Terminate string after slash
00810    else 
00811    {
00812       ++c_path_slash;
00813       *c_path_slash = '\0';
00814    }
00815 
00816 
00817 
00818    //
00819    //Then, strip out the path part...
00820 
00821    //Find the last occurance of fwd or rev slash
00822    //VC 8 /*has*/ HAD a problem with this line 
00823    //there has been some changes to the standard library by Microsoft
00824    //strrchr(const char*, const char*) returns a const char* 
00825    //and is no longer possible to cast into char *
00826   
00827    const char *c_fullpath_slash = max( strrchr(c_fullpath,'/'), strrchr(c_fullpath,'\\') );
00828 
00829    //If found, copy everthying after the slash
00830    if (c_fullpath_slash)
00831    {
00832       ++c_fullpath_slash;
00833       strcpy(c_file, c_fullpath_slash);
00834    }
00835    //Else copy everything
00836    else
00837    {
00838       strcpy(c_file, c_fullpath);
00839    }
00840 
00841 
00842    //
00843    //Finally, deal with the extension
00844 
00845    char *c_file_dot = strrchr(c_file,'.');
00846 
00847    //Non-leading '.' starts extension...
00848    if (c_file_dot && (c_file_dot != c_file))
00849    {
00850       //Copy extension including leading '.'
00851       strcpy(c_ext, c_file_dot);
00852 
00853       //And lop it off of the file name
00854       *c_file_dot = '\0';
00855    }
00856    //Otherwise there's no extension...
00857    else
00858    {
00859       strcpy(c_ext,"");
00860    }
00861 
00862 
00863    //
00864    //Now turn the given path into an absolute, verified path...
00865 
00866    if (chdir_(c_path) && ((path = getcwd_()) != NULL_STR) )
00867    {
00868       //Success!
00869 
00870       //Copy the file and extension into return vars...
00871       file = str_ptr(c_file);
00872       ext  = str_ptr(c_ext);
00873 
00874       result = true;
00875    }
00876    else
00877    {
00878       //Failed to turn given path into real absolute path...
00879 
00880       result = false;
00881    }
00882 
00883    if ((old_cwd == NULL_STR) || !chdir_(old_cwd) )
00884    {
00885       err_mesg(ERR_LEV_SPAM, 
00886          "IOManager::split_filename() - *WARNING* Couldn't restore old current working directory!!");
00887    }
00888 
00889    delete[] c_path;
00890    delete[] c_file;
00891    delete[] c_ext;
00892 
00893    return result;
00894 }

Generated on Mon Sep 18 11:39:31 2006 for jot by  doxygen 1.4.4