From 8ea77af9e738ca7a4064941b77cc9c0a098684af Mon Sep 17 00:00:00 2001 From: Markus Mohrhard Date: Sun, 9 Sep 2012 02:42:16 +0200 Subject: [PATCH 3/8] add files for gnumeric parser --- include/orcus/gnumeric/gnumeric_cell_context.hpp | 77 +++++++ include/orcus/gnumeric/gnumeric_context.hpp | 66 ++++++ include/orcus/gnumeric/gnumeric_handler.hpp | 70 +++++++ include/orcus/gnumeric/gnumeric_sheet_context.hpp | 71 +++++++ .../orcus/gnumeric/gnumeric_token_constants.hpp | 40 ++++ include/orcus/gnumeric/gnumeric_tokens.hpp | 42 ++++ include/orcus/orcus_gnumeric.hpp | 60 ++++++ src/liborcus/gnumeric_cell_context.cpp | 217 ++++++++++++++++++++ src/liborcus/gnumeric_context.cpp | 110 ++++++++++ src/liborcus/gnumeric_handler.cpp | 100 +++++++++ src/liborcus/gnumeric_sheet_context.cpp | 103 ++++++++++ src/liborcus/gnumeric_tokens.cpp | 40 ++++ src/liborcus/orcus_gnumeric.cpp | 108 ++++++++++ 13 files changed, 1104 insertions(+) create mode 100755 include/orcus/gnumeric/gnumeric_cell_context.hpp create mode 100755 include/orcus/gnumeric/gnumeric_context.hpp create mode 100755 include/orcus/gnumeric/gnumeric_handler.hpp create mode 100755 include/orcus/gnumeric/gnumeric_sheet_context.hpp create mode 100755 include/orcus/gnumeric/gnumeric_token_constants.hpp create mode 100755 include/orcus/gnumeric/gnumeric_tokens.hpp create mode 100755 include/orcus/orcus_gnumeric.hpp create mode 100755 src/liborcus/gnumeric_cell_context.cpp create mode 100755 src/liborcus/gnumeric_context.cpp create mode 100755 src/liborcus/gnumeric_handler.cpp create mode 100755 src/liborcus/gnumeric_sheet_context.cpp create mode 100755 src/liborcus/gnumeric_tokens.cpp create mode 100755 src/liborcus/orcus_gnumeric.cpp diff --git a/include/orcus/gnumeric/gnumeric_cell_context.hpp b/include/orcus/gnumeric/gnumeric_cell_context.hpp new file mode 100755 index 0000000..b60b370 --- /dev/null +++ b/include/orcus/gnumeric/gnumeric_cell_context.hpp @@ -0,0 +1,77 @@ +/************************************************************************* + * + * Copyright (c) 2010, 2011 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#ifndef __ORCUS_GNUMERIC_CELL_CONTEXT_HPP__ +#define __ORCUS_GNUMERIC_CELL_CONTEXT_HPP__ + +#include "orcus/xml_context.hpp" +#include + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; + +}} + +struct gnumeric_cell_data; + +class gnumeric_cell_context : public xml_context_base +{ +public: + gnumeric_cell_context(const tokens& tokens, spreadsheet::iface::import_factory* factory, spreadsheet::iface::import_sheet* sheet); + virtual ~gnumeric_cell_context(); + + virtual bool can_handle_element(xmlns_token_t ns, xml_token_t name) const; + virtual xml_context_base* create_child_context(xmlns_token_t ns, xml_token_t name) const; + virtual void end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs); + virtual bool end_element(xmlns_token_t ns, xml_token_t name); + virtual void characters(const pstring& str); + +private: + void start_cell(const xml_attrs_t& attrs); + void end_cell(); +private: + spreadsheet::iface::import_factory* mp_factory; + + boost::scoped_ptr mp_cell_data; + + /** + * Used for temporary storage of characters + */ + pstring chars; + + spreadsheet::iface::import_sheet* mp_sheet; +}; + +} // namespace orcus + +#endif diff --git a/include/orcus/gnumeric/gnumeric_context.hpp b/include/orcus/gnumeric/gnumeric_context.hpp new file mode 100755 index 0000000..a77f871 --- /dev/null +++ b/include/orcus/gnumeric/gnumeric_context.hpp @@ -0,0 +1,66 @@ +/************************************************************************* + * + * Copyright (c) 2010, 2011 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#ifndef __ORCUS_GNUMERICCONTEXT_HPP__ +#define __ORCUS_GNUMERICCONTEXT_HPP__ + +#include "orcus/xml_context.hpp" + +#include + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; + +}} + +class gnumeric_content_xml_context : public xml_context_base +{ +public: + gnumeric_content_xml_context(const tokens& tokens, spreadsheet::iface::import_factory* factory); + virtual ~gnumeric_content_xml_context(); + + virtual bool can_handle_element(xmlns_token_t ns, xml_token_t name) const; + virtual xml_context_base* create_child_context(xmlns_token_t ns, xml_token_t name) const; + virtual void end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs); + virtual bool end_element(xmlns_token_t ns, xml_token_t name); + virtual void characters(const pstring& str); + +private: + +private: + spreadsheet::iface::import_factory* mp_factory; +}; + +} + +#endif diff --git a/include/orcus/gnumeric/gnumeric_handler.hpp b/include/orcus/gnumeric/gnumeric_handler.hpp new file mode 100755 index 0000000..4afe761 --- /dev/null +++ b/include/orcus/gnumeric/gnumeric_handler.hpp @@ -0,0 +1,70 @@ +/************************************************************************* + * + * Copyright (c) 2010, 2011 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#ifndef __ORCUS_GNUMERICHANDLER_HPP__ +#define __ORCUS_GNUMERICHANDLER_HPP__ + +#include "orcus/xml_handler.hpp" +#include "orcus/xml_context.hpp" + +#include +#include + +namespace orcus { + +class tokens; +class gnumeric_content_xml_context; + +namespace spreadsheet { namespace iface { class import_factory; }} + +/** + * Handler for parsing the content.xml part. + */ +class gnumeric_content_xml_handler : public xml_stream_handler +{ +public: + gnumeric_content_xml_handler(const tokens& tokens, spreadsheet::iface::import_factory* factory); + virtual ~gnumeric_content_xml_handler(); + + virtual void start_document(); + virtual void end_document(); + virtual void start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs); + virtual void end_element(xmlns_token_t ns, xml_token_t name); + virtual void characters(const pstring& str); + +private: + xml_context_base& get_current_context(); + +private: + spreadsheet::iface::import_factory* mp_factory; + typedef ::boost::ptr_vector context_stack_type; + context_stack_type m_context_stack; +}; + +} + +#endif diff --git a/include/orcus/gnumeric/gnumeric_sheet_context.hpp b/include/orcus/gnumeric/gnumeric_sheet_context.hpp new file mode 100755 index 0000000..dd37260 --- /dev/null +++ b/include/orcus/gnumeric/gnumeric_sheet_context.hpp @@ -0,0 +1,71 @@ +/************************************************************************* + * + * Copyright (c) 2010, 2011 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#ifndef __ORCUS_GNUMERIC_SHEET_CONTEXT_HPP__ +#define __ORCUS_GNUMERIC_SHEET_CONTEXT_HPP__ + +#include "orcus/xml_context.hpp" + +namespace orcus { + +namespace spreadsheet { namespace iface { + +class import_factory; +class import_sheet; + +}} + +class gnumeric_sheet_context : public xml_context_base +{ +public: + gnumeric_sheet_context(const tokens& tokens, spreadsheet::iface::import_factory* factory); + virtual ~gnumeric_sheet_context(); + + virtual bool can_handle_element(xmlns_token_t ns, xml_token_t name) const; + virtual xml_context_base* create_child_context(xmlns_token_t ns, xml_token_t name) const; + virtual void end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child); + + virtual void start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs); + virtual bool end_element(xmlns_token_t ns, xml_token_t name); + virtual void characters(const pstring& str); + +private: + void end_table(); +private: + spreadsheet::iface::import_factory* mp_factory; + + spreadsheet::iface::import_sheet* mp_sheet; + + /** + * Used for temporary storage of characters + */ + pstring chars; +}; + +} // namespace orcus + +#endif diff --git a/include/orcus/gnumeric/gnumeric_token_constants.hpp b/include/orcus/gnumeric/gnumeric_token_constants.hpp new file mode 100755 index 0000000..042e1d3 --- /dev/null +++ b/include/orcus/gnumeric/gnumeric_token_constants.hpp @@ -0,0 +1,40 @@ +/************************************************************************* + * + * Copyright (c) 2010 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#ifndef __ORCUS_GNUMERIC_TOKEN_CONSTANTS_HPP__ +#define __ORCUS_GNUMERIC_TOKEN_CONSTANTS_HPP__ + +#include "orcus/types.hpp" + +namespace orcus { + +#include "gnumeric_token_constants.inl" + +} + + +#endif diff --git a/include/orcus/gnumeric/gnumeric_tokens.hpp b/include/orcus/gnumeric/gnumeric_tokens.hpp new file mode 100755 index 0000000..8efe67c --- /dev/null +++ b/include/orcus/gnumeric/gnumeric_tokens.hpp @@ -0,0 +1,42 @@ +/************************************************************************* + * + * Copyright (c) 2010 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#ifndef __ORCUS_GNUMERIC_TOKENS_HPP__ +#define __ORCUS_GNUMERIC_TOKENS_HPP__ + +#include "orcus/tokens.hpp" + +namespace orcus { + +/** + * Singleton instance containing all GNUMERIC tokens. + */ +extern tokens gnumeric_tokens; + +} + +#endif diff --git a/include/orcus/orcus_gnumeric.hpp b/include/orcus/orcus_gnumeric.hpp new file mode 100755 index 0000000..1ce5be9 --- /dev/null +++ b/include/orcus/orcus_gnumeric.hpp @@ -0,0 +1,60 @@ +/************************************************************************* + * + * Copyright (c) 2011-2012 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#ifndef __ORCUS_ORCUS_GNUMERIC_HPP__ +#define __ORCUS_ORCUS_GNUMERIC_HPP__ + +#include "orcus/spreadsheet/import_interface.hpp" +#include "orcus/env.hpp" + +#include + +struct zip; + +namespace orcus { + +namespace spreadsheet { namespace iface { class import_factory; }} + +class ORCUS_DLLPUBLIC orcus_gnumeric +{ + orcus_gnumeric(const orcus_gnumeric&); // disabled +public: + orcus_gnumeric(spreadsheet::iface::import_factory* factory); + ~orcus_gnumeric(); + + void read_file(const char* fpath); + +private: + void read_content_xml(const char* p, size_t size); + +private: + spreadsheet::iface::import_factory* mp_factory; +}; + +} + +#endif diff --git a/src/liborcus/gnumeric_cell_context.cpp b/src/liborcus/gnumeric_cell_context.cpp new file mode 100755 index 0000000..74b3226 --- /dev/null +++ b/src/liborcus/gnumeric_cell_context.cpp @@ -0,0 +1,217 @@ +/************************************************************************* + * + * Copyright (c) 2010, 2011 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#include "orcus/gnumeric/gnumeric_context.hpp" +#include "orcus/gnumeric/gnumeric_token_constants.hpp" +#include "orcus/gnumeric/gnumeric_cell_context.hpp" +#include "orcus/global.hpp" +#include "orcus/spreadsheet/import_interface.hpp" + +#include +#include +#include + +using namespace std; + +namespace orcus { + +using namespace spreadsheet; + +enum gnumeric_cell_type + { + CellTypeBool, + CellTypeValue, + CellTypeString, + CellTypeFormula, + CellTypeSharedFormula, + CellTypeUnknown + }; + + +struct gnumeric_cell_data +{ + row_t row; + col_t col; + gnumeric_cell_type cell_type; + size_t shared_formula_id; +}; + +namespace { + + class cell_attr_parser : public unary_function + { + public: + cell_attr_parser() + { + cell_data.cell_type = CellTypeFormula; + cell_data.shared_formula_id = -1; + } + + cell_attr_parser(const cell_attr_parser& r): + cell_data(r.cell_data) {} + + void operator() (const xml_attr_t& attr) + { + + switch(attr.name) + { + case XML_Row: + cell_data.row = atoi(attr.value.get()); + break; + case XML_Col: + cell_data.col = atoi(attr.value.get()); + break; + case XML_ValueType: + { + int value_type = atoi(attr.value.get()); + switch(value_type) + { + case 20: + cell_data.cell_type = CellTypeBool; + break; + case 30: + case 40: + cell_data.cell_type = CellTypeValue; + break; + case 60: + cell_data.cell_type = CellTypeString; + } + } + break; + case XML_ExprID: + cell_data.shared_formula_id = atoi(attr.value.get()); + cell_data.cell_type = CellTypeSharedFormula; + break; + } + + } + + gnumeric_cell_data get_cell_data() const + { + return cell_data; + } + + private: + gnumeric_cell_data cell_data; + }; + +} + +// ============================================================================ + +gnumeric_cell_context::gnumeric_cell_context(const tokens& tokens, spreadsheet::iface::import_factory* factory, spreadsheet::iface::import_sheet* sheet) : + xml_context_base(tokens), + mp_factory(factory), + mp_sheet(sheet) +{ +} + +gnumeric_cell_context::~gnumeric_cell_context() +{ +} + +bool gnumeric_cell_context::can_handle_element(xmlns_token_t ns, xml_token_t name) const +{ + return true; +} + +xml_context_base* gnumeric_cell_context::create_child_context(xmlns_token_t ns, xml_token_t name) const +{ + return NULL; +} + +void gnumeric_cell_context::end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child) +{ +} + +void gnumeric_cell_context::start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs) +{ + push_stack(ns, name); + + if (ns == XMLNS_gnm) + { + switch (name) + { + case XML_Cell: + start_cell(attrs); + break; + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool gnumeric_cell_context::end_element(xmlns_token_t ns, xml_token_t name) +{ + if(ns == XMLNS_gnm) + { + switch(name) + { + case XML_Cell: + end_cell(); + break; + default: + break; + } + } + return pop_stack(ns, name); +} + +void gnumeric_cell_context::characters(const pstring& str) +{ + chars = str; +} + +void gnumeric_cell_context::start_cell(const xml_attrs_t& attrs) +{ + mp_cell_data.reset(new gnumeric_cell_data); + cell_attr_parser parser = for_each(attrs.begin(), attrs.end(), cell_attr_parser()); + *mp_cell_data = parser.get_cell_data(); +} + +void gnumeric_cell_context::end_cell() +{ + if(!mp_cell_data) + return; + + col_t col = mp_cell_data->col; + row_t row = mp_cell_data->row; + gnumeric_cell_type cell_type = mp_cell_data->cell_type; + switch(cell_type) + { + case CellTypeValue: + case CellTypeString: + mp_sheet->set_auto(row, col, chars.get(), chars.size()); + break; + } + + mp_cell_data.reset(); +} + +} diff --git a/src/liborcus/gnumeric_context.cpp b/src/liborcus/gnumeric_context.cpp new file mode 100755 index 0000000..8943ed7 --- /dev/null +++ b/src/liborcus/gnumeric_context.cpp @@ -0,0 +1,110 @@ +/************************************************************************* + * + * Copyright (c) 2010, 2011 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#include "orcus/gnumeric/gnumeric_context.hpp" +#include "orcus/gnumeric/gnumeric_token_constants.hpp" +#include "orcus/gnumeric/gnumeric_sheet_context.hpp" +#include "orcus/global.hpp" +#include "orcus/spreadsheet/import_interface.hpp" + +#include +#include +#include + +using namespace std; + +namespace orcus { + +namespace { + +} + +// ============================================================================ + +gnumeric_content_xml_context::gnumeric_content_xml_context(const tokens& tokens, spreadsheet::iface::import_factory* factory) : + xml_context_base(tokens), + mp_factory(factory) +{ +} + +gnumeric_content_xml_context::~gnumeric_content_xml_context() +{ +} + +bool gnumeric_content_xml_context::can_handle_element(xmlns_token_t ns, xml_token_t name) const +{ + if(ns == XMLNS_gnm && name == XML_Sheet) + return false; + + return true; +} + +xml_context_base* gnumeric_content_xml_context::create_child_context(xmlns_token_t ns, xml_token_t name) const +{ + if(ns == XMLNS_gnm && name == XML_Sheet) + return new gnumeric_sheet_context(get_tokens(), mp_factory); + + return NULL; +} + +void gnumeric_content_xml_context::end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child) +{ +} + +void gnumeric_content_xml_context::start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs) +{ + xml_token_pair_t parent = push_stack(ns, name); + + if (ns == XMLNS_gnm) + { + switch (name) + { + default: + warn_unhandled(); + } + } + else + warn_unhandled(); +} + +bool gnumeric_content_xml_context::end_element(xmlns_token_t ns, xml_token_t name) +{ + if (ns == XMLNS_gnm) + { + switch (name) + { + + } + } + return pop_stack(ns, name); +} + +void gnumeric_content_xml_context::characters(const pstring& str) +{ +} + +} diff --git a/src/liborcus/gnumeric_handler.cpp b/src/liborcus/gnumeric_handler.cpp new file mode 100755 index 0000000..d8a6264 --- /dev/null +++ b/src/liborcus/gnumeric_handler.cpp @@ -0,0 +1,100 @@ +/************************************************************************* + * + * Copyright (c) 2010-2012 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#include "orcus/gnumeric/gnumeric_handler.hpp" +#include "orcus/gnumeric/gnumeric_context.hpp" +#include "orcus/exception.hpp" + +#include + +using namespace std; + +namespace orcus { + +gnumeric_content_xml_handler::gnumeric_content_xml_handler(const tokens& tokens, spreadsheet::iface::import_factory* factory) : + mp_factory(factory) +{ + m_context_stack.push_back(new gnumeric_content_xml_context(tokens, factory)); +} + +gnumeric_content_xml_handler::~gnumeric_content_xml_handler() +{ +} + +void gnumeric_content_xml_handler::start_document() +{ +} + +void gnumeric_content_xml_handler::end_document() +{ +} + +void gnumeric_content_xml_handler::start_element( + xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs) +{ + xml_context_base& cur = get_current_context(); + if (!cur.can_handle_element(ns, name)) + m_context_stack.push_back(cur.create_child_context(ns, name)); + + get_current_context().start_element(ns, name, attrs); +} + +void gnumeric_content_xml_handler::end_element(xmlns_token_t ns, xml_token_t name) +{ + bool ended = get_current_context().end_element(ns, name); + + if (ended) + { + if (m_context_stack.size() > 1) + { + // Call end_child_context of the parent context to provide a way for + // the two adjacent contexts to communicate with each other. + context_stack_type::reverse_iterator itr_cur = m_context_stack.rbegin(); + context_stack_type::reverse_iterator itr_par = itr_cur + 1; + itr_par->end_child_context(ns, name, &(*itr_cur)); + } + m_context_stack.pop_back(); + } +} + +void gnumeric_content_xml_handler::characters(const pstring& str) +{ + if(m_context_stack.empty()) + return; + + get_current_context().characters(str); +} + +xml_context_base& gnumeric_content_xml_handler::get_current_context() +{ + if (m_context_stack.empty()) + throw general_error("context stack is empty"); + + return m_context_stack.back(); +} + +} diff --git a/src/liborcus/gnumeric_sheet_context.cpp b/src/liborcus/gnumeric_sheet_context.cpp new file mode 100755 index 0000000..868d0d7 --- /dev/null +++ b/src/liborcus/gnumeric_sheet_context.cpp @@ -0,0 +1,103 @@ +/************************************************************************* + * + * Copyright (c) 2010, 2011 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ +#include "orcus/gnumeric/gnumeric_sheet_context.hpp" +#include "orcus/gnumeric/gnumeric_cell_context.hpp" +#include "orcus/gnumeric/gnumeric_token_constants.hpp" +#include "orcus/global.hpp" +#include "orcus/spreadsheet/import_interface.hpp" + + +namespace orcus { + + gnumeric_sheet_context::gnumeric_sheet_context(const tokens& tokens, spreadsheet::iface::import_factory* factory): + xml_context_base(tokens), + mp_factory(factory) + { + } + + gnumeric_sheet_context::~gnumeric_sheet_context() + { + } + + bool gnumeric_sheet_context::can_handle_element(xmlns_token_t ns, xml_token_t name) const + { + if(ns == XMLNS_gnm && name == XML_Cells) + return false; + + return true; + } + + xml_context_base* gnumeric_sheet_context::create_child_context(xmlns_token_t ns, xml_token_t name) const + { + if(ns == XMLNS_gnm && name == XML_Cells) + return new gnumeric_cell_context(get_tokens(), mp_factory, mp_sheet); + + return NULL; + } + void gnumeric_sheet_context::end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child) + { + } + + void gnumeric_sheet_context::start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs) + { + xml_token_pair_t parent = push_stack(ns, name); + } + + bool gnumeric_sheet_context::end_element(xmlns_token_t ns, xml_token_t name) + { + if(ns == XMLNS_gnm) + { + switch(name) + { + case XML_Name: + { + xml_token_pair_t parent = get_parent_element(); + if(parent.first == XMLNS_gnm && parent.second == XML_Sheet) + end_table(); + else + warn_unhandled(); + } + break; + default: + break; + } + } + + return pop_stack(ns, name); + } + + void gnumeric_sheet_context::characters(const pstring& str) + { + chars = str; + } + + void gnumeric_sheet_context::end_table() + { + mp_sheet = mp_factory->append_sheet(chars.get(), chars.size()); + } + +} diff --git a/src/liborcus/gnumeric_tokens.cpp b/src/liborcus/gnumeric_tokens.cpp new file mode 100755 index 0000000..2dea647 --- /dev/null +++ b/src/liborcus/gnumeric_tokens.cpp @@ -0,0 +1,40 @@ +/************************************************************************* + * + * Copyright (c) 2010 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#include "orcus/gnumeric/gnumeric_tokens.hpp" + +namespace orcus { + +namespace { + +#include "gnumeric_tokens.inl" + +} + +tokens gnumeric_tokens = + tokens(token_names, token_name_count, nstoken_names, nstoken_name_count); + diff --git a/src/liborcus/orcus_gnumeric.cpp b/src/liborcus/orcus_gnumeric.cpp new file mode 100755 index 0000000..44b5680 --- /dev/null +++ b/src/liborcus/orcus_gnumeric.cpp @@ -0,0 +1,108 @@ +/************************************************************************* + * + * Copyright (c) 2010-2012 Kohei Yoshida + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + ************************************************************************/ + +#include "orcus/orcus_gnumeric.hpp" +#include "orcus/xml_parser.hpp" +#include "orcus/gnumeric/gnumeric_handler.hpp" +#include "orcus/gnumeric/gnumeric_tokens.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; + +#define BUFFER_LENGTH 0x2000 + +namespace orcus { + + +orcus_gnumeric::orcus_gnumeric(spreadsheet::iface::import_factory* factory) : + mp_factory(factory) +{ +} + +orcus_gnumeric::~orcus_gnumeric() +{ +} + +void orcus_gnumeric::read_content_xml(const char* p, size_t size) +{ + xml_stream_parser parser(gnumeric_tokens, p, size, "content.xml"); + ::boost::scoped_ptr handler( + new gnumeric_content_xml_handler(gnumeric_tokens, mp_factory)); + parser.set_handler(handler.get()); + parser.parse(); +} + +void orcus_gnumeric::read_file(const char* fpath) +{ + cout << "reading " << fpath << endl; + + gzFile file = gzopen(fpath, "rb"); + + if(!file) + return; + + std::string file_content; + + while(1) + { + char buffer[BUFFER_LENGTH]; + int read_characters = gzread(file, buffer, BUFFER_LENGTH); + if(read_characters < 0) + { + std::cout << "Read error" << std::endl; + break; + } + + file_content.append(buffer, read_characters); + if(read_characters < BUFFER_LENGTH) + { + if(gzeof(file)) + break; + else + { + const char * error; + int err; + error = gzerror (file, &err); + std::cout << "error: " << error << std::endl; + } + } + } + + read_content_xml(file_content.c_str(), file_content.length()); +} + +} -- 1.7.10.4