// 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 #include #include 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(node); const xmlpp::TextNode* nodeText = dynamic_cast(node); const xmlpp::CommentNode* nodeComment = dynamic_cast(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(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::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::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::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& names, std::list& 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& names, std::list& 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; } }