//
// $Id$
-
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
-#include <sys/types.h> // for gdbm open flags
-#include <sys/stat.h> // for gdbm open flags
-
-#ifdef HAVE_GDBM
-# include <gdbm.h>
-#else
-# include <simgear/gdbm/gdbm.h>
-#endif
-
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/fgstream.hxx>
-
-#include <Main/options.hxx>
+#include <simgear/misc/sgstream.hxx>
#include STL_STRING
#include STL_FUNCTIONAL
#include "simple.hxx"
+SG_USING_NAMESPACE(std);
+
+#ifndef _MSC_VER
+# define NDEBUG // she don't work without it.
+#endif
+#include <mk4.h>
+#include <mk4str.h>
+#ifndef _MSC_VER
+# undef NDEBUG
+#endif
+
+#ifdef SG_HAVE_STD_INCLUDES
+# include <istream>
+#elif defined( __BORLANDC__ ) || defined (__APPLE__)
+# include <iostream>
+#else
+# include <istream.h>
+#endif
+SG_USING_STD(istream);
+
+
+inline istream&
+operator >> ( istream& in, FGAirport& a )
+{
+ return in >> a.id >> a.latitude >> a.longitude >> a.elevation;
+}
+
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;
+ // open the specified database readonly
+ storage = new c4_Storage( file.c_str(), false );
+
+ if ( !storage->Strategy().IsValid() ) {
+ SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
exit(-1);
- } else {
- cout << "successfully opened " << file << endl;
}
+
+ vAirport = new c4_View;
+ *vAirport =
+ storage->GetAs("airport[ID:S,Longitude:F,Latitude:F,Elevation:F]");
}
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 );
+ c4_StringProp pID ("ID");
+ c4_FloatProp pLon ("Longitude");
+ c4_FloatProp pLat ("Latitude");
+ c4_FloatProp pElev ("Elevation");
- cout << "gdbm_fetch() finished" << endl;
+ int idx = vAirport->Find(pID[id.c_str()]);
+ SG_LOG( SG_TERRAIN, SG_INFO, "idx = " << idx );
- 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 {
+ if ( idx == -1 ) {
return false;
}
+ c4_RowRef r = vAirport->GetAt(idx);
+ a->id = (const char *) pID(r); /// NHV fix wrong case crash
+ a->longitude = (double) pLon(r);
+ a->latitude = (double) pLat(r);
+ a->elevation = (double) pElev(r);
+
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;
- }
-
+ FGAirport a;
+ search( id, &a );
return a;
}
// Destructor
FGAirports::~FGAirports( void ) {
- gdbm_close( dbf );
+ delete storage;
}
airports.erase( airports.begin(), airports.end() );
- fg_gzifstream in( file );
+ sg_gzifstream in( file );
if ( !in.is_open() ) {
- FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << file );
+ SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
exit(-1);
+ } else {
+ SG_LOG( SG_GENERAL, SG_ALERT, "opened: " << file );
}
- /*
- // We can use the STL copy algorithm because the input
- // file doesn't contain and comments or blank lines.
- copy( istream_iterator<FGAirport,ptrdiff_t>(in.stream()),
- istream_iterator<FGAirport,ptrdiff_t>(),
- inserter( airports, airports.begin() ) );
- */
+ // skip first line of file
+ char tmp[2048];
+ in.getline( tmp, 2048 );
// read in each line of the file
#ifdef __MWERKS__
- in >> skipcomment;
+ in >> ::skipws;
char c = 0;
while ( in.get(c) && c != '\0' ) {
- in.putback(c);
- in >> a;
- airports.insert(a);
- in >> skipcomment;
+ if ( c == 'A' ) {
+ in >> a;
+ SG_LOG( SG_GENERAL, SG_INFO, a.id );
+ in >> skipeol;
+ airports.insert(a);
+ } else if ( c == 'R' ) {
+ in >> skipeol;
+ } else {
+ in >> skipeol;
+ }
+ in >> ::skipws;
}
#else
- in >> skipcomment;
+ in >> ::skipws;
+ string token;
while ( ! in.eof() ) {
- in >> a;
- airports.insert(a);
- in >> skipcomment;
+ in >> token;
+ if ( token == "A" ) {
+ in >> a;
+ SG_LOG( SG_GENERAL, SG_INFO, "in <- " << a.id );
+ in >> skipeol;
+ airports.insert(a);
+ } else if ( token == "R" ) {
+ in >> skipeol;
+ } else {
+ in >> skipeol;
+ }
+ in >> ::skipws;
}
#endif
// save the data in gdbm format
-bool FGAirportsUtil::dump_gdbm( const string& file ) {
+bool FGAirportsUtil::dump_mk4( const string& file ) {
- GDBM_FILE dbf;
+ // open database for writing
+ c4_Storage storage( file.c_str(), true );
-#if !defined( MACOS )
- dbf = gdbm_open( (char *)file.c_str(), 0, GDBM_NEWDB | GDBM_FAST,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
- NULL );
-#else
- dbf = gdbm_open( (char *)file.c_str(), 0, GDBM_NEWDB | GDBM_FAST,
- NULL, NULL );
-#endif
+ // need to do something about error handling here!
- if ( dbf == NULL ) {
- cout << "Error opening " << file << endl;
- exit(-1);
- } else {
- cout << "successfully opened " << file << endl;
- }
+ // define the properties
+ c4_StringProp pID ("ID");
+ c4_FloatProp pLon ("Longitude");
+ c4_FloatProp pLat ("Latitude");
+ c4_FloatProp pElev ("Elevation");
- 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();
+ // Start with an empty view of the proper structure.
+ c4_View vAirport =
+ storage.GetAs("airport[ID:S,Longitude:F,Latitude:F,Elevation:F]");
- datum content;
- FGAirport tmp = *current;
- content.dptr = (char *)(& tmp);
- content.dsize = sizeof( *current );
+ c4_Row row;
- gdbm_store( dbf, key, content, GDBM_REPLACE );
+ const_iterator current = airports.begin();
+ const_iterator end = airports.end();
+ while ( current != end ) {
+ // add each airport record
+ SG_LOG( SG_TERRAIN, SG_BULK, "out -> " << current->id );
+ pID (row) = current->id.c_str();
+ pLon (row) = current->longitude;
+ pLat (row) = current->latitude;
+ pElev (row) = current->elevation;
+ vAirport.Add(row);
++current;
}
- gdbm_close( dbf );
+ // commit our changes
+ storage.Commit();
return true;
}