// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// Copyright 2003 Liam Girdwood
#include "config.h"
#include "import.hh"
#include "astro_object.hh"
#include "deep_object.hh"
#include "star_object.hh"
#include "skymap_object.hh"
#include "comet.hh"
#include "galaxy.hh"
#include "nebula.hh"
#include "asteroid.hh"
#include <string>
#include <iostream>
#include <fstream>
namespace Pollux
{
/*! \fn Import::Import()
*
* Constructor. Set up default import paths.
*/
Import::Import()
{
m_path = NOVA_CATALOG_DIR;
m_path += "/";
m_name = "";
}
/*! \fn Import::~Import()
*
* Destructor. Clear the import table.
*/
Import::~Import()
{
m_import_table.clear();
}
/*! \fn void Import::set_name (std::string& name)
*
* Set the name of the catalog to import.
*/
void Import::set_name (std::string& name)
{
m_name = name;
}
/*! \fn void Import::set_path (std::string& path)
*
* Set the path to the ASCII catalog
*/
void Import::set_path (std::string& path)
{
m_path = path;
}
/*! \fn bool Import::parse_descriptor ()
* \return true if the descriptor was parsed successfully.
*
* Parse the XML catalog descriptor and build up an internal
* map of catalog data elements.
*/
bool Import::parse_descriptor ()
{
Glib::ustring filename = m_path + m_name + ".xml";
try {
xmlpp::DomParser parser;
parser.set_validate();
parser.set_substitute_entities();
parser.parse_file(filename);
if(parser) {
const xmlpp::Node* pNode = parser.get_document()->get_root_node();
parse_node(pNode);
}
}
catch(const std::exception& ex) {
std::cerr << "Exception caught: " << ex.what() << std::endl;
return false;
}
if (!build_import_table ()) {
std::cerr << "could not parse descriptor " << std::endl;
return false;
}
return true;
}
void Import::parse_node(const xmlpp::Node* node)
{
const xmlpp::ContentNode* nodeContent = dynamic_cast<const xmlpp::ContentNode*>(node);
const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
const xmlpp::CommentNode* nodeComment = dynamic_cast<const xmlpp::CommentNode*>(node);
const xmlpp::Attribute* attribute;
if(nodeText && nodeText->is_white_space())
return;
std::string nodename = node->get_name();
if(const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node)) {
attribute = nodeElement->get_attribute("RA");
if(attribute) {
//m_centre_ra = atof(attribute->get_value().c_str());
}
attribute = nodeElement->get_attribute("DEC");
if(attribute) {
//m_centre_dec = atof(attribute->get_value().c_str());
}
}
if(!nodeContent) {
//Recurse through child nodes:
xmlpp::Node::NodeList list = node->get_children();
for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter) {
parse_node(*iter); //recursive
}
}
}
/*! \fn Catalog* Import::import_catalog ()
* \return Returns a pointer to a catalog object on success,
* otherwise returns 0.
*
* Imports a catalogs ASCII data files into a binary representation.
*/
Catalog* Import::import_catalog ()
{
std::ifstream* file;
std::string file_name;
char c, line[MAX_LINE_SIZE];
m_first_pass = true;
// is the catalog descriptor valid
if (!parse_descriptor()) {
std::cerr << "could not parse catalog descriptor" << std::endl;
return 0;
}
// create the catalog
Catalog* catalog = new Catalog(m_name, m_description, m_maintainer,
m_type_str, m_created, m_version, m_history,
m_acknowledge);
if (!catalog) {
std::cerr << "could not create catalog" << std::endl;
return 0;
}
// iterate through files
for (std::list<std::string*>::iterator j = m_files.begin(); j != m_files.end(); j++) {
// try and open catalog file
file_name = m_path + "/" + **j;
std::cout << "opening " << file_name << std::endl;
file = new std::ifstream(file_name.c_str());
if (file->is_open()) {
// ok file is open, read it
while(!(file->eof ())) {
// read 1 line of the file
file->getline(line, 1024, '\n');
// process line and create object
if (!create_object (catalog, line)) {
// cant create object, keep trying
std::cerr << __FILE__ << " cat create object " << std::endl;
}
}
} else {
// cant open catalog file
std::cerr << "cant open catalog file " << std::endl;
file->close();
delete file;
delete catalog;
return 0;
}
file->close();
delete file;
}
return catalog;
}
/*! \fn Catalog* Import::import_catalog ()
* \return true on success.
*
* Builds a table mapping catalog elements to import data
*/
bool Import::build_import_table ()
{
bool success = false;
#if 0
// get cat info from the sax parser
parser->get_cat_description (m_description);
parser->get_cat_maintainer (m_maintainer);
parser->get_cat_type (m_type_str);
m_size = parser->get_cat_size ();
parser->get_cat_created (m_created);
parser->get_cat_history(m_history);
parser->get_cat_version(m_version);
parser->get_cat_acknowledge(m_acknowledge);
// set up catalog type
if (m_type_str == "skymap")
m_type = SKYMAP;
else if (m_type_str == "star")
m_type = STAR;
else if (m_type_str == "galaxy")
m_type = GALAXY;
else if (m_type_str == "nebula")
m_type = NEBULA;
else if (m_type_str == "asteroid")
m_type = ASTEROID;
else if (m_type_str == "comet")
m_type = COMET;
// get cat file list
if (!(parser->get_file_list(m_files)))
return false;
// get elements from the sax parser
int lowest = -1;
Element* element = parser->get_next_element(lowest);
while (element) {
success = true;
// create new item
import_item* item = new import_item;
// item start position
item->pos = element->position;
// item length
item->len = strtol(element->type.c_str()+1, 0, 10);
// item type
switch (element->type[0]) {
case 'I':
item->type = Castor::AstroObject::INT;
break;
case 'F':
item->type = Castor::AstroObject::DOUBLE;
break;
case 'A':
item->type = Castor::AstroObject::STRING;
break;
default:
item->type = Castor::AstroObject::STRING;
break;
}
// build remainder of item
item->name = element->name;
item->units = element->units;
item->desc = element->description;
item->extra = false;
m_import_table.push_back (item);
// next element ?
lowest = item->pos;
element = parser->get_next_element(lowest);
}
#endif
return success;
}
/*! \fn bool Import::create_object (Catalog* catalog, const char * line)
* \return True on success
*
* Creates the appropraite catalog objects.
*/
bool Import::create_object (Catalog* catalog, const char * line)
{
Castor::AstroObject* object;
switch (m_type) {
case STAR:
object = new Castor::StarObject();
break;
case SKYMAP:
object = new Castor::SkymapObject();
break;
case DEEP_OTHER:
object = new Castor::DeepObject();
break;
case NEBULA:
object = new Castor::Nebula();
break;
case ASTEROID:
object = new Castor::Asteroid();
break;
case COMET:
object = new Castor::Comet();
break;
case GALAXY:
object = new Castor::Galaxy();
break;
}
// add extra element descriptors
if (m_first_pass) {
for (std::list<import_item*>::iterator j = m_import_table.begin(); j != m_import_table.end(); j++) {
if (!(object->check_element((*j)->name))) {
catalog->add_description ((*j)->name, (*j)->units, (*j)->desc);
(*j)->extra = true;
}
}
}
m_first_pass = false;
// iterate through items
for (std::list<import_item*>::iterator j = m_import_table.begin(); j != m_import_table.end(); j++) {
std::string val;
// if item is non blank the add, else if blank and extra also add it
if (get_element (*j, val, line))
object->add_element ((*j)->name, (*j)->type, val);
else
if ((*j)->extra)
object->add_element ((*j)->name, (*j)->type, val);
}
// add object
catalog->add(object);
return true;
}
/*! \fn int Import::scan(std::list<std::string*>& names,
std::list<std::string*>& description)
* \param names A list of catalog names found
* \param description A list of catalog descriptions found
* \return Number of catalogs found
* \todo implement catalog scan
*
* Scan the filesystem catalog dir for Nova catalogs
*/
int Import::scan(std::list<std::string*>& names,
std::list<std::string*>& description)
{
}
/*! \fn bool Import::get_element (import_item* item, std::string& value, const char* line)
* \return True on success
*
* Extracts an individual ASCII data element out of the catalog.
*/
bool Import::get_element (import_item* item, std::string& value, const char* line)
{
int i, pos;
char buffer[256];
pos = item->pos -1;
for (i = 0; i < item->len; i++) {
if (!(isspace(*(line + pos + i)))) {
strncpy (buffer, line + pos, item->len);
buffer[item->len] = 0;
value = buffer;
return true;
}
}
return false;
}
}
syntax highlighted by Code2HTML, v. 0.9.1