diff --git a/src/Airports/Makefile.am b/src/Airports/Makefile.am index 63eecbb33..e3a205af9 100644 --- a/src/Airports/Makefile.am +++ b/src/Airports/Makefile.am @@ -1,7 +1,13 @@ noinst_LIBRARIES = libAirports.a +noinst_PROGRAMS = buildsimple + libAirports_a_SOURCES = \ genapt.cxx genapt.hxx \ simple.cxx simple.hxx +buildsimple_SOURCES = buildsimple.cxx + +buildsimple_LDADD = libAirports.a -lsgdebug -lsgmisc -lgdbm -lz + INCLUDES += -I$(top_builddir) -I$(top_builddir)/src diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index 7b4442166..2cafe0242 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -24,10 +24,13 @@ // $Id$ +#include // for gdbm open flags +#include // for gdbm open flags +#include + #include #include -#include #include #include
@@ -39,32 +42,99 @@ #include "simple.hxx" -fgAIRPORTS::fgAIRPORTS() { +FGAirports::FGAirports( const string& file ) { + dbf = gdbm_open( (char *)file.c_str(), 0, GDBM_READER, 0, NULL ); + if ( dbf == NULL ) { + cout << "Error opening " << file << endl; + exit(-1); + } else { + cout << "successfully opened " << file << endl; + } +} + + +// search for the specified id +bool +FGAirports::search( const string& id, FGAirport* a ) const +{ + FGAirport *tmp; + datum content; + datum key; + + key.dptr = (char *)id.c_str(); + key.dsize = id.length(); + + content = gdbm_fetch( dbf, key ); + + cout << "gdbm_fetch() finished" << endl; + + if ( content.dptr != NULL ) { + tmp = (FGAirport *)content.dptr; + + // a->id = tmp->id; + a->longitude = tmp->longitude; + a->latitude = tmp->latitude; + a->elevation = tmp->elevation; + + free( content.dptr ); + + } else { + return false; + } + + return true; +} + + +FGAirport +FGAirports::search( const string& id ) const +{ + FGAirport a, *tmp; + datum content; + datum key; + + key.dptr = (char *)id.c_str(); + key.dsize = id.length(); + + content = gdbm_fetch( dbf, key ); + + if ( content.dptr != NULL ) { + tmp = (FGAirport *)content.dptr; + a = *tmp; + } + + return a; +} + + +// Destructor +FGAirports::~FGAirports( void ) { + gdbm_close( dbf ); +} + + +// Constructor +FGAirportsUtil::FGAirportsUtil() { } // load the data -int fgAIRPORTS::load( const string& file ) { - fgAIRPORT a; - - // build the path name to the airport file - FGPath path( current_options.get_fg_root() ); - path.append( "Airports" ); - path.append( file ); +int FGAirportsUtil::load( const string& file ) { + FGAirport a; airports.erase( airports.begin(), airports.end() ); - fg_gzifstream in( path.str() ); + fg_gzifstream in( file ); if ( !in.is_open() ) { - FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << path.str() ); + FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << file ); exit(-1); } /* // We can use the STL copy algorithm because the input // file doesn't contain and comments or blank lines. - copy( istream_iterator(in.stream()), - istream_iterator(), + copy( istream_iterator(in.stream()), + istream_iterator(), inserter( airports, airports.begin() ) ); */ @@ -96,11 +166,48 @@ int fgAIRPORTS::load( const string& file ) { } +// save the data in gdbm format +bool FGAirportsUtil::dump_gdbm( const string& file ) { + + GDBM_FILE dbf; + dbf = gdbm_open( (char *)file.c_str(), 0, GDBM_NEWDB | GDBM_FAST, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, + NULL ); + if ( dbf == NULL ) { + cout << "Error opening " << file << endl; + exit(-1); + } else { + cout << "successfully opened " << file << endl; + } + + iterator current = airports.begin(); + const_iterator end = airports.end(); + while ( current != end ) { + datum key; + key.dptr = (char *)current->id.c_str(); + key.dsize = current->id.length(); + + datum content; + FGAirport tmp = *current; + content.dptr = (char *)(& tmp); + content.dsize = sizeof( *current ); + + gdbm_store( dbf, key, content, GDBM_REPLACE ); + + ++current; + } + + gdbm_close( dbf ); + + return true; +} + + // search for the specified id bool -fgAIRPORTS::search( const string& id, fgAIRPORT* a ) const +FGAirportsUtil::search( const string& id, FGAirport* a ) const { - const_iterator it = airports.find( fgAIRPORT(id) ); + const_iterator it = airports.find( FGAirport(id) ); if ( it != airports.end() ) { *a = *it; @@ -113,17 +220,17 @@ fgAIRPORTS::search( const string& id, fgAIRPORT* a ) const } -fgAIRPORT -fgAIRPORTS::search( const string& id ) const +FGAirport +FGAirportsUtil::search( const string& id ) const { - fgAIRPORT a; + FGAirport a; this->search( id, &a ); return a; } // Destructor -fgAIRPORTS::~fgAIRPORTS( void ) { +FGAirportsUtil::~FGAirportsUtil( void ) { } diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index 92f872d23..e8f513697 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -1,4 +1,3 @@ -// // simple.hxx -- a really simplistic class to manage airport ID, // lat, lon of the center of one of it's runways, and // elevation in feet. @@ -33,6 +32,8 @@ #endif +#include + #include #ifdef FG_HAVE_STD_INCLUDES @@ -56,37 +57,65 @@ FG_USING_STD(istream); #endif -class fgAIRPORT { +class FGAirport { + public: - fgAIRPORT( const string& name = "", + + FGAirport( const string& name = "", double lon = 0.0, double lat = 0.0, double ele = 0.0 ) : id(name), longitude(lon), latitude(lat), elevation(ele) {} - bool operator < ( const fgAIRPORT& a ) const { + bool operator < ( const FGAirport& a ) const { return id < a.id; } public: + string id; double longitude; double latitude; double elevation; + }; inline istream& -operator >> ( istream& in, fgAIRPORT& a ) +operator >> ( istream& in, FGAirport& a ) { return in >> a.id >> a.longitude >> a.latitude >> a.elevation; } -class fgAIRPORTS { + +class FGAirports { + +private: + + GDBM_FILE dbf; + +public: + + // Constructor + FGAirports( const string& file ); + + // Destructor + ~FGAirports(); + + // search for the specified id. + // Returns true if successful, otherwise returns false. + // On success, airport data is returned thru "airport" pointer. + // "airport" is not changed if "id" is not found. + bool search( const string& id, FGAirport* airport ) const; + FGAirport search( const string& id ) const; +}; + + +class FGAirportsUtil { public: #ifdef FG_NO_DEFAULT_TEMPLATE_ARGS - typedef set< fgAIRPORT, less< fgAIRPORT > > container; + typedef set< FGAirport, less< FGAirport > > container; #else - typedef set< fgAIRPORT > container; + typedef set< FGAirport > container; #endif typedef container::iterator iterator; typedef container::const_iterator const_iterator; @@ -97,20 +126,23 @@ private: public: // Constructor - fgAIRPORTS(); + FGAirportsUtil(); // Destructor - ~fgAIRPORTS(); + ~FGAirportsUtil(); // load the data int load( const string& file ); + // save the data in gdbm format + bool dump_gdbm( const string& file ); + // search for the specified id. // Returns true if successful, otherwise returns false. // On success, airport data is returned thru "airport" pointer. // "airport" is not changed if "id" is not found. - bool search( const string& id, fgAIRPORT* airport ) const; - fgAIRPORT search( const string& id ) const; + bool search( const string& id, FGAirport* airport ) const; + FGAirport search( const string& id ) const; }; diff --git a/src/Autopilot/autopilot.cxx b/src/Autopilot/autopilot.cxx index b7b201f5c..4d473ef2f 100644 --- a/src/Autopilot/autopilot.cxx +++ b/src/Autopilot/autopilot.cxx @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -919,14 +920,16 @@ void TgtAptDialog_OK (puObject *) if ( TgtAptId.length() ) { // set initial position from TgtAirport id - fgAIRPORTS airports; - fgAIRPORT a; + FGPath path( current_options.get_fg_root() ); + path.append( "Airports" ); + path.append( "simple.gdbm" ); + FGAirports airports( path.c_str() ); + FGAirport a; FG_LOG( FG_GENERAL, FG_INFO, "Attempting to set starting position from airport code " << s ); - airports.load("apt_simple"); if ( airports.search( TgtAptId, &a ) ) { double course, reverse, distance; diff --git a/src/GUI/gui.cxx b/src/GUI/gui.cxx index 7a8a71b94..86ffd3891 100644 --- a/src/GUI/gui.cxx +++ b/src/GUI/gui.cxx @@ -996,8 +996,11 @@ void AptDialog_Cancel(puObject *) void AptDialog_OK (puObject *) { - fgAIRPORTS airports; - fgAIRPORT a; + FGPath path( current_options.get_fg_root() ); + path.append( "Airports" ); + path.append( "simple.gdbm" ); + FGAirports airports( path.c_str() ); + FGAirport a; FGTime *t = FGTime::cur_time_params; int PauseMode = t->getPause(); @@ -1018,7 +1021,6 @@ void AptDialog_OK (puObject *) "Attempting to set starting position from airport code " << AptId ); - airports.load("apt_simple"); if ( airports.search( AptId, &a ) ) { current_options.set_airport_id( AptId.c_str() ); diff --git a/src/Main/Makefile.am b/src/Main/Makefile.am index 944092c7d..43a0e60a8 100644 --- a/src/Main/Makefile.am +++ b/src/Main/Makefile.am @@ -68,7 +68,7 @@ fgfs_LDADD = \ $(SERIAL_LIBS) \ -lsgscreen -lsgmath -lsgbucket -lsgdebug -lsgmagvar -lsgmisc \ -lplibpu -lplibfnt -lplibssg -lplibsg \ - -lz \ + -lgdbm -lz \ $(opengl_LIBS) \ $(audio_LIBS) diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 2aa39bb4e..66920fc4b 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -137,14 +137,26 @@ bool fgInitPosition( void ) { if ( id.length() ) { // set initial position from airport id - fgAIRPORTS airports; - fgAIRPORT a; + FGPath path( current_options.get_fg_root() ); + path.append( "Airports" ); + path.append( "simple.gdbm" ); + FGAirports airports( path.c_str() ); + FGAirport a; FG_LOG( FG_GENERAL, FG_INFO, "Attempting to set starting position from airport code " << id ); - airports.load("apt_simple"); + // FGPath inpath( current_options.get_fg_root() ); + // inpath.append( "Airports" ); + // inpath.append( "apt_simple" ); + // airports.load( inpath.c_str() ); + + // FGPath outpath( current_options.get_fg_root() ); + // outpath.append( "Airports" ); + // outpath.append( "simple.gdbm" ); + // airports.dump_gdbm( outpath.c_str() ); + if ( ! airports.search( id, &a ) ) { FG_LOG( FG_GENERAL, FG_ALERT, "Failed to find " << id << " in database." );