mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
optimize format garbage collection and apply style fills to formats correctly, fixes #79, fix cell iteration, closes #73, add third-party licenses to LICENSE.md, update README, fix all clang and msvc warnings
This commit is contained in:
parent
26c2f89abb
commit
f90e35e007
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -2,28 +2,34 @@
|
|||
path = third-party/libstudxml
|
||||
url = http://scm.codesynthesis.com/libstudxml/libstudxml.git
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/cxxtest"]
|
||||
path = third-party/cxxtest
|
||||
url = https://github.com/CxxTest/cxxtest
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/utfcpp"]
|
||||
path = third-party/utfcpp
|
||||
url = https://github.com/nemtrif/utfcpp
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/pugixml"]
|
||||
path = third-party/pugixml
|
||||
url = https://github.com/zeux/pugixml
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/botan"]
|
||||
path = third-party/botan
|
||||
url = https://github.com/randombit/botan
|
||||
branch = master
|
||||
ignore = dirty
|
||||
|
||||
[submodule "third-party/zlib"]
|
||||
path = third-party/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
branch = develop
|
||||
ignore = dirty
|
||||
|
|
421
LICENCE.md
421
LICENCE.md
|
@ -1,5 +1,5 @@
|
|||
This software is under the MIT Licence
|
||||
======================================
|
||||
This software is distributed under the MIT Licence
|
||||
==================================================
|
||||
|
||||
Copyright (c) 2014-2015 Thomas Fussell
|
||||
|
||||
|
@ -21,3 +21,420 @@ 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.
|
||||
|
||||
|
||||
Third-party licenses
|
||||
====================
|
||||
|
||||
|
||||
Pole is distributed under the BSD 2-Clause License
|
||||
==================================================
|
||||
|
||||
POLE - Portable C++ library to access OLE Storage
|
||||
Copyright (C) 2002-2007 Ariya Hidayat (ariya@kde.org). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Botan is distributed under the BSD 2-Clause License
|
||||
===================================================
|
||||
|
||||
Copyright (C) 1999-2013,2014,2015,2016 Jack Lloyd
|
||||
2001 Peter J Jones
|
||||
2004-2007 Justin Karneges
|
||||
2004 Vaclav Ovsik
|
||||
2005 Matthew Gregan
|
||||
2005-2006 Matt Johnston
|
||||
2006 Luca Piccarreta
|
||||
2007 Yves Jerschow
|
||||
2007,2008 FlexSecure GmbH
|
||||
2007,2008 Technische Universitat Darmstadt
|
||||
2007,2008,2010,2014 Falko Strenzke
|
||||
2007,2008 Martin Doering
|
||||
2007 Manuel Hartl
|
||||
2007 Christoph Ludwig
|
||||
2007 Patrick Sona
|
||||
2008 Copyright Projet SECRET, INRIA, Rocquencourt
|
||||
2008 Bhaskar Biswas and Nicolas Sendrier
|
||||
2008 Google Inc.
|
||||
2010 Olivier de Gaalon
|
||||
2012 Vojtech Kral
|
||||
2012,2014 Markus Wanner
|
||||
2013 Joel Low
|
||||
2014 cryptosource GmbH
|
||||
2014 Andrew Moon
|
||||
2015 Daniel Seither (Kullo GmbH)
|
||||
2015 Simon Warta (Kullo GmbH)
|
||||
2015 Matej Kenda (TopIT d.o.o.)
|
||||
2015 René Korthaus
|
||||
2015,2016 Daniel Neus
|
||||
2015 Uri Blumenthal
|
||||
2015,2016 Kai Michaelis
|
||||
2016 Simon Cogliani
|
||||
2015,2016 Rohde & Schwarz Cybersecurity
|
||||
2016 Juraj Somorovsky
|
||||
2016 Christian Mainka
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
libstudxml is distributed under the MIT License
|
||||
===============================================
|
||||
|
||||
Summary: Everything is licensed under the MIT License (text below).
|
||||
|
||||
Code found in the xml/details/expat/ directory is distributed under
|
||||
the MIT License (see the xml/details/expat/LICENSE file for copyright
|
||||
information).
|
||||
|
||||
Code found in the xml/details/genx/ directory is distributed under
|
||||
the MIT License (see the xml/details/genx/LICENSE file for copyright
|
||||
information).
|
||||
|
||||
The rest is Copyright (c) 2013-2014 Code Synthesis Tools CC and is
|
||||
distributed under the MIT License:
|
||||
|
||||
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.
|
||||
|
||||
|
||||
pugixml is distributed under the MIT License
|
||||
============================================
|
||||
|
||||
Copyright (c) 2006-2016 Arseny Kapoulkine
|
||||
|
||||
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.
|
||||
|
||||
|
||||
zlib is distributed under the zlib license
|
||||
==========================================
|
||||
|
||||
(C) 1995-2013 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
utfcpp is distributed under the Boost Software License - Version 1.0
|
||||
====================================================================
|
||||
|
||||
Copyright 2006 Nemanja Trifunovic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
CxxTest is distributed under the LGPL License
|
||||
=============================================
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
||||
|
||||
partio is distributed under the BSD 3-Clause License (with specific non-attribution clause)
|
||||
===========================================================================================
|
||||
|
||||
Copyright 2010 Disney Enterprises, Inc. All rights reserved
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
|
||||
Studios" or the names of its contributors may NOT be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission from Walt Disney Pictures.
|
||||
|
||||
Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
|
79
README.md
79
README.md
|
@ -8,17 +8,16 @@
|
|||
[![License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://opensource.org/licenses/MIT)
|
||||
|
||||
## Introduction
|
||||
xlnt is a C++14 library for reading, writing, and modifying XLSX files as described in [ECMA 376 4th edition](http://www.ecma-international.org/publications/standards/Ecma-376.htm). The API is based on [openpyxl](https://bitbucket.org/openpyxl/openpyxl), a Python library to read/write Excel 2007 xlsx/xlsm files, and ultimately on [PHPExcel](https://github.com/PHPOffice/PHPExcel), pure PHP library for reading and writing spreadsheet files upon which openpyxl was based. This project is still very much a work in progress, but the core development work is complete.
|
||||
xlnt is a C++14 library for reading, writing, and modifying xlsx files as described in [ECMA 376 4th edition](http://www.ecma-international.org/publications/standards/Ecma-376.htm). The API was initially based on [openpyxl](https://bitbucket.org/openpyxl/openpyxl), a Python library to read/write Excel 2007 xlsx/xlsm files, which was itself based on [PHPExcel](https://github.com/PHPOffice/PHPExcel), pure PHP library for reading and writing spreadsheet files. xlnt is still very much a work in progress, but the core development work is complete. For a high-level summary of what you can do with this library, see [here](http://xlnt.readthedocs.io/en/latest/#summary-of-features).
|
||||
|
||||
## Usage
|
||||
Including xlnt in your project
|
||||
```c++
|
||||
// with -std=c++14 -Ixlnt/include -Lxlnt/lib -lxlnt
|
||||
// can also use the generated "xlnt.pc" in ./build directory with pkg-config to get these flags
|
||||
#include <xlnt/xlnt.hpp>
|
||||
```
|
||||
|
||||
Creating a new spreadsheet and saving it as book1.xlsx
|
||||
Creating a new spreadsheet and saving it as "example.xlsx"
|
||||
```c++
|
||||
xlnt::workbook wb;
|
||||
xlnt::worksheet ws = wb.get_active_sheet();
|
||||
|
@ -27,28 +26,11 @@ ws.get_cell("B2").set_value("string data");
|
|||
ws.get_cell("C3").set_formula("=RAND()");
|
||||
ws.merge_cells("C3:C4");
|
||||
ws.freeze_panes("B2");
|
||||
wb.save("book1.xlsx");
|
||||
```
|
||||
|
||||
Opening an existing spreadsheet, book2.xlsx, and printing all cells
|
||||
```c++
|
||||
xlnt::workbook wb2;
|
||||
wb2.load("book2.xlsx");
|
||||
|
||||
// no need to use references, "cell", "range", and "worksheet" classes are only wrappers around pointers to memory in the workbook
|
||||
for(auto row : wb2["sheet2"].rows())
|
||||
{
|
||||
for(auto cell : row)
|
||||
{
|
||||
std::cout << cell << std::endl;
|
||||
}
|
||||
}
|
||||
wb.save("example.xlsx");
|
||||
```
|
||||
|
||||
## Building
|
||||
xlnt uses continous integration and passes all 200+ tests in GCC 4.9, GCC5, VS2015, and Clang (using Apple LLVM 7.0).
|
||||
|
||||
Build configurations for Visual Studio 2015, GNU Make, and Xcode can be created using [cmake](https://cmake.org/) and the cmake scripts in the project's cmake directory. A full list of cmake generators can be found [here](https://cmake.org/cmake/help/v3.0/manual/cmake-generators.7.html). A basic build would look like (starting in the root xlnt directory):
|
||||
xlnt uses continous integration (thanks [Travis CI](https://travis-ci.org/) and [AppVeyor](https://www.appveyor.com/)!) and passes all 270+ tests in GCC 4, GCC 5, VS2015 U3, and Clang (using Apple LLVM 8.0). Build configurations for Visual Studio 2015, GNU Make, and Xcode can be created using [cmake](https://cmake.org/) v3.1+. A full list of cmake generators can be found [here](https://cmake.org/cmake/help/v3.0/manual/cmake-generators.7.html). A basic build would look like (starting in the root xlnt directory):
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
|
@ -57,55 +39,42 @@ cmake ..
|
|||
make -j8
|
||||
```
|
||||
|
||||
The resulting library, libxlnt.dylib or libxlnt.so or xlnt.dll, would be found in the build/lib directory. Other cmake configuration options can be found using "cmake -LH". These options include shared vs static library and whether to build tests or not. An example of building a static library with tests as an Xcode project:
|
||||
The resulting shared (e.g. libxlnt.dylib) library would be found in the build/lib directory. Other cmake configuration options for xlnt can be found using "cmake -LH". These options include building a static library instead of shared and whether to build sample executables or not. An example of building a static library with an Xcode project:
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -D WITH_TESTS=1 -D SHARED=0 -D STATIC=1 -G Xcode ..
|
||||
cmake -D STATIC=ON -G Xcode ..
|
||||
cmake --build .
|
||||
bin/xlnt.test
|
||||
cd bin && ./xlnt.test
|
||||
```
|
||||
*Note for Windows: cmake defaults to building a 32-bit library project. To build a 64-bit library, use the Win64 generator*
|
||||
```bash
|
||||
cmake -G "Visual Studio 14 2015 Win64" ..
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
xlnt uses the following libraries, which are included in the source tree (all but miniz as [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules#Cloning-a-Project-with-Submodules)) for convenience:
|
||||
- [miniz v1.15_r4](https://code.google.com/p/miniz/) (public domain/unlicense)
|
||||
xlnt requires the following libraries which are all distributed under permissive open source licenses. All libraries are included in the source tree as [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules#Cloning-a-Project-with-Submodules) for convenience except for pole and partio's zip component which have been modified and reside in xlnt/source/detail:
|
||||
- [zlib v1.2.8](http://zlib.net/) (zlib License)
|
||||
- [libstudxml v1.1.0](http://www.codesynthesis.com/projects/libstudxml/) (MIT license)
|
||||
- [utfcpp v2.3.4](http://utfcpp.sourceforge.net/) (Boost Software License, Version 1.0)
|
||||
- [cxxtest v4.4](http://cxxtest.com/) (LGPLv3 license [only used for testing, separate from main library assembly])
|
||||
- [pugixml v1.7](http://cxxtest.com/) (LGPLv3 license [only used for testing, separate from main library assembly])
|
||||
- [botan v1.11](https://botan.randombit.net/) (BSD license)
|
||||
- [pole v0.5](https://github.com/catlan/pole) (BSD license)
|
||||
- [botan v1.11](https://botan.randombit.net/) (BSD 2-Clause License)
|
||||
- [pole v0.5](https://github.com/catlan/pole) (BSD 2-Clause License)
|
||||
- [partio v1.1.0](https://github.com/wdas/partio) (BSD 3-Clause License with specific non-attribution clause)
|
||||
|
||||
Initialize the submodules with this command:
|
||||
Additionally, the xlnt test suite (bin/xlnt.test) requires two extra libraries. This test executable is separate from the main xlnt library assembly so the terms of these libraries' licenses should not apply to users of solely the xlnt library:
|
||||
- [cxxtest v4.4](http://cxxtest.com/) (LGPLv3 License)
|
||||
- [pugixml v1.7](http://pugixml.org/) (MIT License)
|
||||
|
||||
Initialize the submodules from the HEAD of their respective Git repositories with this command called from the xlnt root directory:
|
||||
```bash
|
||||
git submodule update --init
|
||||
git submodule update --init --remote
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
More detailed documentation with examples can be found on [Read The Docs](http://xlnt.readthedocs.org/en/latest/) (warning: this is somewhat out of date at the moment).
|
||||
More detailed documentation with examples can be found on [Read The Docs](http://xlnt.readthedocs.org/en/latest/) (Warning: As of November 9, 2016 this is very out of date).
|
||||
|
||||
## License
|
||||
xlnt is currently released to the public for free under the terms of the MIT License:
|
||||
|
||||
Copyright (c) 2015-2016 Thomas Fussell
|
||||
|
||||
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.
|
||||
xlnt is released to the public for free under the terms of the MIT License. See [LICENSE.md](https://github.com/tfussell/xlnt/blob/master/LICENCE.md) for the full text of the license and the licenses of xlnt's third-party dependencies. [LICENSE.md](https://github.com/tfussell/xlnt/blob/master/LICENCE.md) should be distributed alongside any assemblies that use xlnt in source or compiled form.
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ public:
|
|||
/// </summary>
|
||||
static const std::unordered_map<std::string, int> &error_codes();
|
||||
|
||||
cell(const cell &) = default;
|
||||
|
||||
// value
|
||||
|
||||
/// <summary>
|
||||
|
@ -499,6 +501,8 @@ private:
|
|||
/// </summary>
|
||||
class format modifiable_format();
|
||||
|
||||
cell() = delete;
|
||||
|
||||
/// <summary>
|
||||
/// Private constructor to create a cell from its implementation.
|
||||
/// </summary>
|
||||
|
|
|
@ -58,32 +58,32 @@ public:
|
|||
|
||||
class alignment &alignment();
|
||||
const class alignment &alignment() const;
|
||||
style alignment(const xlnt::alignment &new_alignment, bool applied);
|
||||
style alignment(const xlnt::alignment &new_alignment, bool applied = true);
|
||||
bool alignment_applied() const;
|
||||
|
||||
class border &border();
|
||||
const class border &border() const;
|
||||
style border(const xlnt::border &new_border, bool applied);
|
||||
style border(const xlnt::border &new_border, bool applied = true);
|
||||
bool border_applied() const;
|
||||
|
||||
class fill &fill();
|
||||
const class fill &fill() const;
|
||||
style fill(const xlnt::fill &new_fill, bool applied);
|
||||
style fill(const xlnt::fill &new_fill, bool applied = true);
|
||||
bool fill_applied() const;
|
||||
|
||||
class font &font();
|
||||
const class font &font() const;
|
||||
style font(const xlnt::font &new_font, bool applied);
|
||||
style font(const xlnt::font &new_font, bool applied = true);
|
||||
bool font_applied() const;
|
||||
|
||||
class number_format &number_format();
|
||||
const class number_format &number_format() const;
|
||||
style number_format(const xlnt::number_format &new_number_format, bool applied);
|
||||
style number_format(const xlnt::number_format &new_number_format, bool applied = true);
|
||||
bool number_format_applied() const;
|
||||
|
||||
class protection &protection();
|
||||
const class protection &protection() const;
|
||||
style protection(const xlnt::protection &new_protection, bool applied);
|
||||
style protection(const xlnt::protection &new_protection, bool applied = true);
|
||||
bool protection_applied() const;
|
||||
|
||||
bool hidden() const;
|
||||
|
|
|
@ -54,6 +54,8 @@ class XLNT_API invalid_parameter : public exception
|
|||
{
|
||||
public:
|
||||
invalid_parameter();
|
||||
invalid_parameter(const invalid_parameter &) = default;
|
||||
virtual ~invalid_parameter();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -63,6 +65,8 @@ class XLNT_API invalid_sheet_title : public exception
|
|||
{
|
||||
public:
|
||||
invalid_sheet_title(const std::string &title);
|
||||
invalid_sheet_title(const invalid_sheet_title &) = default;
|
||||
virtual ~invalid_sheet_title();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -72,6 +76,7 @@ class XLNT_API missing_number_format : public exception
|
|||
{
|
||||
public:
|
||||
missing_number_format();
|
||||
virtual ~missing_number_format();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -81,6 +86,8 @@ class XLNT_API invalid_file : public exception
|
|||
{
|
||||
public:
|
||||
invalid_file(const std::string &filename);
|
||||
invalid_file(const invalid_file &) = default;
|
||||
virtual ~invalid_file();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -91,6 +98,8 @@ class XLNT_API illegal_character : public exception
|
|||
{
|
||||
public:
|
||||
illegal_character(char c);
|
||||
illegal_character(const illegal_character &) = default;
|
||||
virtual ~illegal_character();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -100,6 +109,8 @@ class XLNT_API invalid_data_type : public exception
|
|||
{
|
||||
public:
|
||||
invalid_data_type();
|
||||
invalid_data_type(const invalid_data_type &) = default;
|
||||
virtual ~invalid_data_type();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -143,6 +154,8 @@ class XLNT_API key_not_found : public exception
|
|||
{
|
||||
public:
|
||||
key_not_found();
|
||||
key_not_found(const key_not_found &) = default;
|
||||
virtual ~key_not_found();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -152,6 +165,8 @@ class XLNT_API no_visible_worksheets : public exception
|
|||
{
|
||||
public:
|
||||
no_visible_worksheets();
|
||||
no_visible_worksheets(const no_visible_worksheets &) = default;
|
||||
virtual ~no_visible_worksheets();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -161,6 +176,7 @@ class XLNT_API unhandled_switch_case : public exception
|
|||
{
|
||||
public:
|
||||
unhandled_switch_case();
|
||||
virtual ~unhandled_switch_case();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -170,6 +186,8 @@ class XLNT_API unsupported : public exception
|
|||
{
|
||||
public:
|
||||
unsupported(const std::string &message);
|
||||
unsupported(const unsupported &) = default;
|
||||
virtual ~unsupported();
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -424,7 +424,7 @@ public:
|
|||
|
||||
format get_format(std::size_t format_index);
|
||||
const format get_format(std::size_t format_index) const;
|
||||
format create_format();
|
||||
format create_format(bool default_format = false);
|
||||
void clear_formats();
|
||||
|
||||
// styles
|
||||
|
|
|
@ -38,17 +38,19 @@ class cell_reference;
|
|||
class range_reference;
|
||||
enum class major_order;
|
||||
|
||||
class XLNT_API cell_iterator : public std::iterator<std::bidirectional_iterator_tag, cell, std::ptrdiff_t, cell*, cell>
|
||||
class XLNT_API cell_iterator : public std::iterator<std::bidirectional_iterator_tag, cell, std::ptrdiff_t, cell *, cell>
|
||||
{
|
||||
public:
|
||||
cell_iterator(worksheet ws, const cell_reference &start_cell);
|
||||
cell_iterator(worksheet ws, const cell_reference &start_cell, const range_reference &limits);
|
||||
|
||||
cell_iterator(worksheet ws, const cell_reference &start_cell, major_order order);
|
||||
cell_iterator(worksheet ws, const cell_reference &start_cell, const range_reference &limits, major_order order);
|
||||
|
||||
cell_iterator(const cell_iterator &other);
|
||||
|
||||
cell operator*();
|
||||
|
||||
cell_iterator &operator=(const cell_iterator &) = default;
|
||||
|
||||
bool operator==(const cell_iterator &other) const;
|
||||
|
||||
bool operator!=(const cell_iterator &other) const;
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
|
||||
const_cell_iterator(const const_cell_iterator &other);
|
||||
|
||||
const_cell_iterator &operator=(const const_cell_iterator &) = default;
|
||||
|
||||
const cell operator*() const;
|
||||
|
||||
bool operator==(const const_cell_iterator &other) const;
|
||||
|
|
|
@ -52,6 +52,8 @@ public:
|
|||
|
||||
const cell_vector operator*() const;
|
||||
|
||||
const_range_iterator &operator=(const const_range_iterator &) = default;
|
||||
|
||||
bool operator==(const const_range_iterator &other) const;
|
||||
|
||||
bool operator!=(const const_range_iterator &other) const;
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
|
||||
~range();
|
||||
|
||||
range(const range &) = default;
|
||||
|
||||
cell_vector operator[](std::size_t vector_index);
|
||||
|
||||
const cell_vector operator[](std::size_t vector_index) const;
|
||||
|
|
|
@ -28,15 +28,11 @@
|
|||
#include <xlnt/cell/cell_reference.hpp>
|
||||
#include <xlnt/worksheet/major_order.hpp>
|
||||
#include <xlnt/worksheet/range_reference.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class cell_vector;
|
||||
class worksheet;
|
||||
|
||||
namespace detail {
|
||||
struct worksheet_impl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An iterator used by worksheet and range for traversing
|
||||
|
@ -45,12 +41,14 @@ struct worksheet_impl;
|
|||
class XLNT_API range_iterator : public std::iterator<std::bidirectional_iterator_tag, cell_vector, std::ptrdiff_t, cell_vector*, cell_vector>
|
||||
{
|
||||
public:
|
||||
range_iterator(worksheet &ws, const range_reference &start_cell, major_order order = major_order::row);
|
||||
range_iterator(worksheet &ws, const range_reference &start_cell, const range_reference &limits, major_order order = major_order::row);
|
||||
|
||||
range_iterator(const range_iterator &other);
|
||||
|
||||
cell_vector operator*() const;
|
||||
|
||||
range_iterator &operator=(const range_iterator &) = default;
|
||||
|
||||
bool operator==(const range_iterator &other) const;
|
||||
|
||||
bool operator!=(const range_iterator &other) const;
|
||||
|
@ -64,7 +62,7 @@ public:
|
|||
range_iterator operator++(int);
|
||||
|
||||
private:
|
||||
detail::worksheet_impl *ws_;
|
||||
worksheet ws_;
|
||||
cell_reference current_cell_;
|
||||
range_reference range_;
|
||||
major_order order_;
|
||||
|
|
|
@ -56,7 +56,7 @@ if(MSVC)
|
|||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unknown-pragmas")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Werror")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
|
@ -117,7 +117,6 @@ if(NOT STATIC)
|
|||
|
||||
if(MSVC)
|
||||
target_compile_definitions(xlnt PRIVATE XLNT_EXPORT=1 _CRT_SECURE_NO_WARNINGS=1)
|
||||
set_target_properties(xlnt PROPERTIES COMPILE_FLAGS "/wd\"4251\" /wd\"4275\" /MP")
|
||||
endif()
|
||||
|
||||
install(TARGETS xlnt
|
||||
|
@ -148,7 +147,6 @@ else()
|
|||
|
||||
if(MSVC)
|
||||
target_compile_definitions(xlnt PRIVATE _CRT_SECURE_NO_WARNINGS=1 NOMINMAX)
|
||||
set_target_properties(xlnt PROPERTIES COMPILE_FLAGS "/MP")
|
||||
endif()
|
||||
|
||||
install(TARGETS xlnt
|
||||
|
@ -160,6 +158,10 @@ endif()
|
|||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE LIBSTUDXML_STATIC_LIB=1)
|
||||
|
||||
if(MSVC)
|
||||
set_target_properties(xlnt PROPERTIES COMPILE_FLAGS "/wd\"4251\" /wd\"4275\" /wd\"4068\" /MP")
|
||||
endif()
|
||||
|
||||
source_group(xlnt FILES ${ROOT_HEADERS})
|
||||
source_group(detail FILES ${DETAIL_HEADERS} ${DETAIL_SOURCES})
|
||||
source_group(cell FILES ${CELL_HEADERS} ${CELL_SOURCES})
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
#include <detail/cell_impl.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <xlnt/cell/cell.hpp>
|
||||
#include <xlnt/cell/cell_reference.hpp>
|
||||
#include <xlnt/cell/comment.hpp>
|
||||
|
@ -49,8 +51,6 @@
|
|||
#include <xlnt/worksheet/row_properties.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
#include <detail/cell_impl.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
std::pair<bool, long double> cast_numeric(const std::string &s)
|
||||
|
@ -559,8 +559,8 @@ const workbook &cell::get_workbook() const
|
|||
//TODO: this shares a lot of code with worksheet::get_point_pos, try to reduce repetion
|
||||
std::pair<int, int> cell::get_anchor() const
|
||||
{
|
||||
static const double DefaultColumnWidth = 51.85;
|
||||
static const double DefaultRowHeight = 15.0;
|
||||
static const auto DefaultColumnWidth = 51.85L;
|
||||
static const auto DefaultRowHeight = 15.0L;
|
||||
|
||||
auto points_to_pixels = [](long double value, long double dpi)
|
||||
{
|
||||
|
@ -569,7 +569,7 @@ std::pair<int, int> cell::get_anchor() const
|
|||
|
||||
auto left_columns = d_->column_ - 1;
|
||||
int left_anchor = 0;
|
||||
auto default_width = points_to_pixels(DefaultColumnWidth, 96.0);
|
||||
auto default_width = points_to_pixels(DefaultColumnWidth, 96.0L);
|
||||
|
||||
for (column_t column_index = 1; column_index <= left_columns; column_index++)
|
||||
{
|
||||
|
@ -579,7 +579,7 @@ std::pair<int, int> cell::get_anchor() const
|
|||
|
||||
if (cdw > 0)
|
||||
{
|
||||
left_anchor += points_to_pixels(cdw, 96.0);
|
||||
left_anchor += points_to_pixels(cdw, 96.0L);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ std::pair<int, int> cell::get_anchor() const
|
|||
|
||||
auto top_rows = d_->row_ - 1;
|
||||
int top_anchor = 0;
|
||||
auto default_height = points_to_pixels(DefaultRowHeight, 96.0);
|
||||
auto default_height = points_to_pixels(DefaultRowHeight, 96.0L);
|
||||
|
||||
for (row_t row_index = 1; row_index <= top_rows; row_index++)
|
||||
{
|
||||
|
@ -599,7 +599,7 @@ std::pair<int, int> cell::get_anchor() const
|
|||
|
||||
if (rdh > 0)
|
||||
{
|
||||
top_anchor += points_to_pixels(rdh, 96.0);
|
||||
top_anchor += points_to_pixels(rdh, 96.0L);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -836,9 +836,11 @@ std::string cell::to_string() const
|
|||
case cell::type::error:
|
||||
return nf.format(get_value<std::string>());
|
||||
case cell::type::boolean:
|
||||
return get_value<long double>() == 0 ? "FALSE" : "TRUE";
|
||||
return get_value<long double>() == 0.L ? "FALSE" : "TRUE";
|
||||
#ifdef WIN32
|
||||
default:
|
||||
return "";
|
||||
throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -849,6 +851,12 @@ bool cell::has_format() const
|
|||
|
||||
void cell::format(const class format new_format)
|
||||
{
|
||||
if (has_format())
|
||||
{
|
||||
format().d_->references -= format().d_->references > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
++new_format.d_->references;
|
||||
d_->format_ = new_format.d_;
|
||||
}
|
||||
|
||||
|
@ -897,6 +905,7 @@ void cell::guess_type_and_set_value(const std::string &value)
|
|||
|
||||
void cell::clear_format()
|
||||
{
|
||||
format().d_->references -= format().d_->references > 0 ? 1 : 0;
|
||||
d_->format_.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,21 @@
|
|||
|
||||
#include <xlnt/xlnt.hpp>
|
||||
|
||||
#include <numeric>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <random>
|
||||
#include <chrono>
|
||||
|
||||
int random(int min, int max)
|
||||
{
|
||||
static std::random_device device{};
|
||||
static std::default_random_engine engine{ device() };
|
||||
std::uniform_int_distribution<int> distribution{ min, max };
|
||||
return distribution(engine);
|
||||
}
|
||||
|
||||
class test_cell : public CxxTest::TestSuite
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -66,7 +66,7 @@ const path constants::part_shared_strings() { return package_xl().append("shared
|
|||
|
||||
const std::unordered_map<std::string, std::string> &constants::get_namespaces()
|
||||
{
|
||||
const std::unordered_map<std::string, std::string> *namespaces =
|
||||
static const std::unordered_map<std::string, std::string> *namespaces =
|
||||
new std::unordered_map<std::string, std::string>
|
||||
{
|
||||
{ "worksheet", "http://schemas.openxmlformats.org/spreadsheetml/2006/main" },
|
||||
|
@ -77,6 +77,10 @@ const std::unordered_map<std::string, std::string> &constants::get_namespaces()
|
|||
{ "core-properties", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties" },
|
||||
{ "extended-properties", "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" },
|
||||
|
||||
{ "encryption", "http://schemas.microsoft.com/office/2006/encryption" },
|
||||
{ "encryption-password", "http://schemas.microsoft.com/office/2006/keyEncryptor/password" },
|
||||
{ "encryption-certificate", "http://schemas.microsoft.com/office/2006/keyEncryptor/certificate" },
|
||||
|
||||
{ "dc", "http://purl.org/dc/elements/1.1/" },
|
||||
{ "dcterms", "http://purl.org/dc/terms/" },
|
||||
{ "dcmitype", "http://purl.org/dc/dcmitype/" },
|
||||
|
@ -96,7 +100,7 @@ const std::unordered_map<std::string, std::string> &constants::get_namespaces()
|
|||
return *namespaces;
|
||||
}
|
||||
|
||||
const std::string constants::get_namespace(const std::string &id)
|
||||
const std::string &constants::get_namespace(const std::string &id)
|
||||
{
|
||||
return get_namespaces().find(id)->second;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ struct XLNT_API constants
|
|||
/// <summary>
|
||||
/// Returns the namespace URI from a namespace name.
|
||||
/// </summary>
|
||||
static const std::string get_namespace(const std::string &id);
|
||||
static const std::string &get_namespace(const std::string &id);
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -15,7 +15,9 @@ std::string to_string(font::underline_style style)
|
|||
case font::underline_style::single: return "single";
|
||||
case font::underline_style::single_accounting: return "singleAccounting";
|
||||
case font::underline_style::none: return "none";
|
||||
default: return default_case("none");
|
||||
#ifdef WIN32
|
||||
default: throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,8 +55,54 @@ std::string to_string(relationship::type t)
|
|||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
|
||||
case relationship::type::vml_drawing:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing";
|
||||
case relationship::type::unknown:
|
||||
return "unknown";
|
||||
case relationship::type::custom_properties:
|
||||
return "custom-properties";
|
||||
case relationship::type::printer_settings:
|
||||
return "printer-settings";
|
||||
case relationship::type::connections:
|
||||
return "connections";
|
||||
case relationship::type::custom_property:
|
||||
return "custom-property";
|
||||
case relationship::type::custom_xml_mappings:
|
||||
return "custom-xml-mappings";
|
||||
case relationship::type::dialogsheet:
|
||||
return "dialogsheet";
|
||||
case relationship::type::drawings:
|
||||
return "drawings";
|
||||
case relationship::type::external_workbook_references:
|
||||
return "external-workbook-references";
|
||||
case relationship::type::metadata:
|
||||
return "metadata";
|
||||
case relationship::type::pivot_table:
|
||||
return "pivot-table";
|
||||
case relationship::type::pivot_table_cache_definition:
|
||||
return "pivot-table-cache-definition";
|
||||
case relationship::type::pivot_table_cache_records:
|
||||
return "pivot-table-cache-records";
|
||||
case relationship::type::query_table:
|
||||
return "query-table";
|
||||
case relationship::type::shared_workbook_revision_headers:
|
||||
return "shared-workbook-revision-headers";
|
||||
case relationship::type::shared_workbook:
|
||||
return "shared-workbook";
|
||||
case relationship::type::revision_log:
|
||||
return "revision-log";
|
||||
case relationship::type::shared_workbook_user_data:
|
||||
return "shared-workbook-user-data";
|
||||
case relationship::type::single_cell_table_definitions:
|
||||
return "single-cell-table-definitions";
|
||||
case relationship::type::table_definition:
|
||||
return "table-definition";
|
||||
case relationship::type::volatile_dependencies:
|
||||
return "volatile-dependencies";
|
||||
case relationship::type::image:
|
||||
return "image";
|
||||
#ifdef WIN32
|
||||
default:
|
||||
return default_case("?");
|
||||
throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +129,9 @@ std::string to_string(pattern_fill_type fill_type)
|
|||
case pattern_fill_type::mediumgray: return "mediumgray";
|
||||
case pattern_fill_type::solid: return "solid";
|
||||
case pattern_fill_type::none: return "none";
|
||||
default: return default_case("none");
|
||||
#ifdef WIN32
|
||||
default: throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +158,9 @@ std::string to_string(border_style style)
|
|||
case border_style::thick: return "thick";
|
||||
case border_style::thin: return "thin";
|
||||
case border_style::none: return "none";
|
||||
default: return default_case("none");
|
||||
#ifdef WIN32
|
||||
default: throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +173,9 @@ std::string to_string(vertical_alignment alignment)
|
|||
case vertical_alignment::justify: return "justify";
|
||||
case vertical_alignment::top: return "top";
|
||||
case vertical_alignment::none: return "none";
|
||||
default: return default_case("none");
|
||||
#ifdef WIN32
|
||||
default: throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +190,9 @@ std::string to_string(horizontal_alignment alignment)
|
|||
case horizontal_alignment::left: return "left";
|
||||
case horizontal_alignment::right: return "right";
|
||||
case horizontal_alignment::none: return "none";
|
||||
default: return default_case("none");
|
||||
#ifdef WIN32
|
||||
default: throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +207,9 @@ std::string to_string(border_side side)
|
|||
case border_side::horizontal: return "horizontal";
|
||||
case border_side::vertical: return "vertical";
|
||||
case border_side::diagonal: return "diagonal";
|
||||
default: return default_case("top");
|
||||
#ifdef WIN32
|
||||
default: throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <xml/parser>
|
||||
#include <xml/serializer>
|
||||
#include <detail/include_libstudxml.hpp>
|
||||
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/styles/border.hpp>
|
||||
|
|
|
@ -9,7 +9,7 @@ const std::vector<std::uint8_t> &excel_thumbnail();
|
|||
|
||||
const std::vector<std::uint8_t> &excel_thumbnail()
|
||||
{
|
||||
const auto *data = new std::vector<std::uint8_t>{
|
||||
static const auto *data = new std::vector<std::uint8_t>{
|
||||
0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x00,0x00,0x48,0x00,0x48,0x00,0x00,0xff,0xe1,0x00,0x80,0x45,0x78,0x69,0x66,0x00,0x00,0x4d,0x4d,0x00
|
||||
,0x2a,0x00,0x00,0x00,0x08,0x00,0x04,0x01,0x1a,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x3e,0x01,0x1b,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x46,0x01
|
||||
,0x28,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x87,0x69,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00
|
||||
|
|
|
@ -49,6 +49,8 @@ struct format_impl
|
|||
|
||||
optional<std::string> style;
|
||||
|
||||
std::size_t references = 0;
|
||||
|
||||
XLNT_API friend bool operator==(const format_impl &left, const format_impl &right)
|
||||
{
|
||||
return left.parent == right.parent
|
||||
|
|
33
source/detail/include_botan.hpp
Normal file
33
source/detail/include_botan.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// 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, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#pragma clang diagnostic push
|
||||
|
||||
#pragma clang diagnostic ignored "-Wreserved-id-macro"
|
||||
#pragma clang diagnostic ignored "-Wdocumentation"
|
||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
|
||||
#include <botan_all.h>
|
||||
|
||||
#pragma clang diagnostic pop
|
|
@ -22,7 +22,12 @@
|
|||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
#pragma clang diagnostic ignored "-Wextra-semi"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
#include <xml/content>
|
||||
#include <xml/parser>
|
||||
#include <xml/qname>
|
||||
#include <xml/serializer>
|
||||
#pragma clang diagnostic pop
|
||||
|
|
|
@ -179,6 +179,10 @@ bool format_condition::satisfied_by(long double number) const
|
|||
return std::fabs(number - value) >= std::numeric_limits<long double>::min();
|
||||
case condition_type::equal:
|
||||
return std::fabs(number - value) < std::numeric_limits<long double>::min();
|
||||
#ifdef WIN32
|
||||
default:
|
||||
throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,7 +638,7 @@ void number_format_parser::finalize()
|
|||
auto temp = code.parts[exponent_index].placeholders.type;
|
||||
code.parts[exponent_index].placeholders = next.placeholders;
|
||||
code.parts[exponent_index].placeholders.type = temp;
|
||||
code.parts.erase(code.parts.begin() + exponent_index + 1);
|
||||
code.parts.erase(code.parts.begin() + static_cast<typename std::vector<format_code>::difference_type>(exponent_index + 1));
|
||||
|
||||
for (std::size_t i = 0; i < code.parts.size(); ++i)
|
||||
{
|
||||
|
@ -1261,7 +1265,7 @@ std::string number_formatter::fill_placeholders(const format_placeholders &p, lo
|
|||
|
||||
if (p.thousands_scale > 0)
|
||||
{
|
||||
number /= std::pow(1000, p.thousands_scale);
|
||||
number /= std::pow(1000.L, p.thousands_scale);
|
||||
}
|
||||
|
||||
auto integer_part = static_cast<int>(number);
|
||||
|
@ -1341,9 +1345,9 @@ std::string number_formatter::fill_scientific_placeholders(const format_placehol
|
|||
{
|
||||
std::size_t logarithm = 0;
|
||||
|
||||
if (number != 0)
|
||||
if (number != 0.L)
|
||||
{
|
||||
logarithm = static_cast<int>(std::log10(number));
|
||||
logarithm = static_cast<std::size_t>(std::log10(number));
|
||||
|
||||
if (integer_part.num_zeros + integer_part.num_optionals > 1)
|
||||
{
|
||||
|
@ -1351,14 +1355,14 @@ std::string number_formatter::fill_scientific_placeholders(const format_placehol
|
|||
}
|
||||
}
|
||||
|
||||
number /= std::pow(10, logarithm);
|
||||
number /= std::pow(10.L, logarithm);
|
||||
|
||||
auto integer = static_cast<int>(number);
|
||||
auto fraction = number - integer;
|
||||
|
||||
std::string integer_string = std::to_string(integer);
|
||||
|
||||
if (number == 0)
|
||||
if (number == 0.L)
|
||||
{
|
||||
integer_string = std::string(integer_part.num_zeros + integer_part.num_optionals, '0');
|
||||
}
|
||||
|
@ -1389,15 +1393,15 @@ std::string number_formatter::fill_scientific_placeholders(const format_placehol
|
|||
return integer_string + fractional_string + exponent_string;
|
||||
}
|
||||
|
||||
std::string number_formatter::fill_fraction_placeholders(const format_placeholders &numerator,
|
||||
const format_placeholders &denominator, long double number, bool improper)
|
||||
std::string number_formatter::fill_fraction_placeholders(const format_placeholders &/*numerator*/,
|
||||
const format_placeholders &denominator, long double number, bool /*improper*/)
|
||||
{
|
||||
auto fractional_part = number - static_cast<int>(number);
|
||||
auto original_fractional_part = fractional_part;
|
||||
fractional_part *= 10;
|
||||
|
||||
while (std::abs(fractional_part - static_cast<int>(fractional_part)) > 0.000001
|
||||
&& std::abs(fractional_part - static_cast<int>(fractional_part)) < 0.999999)
|
||||
while (std::abs(fractional_part - static_cast<int>(fractional_part)) > 0.000001L
|
||||
&& std::abs(fractional_part - static_cast<int>(fractional_part)) < 0.999999L)
|
||||
{
|
||||
fractional_part *= 10;
|
||||
}
|
||||
|
@ -1478,12 +1482,12 @@ std::string number_formatter::format_number(const format_code &format, long doub
|
|||
|
||||
if (format.is_datetime)
|
||||
{
|
||||
if (number != 0)
|
||||
if (number != 0.L)
|
||||
{
|
||||
dt = xlnt::datetime::from_number(number, calendar_);
|
||||
}
|
||||
|
||||
hour = dt.hour;
|
||||
hour = static_cast<std::size_t>(dt.hour);
|
||||
|
||||
if (format.twelve_hour)
|
||||
{
|
||||
|
@ -1526,7 +1530,7 @@ std::string number_formatter::format_number(const format_code &format, long doub
|
|||
{
|
||||
auto digits = std::min(static_cast<std::size_t>(6), part.placeholders.num_zeros + part.placeholders.num_optionals);
|
||||
auto denominator = static_cast<int>(std::pow(10.0, digits));
|
||||
auto fractional_seconds = dt.microsecond / 1.0E6 * denominator;
|
||||
auto fractional_seconds = dt.microsecond / 1.0E6L * denominator;
|
||||
fractional_seconds = std::round(fractional_seconds) / denominator;
|
||||
result.append(fill_placeholders(part.placeholders, fractional_seconds));
|
||||
break;
|
||||
|
@ -1541,7 +1545,7 @@ std::string number_formatter::format_number(const format_code &format, long doub
|
|||
{
|
||||
i += 2;
|
||||
|
||||
if (number == 0)
|
||||
if (number == 0.L)
|
||||
{
|
||||
result.pop_back();
|
||||
break;
|
||||
|
@ -1576,10 +1580,10 @@ std::string number_formatter::format_number(const format_code &format, long doub
|
|||
result.append(std::to_string(dt.day));
|
||||
break;
|
||||
case template_part::template_type::month_abbreviation:
|
||||
result.append(month_names->at(dt.month - 1).substr(0, 3));
|
||||
result.append(month_names->at(static_cast<std::size_t>(dt.month) - 1).substr(0, 3));
|
||||
break;
|
||||
case template_part::template_type::month_name:
|
||||
result.append(month_names->at(dt.month - 1));
|
||||
result.append(month_names->at(static_cast<std::size_t>(dt.month) - 1));
|
||||
break;
|
||||
case template_part::template_type::month_number:
|
||||
result.append(std::to_string(dt.month));
|
||||
|
@ -1684,15 +1688,15 @@ std::string number_formatter::format_number(const format_code &format, long doub
|
|||
break;
|
||||
|
||||
case template_part::template_type::month_letter:
|
||||
result.append(month_names->at(dt.month - 1).substr(0, 1));
|
||||
result.append(month_names->at(static_cast<std::size_t>(dt.month) - 1).substr(0, 1));
|
||||
break;
|
||||
|
||||
case template_part::template_type::day_abbreviation:
|
||||
result.append(day_names->at(dt.weekday() - 1).substr(0, 3));
|
||||
result.append(day_names->at(static_cast<std::size_t>(dt.weekday()) - 1).substr(0, 3));
|
||||
break;
|
||||
|
||||
case template_part::template_type::day_name:
|
||||
result.append(day_names->at(dt.weekday() - 1));
|
||||
result.append(day_names->at(static_cast<std::size_t>(dt.weekday()) - 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1736,8 +1740,32 @@ std::string number_formatter::format_text(const format_code &format, const std::
|
|||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case template_part::template_type::fill: break;
|
||||
case template_part::template_type::space: break;
|
||||
case template_part::template_type::month_number: break;
|
||||
case template_part::template_type::month_number_leading_zero: break;
|
||||
case template_part::template_type::month_abbreviation: break;
|
||||
case template_part::template_type::month_name: break;
|
||||
case template_part::template_type::month_letter: break;
|
||||
case template_part::template_type::day_number: break;
|
||||
case template_part::template_type::day_number_leading_zero: break;
|
||||
case template_part::template_type::day_abbreviation: break;
|
||||
case template_part::template_type::day_name: break;
|
||||
case template_part::template_type::year_short: break;
|
||||
case template_part::template_type::year_long: break;
|
||||
case template_part::template_type::hour: break;
|
||||
case template_part::template_type::hour_leading_zero: break;
|
||||
case template_part::template_type::minute: break;
|
||||
case template_part::template_type::minute_leading_zero: break;
|
||||
case template_part::template_type::second: break;
|
||||
case template_part::template_type::second_fractional: break;
|
||||
case template_part::template_type::second_leading_zero: break;
|
||||
case template_part::template_type::second_leading_zero_fractional: break;
|
||||
case template_part::template_type::am_pm: break;
|
||||
case template_part::template_type::a_p: break;
|
||||
case template_part::template_type::elapsed_hours: break;
|
||||
case template_part::template_type::elapsed_minutes: break;
|
||||
case template_part::template_type::elapsed_seconds: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,49 @@
|
|||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include "pole.h"
|
||||
#include <detail/pole.hpp>
|
||||
|
||||
// enable to activate debugging output
|
||||
// #define POLE_DEBUG
|
||||
|
||||
namespace {
|
||||
|
||||
// helper function: recursively find siblings of index
|
||||
void dirtree_find_siblings( POLE::DirTree* dirtree, std::vector<std::size_t>& result,
|
||||
std::size_t index )
|
||||
{
|
||||
auto e = dirtree->entry( index );
|
||||
if( !e ) return;
|
||||
if( !e->valid ) return;
|
||||
|
||||
// prevent infinite loop
|
||||
for( std::size_t i = 0; i < result.size(); i++ )
|
||||
if( result[i] == index ) return;
|
||||
|
||||
// add myself
|
||||
result.push_back( index );
|
||||
|
||||
// visit previous sibling, don't go infinitely
|
||||
std::size_t prev = e->prev;
|
||||
if( ( prev > 0 ) && ( prev < dirtree->entryCount() ) )
|
||||
{
|
||||
for( std::size_t i = 0; i < result.size(); i++ )
|
||||
if( result[i] == prev ) prev = 0;
|
||||
if( prev ) dirtree_find_siblings( dirtree, result, prev );
|
||||
}
|
||||
|
||||
// visit next sibling, don't go infinitely
|
||||
std::size_t next = e->next;
|
||||
if( ( next > 0 ) && ( next < dirtree->entryCount() ) )
|
||||
{
|
||||
for( std::size_t i = 0; i < result.size(); i++ )
|
||||
if( result[i] == next ) next = 0;
|
||||
if( next ) dirtree_find_siblings( dirtree, result, next );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace POLE
|
||||
{
|
||||
|
||||
|
@ -44,28 +82,28 @@ namespace POLE
|
|||
|
||||
using namespace POLE;
|
||||
|
||||
static inline std::uint16_t readU16( const std::uint8_t* ptr )
|
||||
static inline std::uint16_t readU16(const std::uint8_t* ptr)
|
||||
{
|
||||
return ptr[0]+(ptr[1]<<8);
|
||||
return static_cast<std::uint16_t>(ptr[0] + (ptr[1] << 8));
|
||||
}
|
||||
|
||||
static inline std::uint32_t readU32( const std::uint8_t* ptr )
|
||||
static inline std::uint32_t readU32(const std::uint8_t* ptr)
|
||||
{
|
||||
return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24);
|
||||
return static_cast<std::uint32_t>(ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24));
|
||||
}
|
||||
|
||||
static inline void writeU16( std::uint8_t* ptr, std::uint16_t data )
|
||||
{
|
||||
ptr[0] = (std::uint8_t)(data & 0xff);
|
||||
ptr[1] = (std::uint8_t)((data >> 8) & 0xff);
|
||||
ptr[0] = static_cast<std::uint8_t>(data & 0xff);
|
||||
ptr[1] = static_cast<std::uint8_t>((data >> 8) & 0xff);
|
||||
}
|
||||
|
||||
static inline void writeU32( std::uint8_t* ptr, std::uint32_t data )
|
||||
{
|
||||
ptr[0] = (std::uint8_t)(data & 0xff);
|
||||
ptr[1] = (std::uint8_t)((data >> 8) & 0xff);
|
||||
ptr[2] = (std::uint8_t)((data >> 16) & 0xff);
|
||||
ptr[3] = (std::uint8_t)((data >> 24) & 0xff);
|
||||
ptr[0] = static_cast<std::uint8_t>(data & 0xff);
|
||||
ptr[1] = static_cast<std::uint8_t>((data >> 8) & 0xff);
|
||||
ptr[2] = static_cast<std::uint8_t>((data >> 16) & 0xff);
|
||||
ptr[3] = static_cast<std::uint8_t>((data >> 24) & 0xff);
|
||||
}
|
||||
|
||||
static const std::uint8_t pole_magic[] =
|
||||
|
@ -243,9 +281,9 @@ std::vector<std::size_t> AllocTable::follow( std::size_t start )
|
|||
std::size_t p = start;
|
||||
while( p < count() )
|
||||
{
|
||||
if( p == (std::size_t)Eof ) break;
|
||||
if( p == (std::size_t)Bat ) break;
|
||||
if( p == (std::size_t)MetaBat ) break;
|
||||
if( p == static_cast<std::size_t>(Eof) ) break;
|
||||
if( p == static_cast<std::size_t>(Bat) ) break;
|
||||
if( p == static_cast<std::size_t>(MetaBat) ) break;
|
||||
if( already_exist(chain, p) ) break;
|
||||
chain.push_back(p);
|
||||
if( data[p] >= count() ) break;
|
||||
|
@ -332,14 +370,14 @@ std::size_t DirTree::entryCount()
|
|||
|
||||
DirEntry* DirTree::entry( std::size_t index )
|
||||
{
|
||||
if( index >= entryCount() ) return (DirEntry*) 0;
|
||||
if( index >= entryCount() ) return nullptr;
|
||||
return &entries[ index ];
|
||||
}
|
||||
|
||||
std::ptrdiff_t DirTree::indexOf( DirEntry* e )
|
||||
{
|
||||
for( std::size_t i = 0; i < entryCount(); i++ )
|
||||
if( entry( i ) == e ) return i;
|
||||
if( entry( i ) == e ) return static_cast<std::ptrdiff_t>(i);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -353,7 +391,7 @@ std::ptrdiff_t DirTree::parent( std::size_t index )
|
|||
std::vector<std::size_t> chi = children( j );
|
||||
for( std::size_t i=0; i<chi.size();i++ )
|
||||
if( chi[i] == index )
|
||||
return j;
|
||||
return static_cast<std::ptrdiff_t>(j);
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
@ -370,15 +408,15 @@ std::string DirTree::fullName( std::size_t index )
|
|||
DirEntry * _entry = 0;
|
||||
while( p > 0 )
|
||||
{
|
||||
_entry = entry( p );
|
||||
_entry = entry( static_cast<std::size_t>(p) );
|
||||
if (_entry->dir && _entry->valid)
|
||||
{
|
||||
result.insert( 0, _entry->name);
|
||||
result.insert( 0, "/" );
|
||||
}
|
||||
--p;
|
||||
index = p;
|
||||
if( index <= 0 ) break;
|
||||
index = static_cast<std::size_t>(p);
|
||||
if( p <= 0 ) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -388,7 +426,7 @@ std::string DirTree::fullName( std::size_t index )
|
|||
// if create is true, a new entry is returned
|
||||
DirEntry* DirTree::entry( const std::string& name, bool create )
|
||||
{
|
||||
if( !name.length() ) return (DirEntry*)0;
|
||||
if( !name.length() ) return nullptr;
|
||||
|
||||
// quick check for "/" (that's root)
|
||||
if( name == "/" ) return entry( 0 );
|
||||
|
@ -423,15 +461,15 @@ DirEntry* DirTree::entry( const std::string& name, bool create )
|
|||
if( ce )
|
||||
if( ce->valid && ( ce->name.length()>1 ) )
|
||||
if( ce->name == *it )
|
||||
child = chi[i];
|
||||
child = static_cast<std::ptrdiff_t>(chi[i]);
|
||||
}
|
||||
|
||||
// traverse to the child
|
||||
if( child > 0 ) index = child;
|
||||
if( child > 0 ) index = static_cast<std::size_t>(child);
|
||||
else
|
||||
{
|
||||
// not found among children
|
||||
if( !create ) return (DirEntry*)0;
|
||||
if( !create ) return nullptr;
|
||||
|
||||
// create a new entry
|
||||
std::size_t parent = index;
|
||||
|
@ -453,40 +491,6 @@ DirEntry* DirTree::entry( const std::string& name, bool create )
|
|||
return entry( index );
|
||||
}
|
||||
|
||||
// helper function: recursively find siblings of index
|
||||
void dirtree_find_siblings( DirTree* dirtree, std::vector<std::size_t>& result,
|
||||
std::size_t index )
|
||||
{
|
||||
DirEntry* e = dirtree->entry( index );
|
||||
if( !e ) return;
|
||||
if( !e->valid ) return;
|
||||
|
||||
// prevent infinite loop
|
||||
for( std::size_t i = 0; i < result.size(); i++ )
|
||||
if( result[i] == index ) return;
|
||||
|
||||
// add myself
|
||||
result.push_back( index );
|
||||
|
||||
// visit previous sibling, don't go infinitely
|
||||
std::size_t prev = e->prev;
|
||||
if( ( prev > 0 ) && ( prev < dirtree->entryCount() ) )
|
||||
{
|
||||
for( std::size_t i = 0; i < result.size(); i++ )
|
||||
if( result[i] == prev ) prev = 0;
|
||||
if( prev ) dirtree_find_siblings( dirtree, result, prev );
|
||||
}
|
||||
|
||||
// visit next sibling, don't go infinitely
|
||||
std::size_t next = e->next;
|
||||
if( ( next > 0 ) && ( next < dirtree->entryCount() ) )
|
||||
{
|
||||
for( std::size_t i = 0; i < result.size(); i++ )
|
||||
if( result[i] == next ) next = 0;
|
||||
if( next ) dirtree_find_siblings( dirtree, result, next );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::size_t> DirTree::children( std::size_t index )
|
||||
{
|
||||
std::vector<std::size_t> result;
|
||||
|
@ -511,10 +515,10 @@ void DirTree::load( std::uint8_t* buffer, std::size_t size )
|
|||
|
||||
// parse name of this entry, which stored as Unicode 16-bit
|
||||
std::string name;
|
||||
int name_len = readU16( buffer + 0x40+p );
|
||||
auto name_len = static_cast<std::size_t>(readU16( buffer + 0x40+p ));
|
||||
if( name_len > 64 ) name_len = 64;
|
||||
for( int j=0; ( buffer[j+p]) && (j<name_len); j+= 2 )
|
||||
name.append( 1, buffer[j+p] );
|
||||
for( std::size_t j=0; ( buffer[j+p]) && (j<name_len); j+= 2 )
|
||||
name.append( 1, static_cast<char>(buffer[j+p]) );
|
||||
|
||||
// first char isn't printable ? remove it...
|
||||
if( buffer[p] < 32 )
|
||||
|
@ -556,10 +560,10 @@ void DirTree::save( std::uint8_t* buffer )
|
|||
|
||||
// root is fixed as "Root Entry"
|
||||
DirEntry* root = entry( 0 );
|
||||
std::string name = "Root Entry";
|
||||
for( std::size_t j = 0; j < name.length(); j++ )
|
||||
buffer[ j*2 ] = name[j];
|
||||
writeU16( buffer + 0x40, static_cast<std::uint16_t>(name.length()*2 + 2) );
|
||||
std::string entry_name = "Root Entry";
|
||||
for( std::size_t j = 0; j < entry_name.length(); j++ )
|
||||
buffer[ j*2 ] = static_cast<std::uint8_t>(entry_name[j]);
|
||||
writeU16( buffer + 0x40, static_cast<std::uint16_t>(entry_name.length()*2 + 2) );
|
||||
writeU32( buffer + 0x74, 0xffffffff );
|
||||
writeU32( buffer + 0x78, 0 );
|
||||
writeU32( buffer + 0x44, 0xffffffff );
|
||||
|
@ -579,15 +583,15 @@ void DirTree::save( std::uint8_t* buffer )
|
|||
}
|
||||
|
||||
// max length for name is 32 chars
|
||||
std::string name = e->name;
|
||||
if( name.length() > 32 )
|
||||
name.erase( 32, name.length() );
|
||||
entry_name = e->name;
|
||||
if( entry_name.length() > 32 )
|
||||
entry_name.erase( 32, entry_name.length() );
|
||||
|
||||
// write name as Unicode 16-bit
|
||||
for( std::size_t j = 0; j < name.length(); j++ )
|
||||
buffer[ i*128 + j*2 ] = name[j];
|
||||
for( std::size_t j = 0; j < entry_name.length(); j++ )
|
||||
buffer[ i*128 + j*2 ] = static_cast<std::uint8_t>(entry_name[j]);
|
||||
|
||||
writeU16( buffer + i*128 + 0x40, static_cast<std::uint16_t>(name.length()*2 + 2) );
|
||||
writeU16( buffer + i*128 + 0x40, static_cast<std::uint16_t>(entry_name.length()*2 + 2) );
|
||||
writeU32( buffer + i*128 + 0x74, e->start );
|
||||
writeU32( buffer + i*128 + 0x78, e->size );
|
||||
writeU32( buffer + i*128 + 0x44, e->prev );
|
||||
|
@ -626,7 +630,7 @@ void DirTree::debug()
|
|||
|
||||
StorageIO::StorageIO( Storage* st, char* bytes, std::size_t length ):
|
||||
storage( st ),
|
||||
filedata((std::uint8_t *)bytes),
|
||||
filedata(reinterpret_cast<std::uint8_t *>(bytes)),
|
||||
dataLength(length),
|
||||
result( Storage::Ok ),
|
||||
opened( false ),
|
||||
|
@ -818,19 +822,19 @@ void StorageIO::close()
|
|||
StreamIO* StorageIO::streamIO( const std::string& name )
|
||||
{
|
||||
// sanity check
|
||||
if( !name.length() ) return (StreamIO*)0;
|
||||
if( !name.length() ) return nullptr;
|
||||
|
||||
// search in the entries
|
||||
DirEntry* entry = dirtree->entry( name );
|
||||
//if( entry) std::cout << "FOUND\n";
|
||||
if( !entry ) return (StreamIO*)0;
|
||||
if( !entry ) return nullptr;
|
||||
//if( !entry->dir ) std::cout << " NOT DIR\n";
|
||||
if( entry->dir ) return (StreamIO*)0;
|
||||
if( entry->dir ) return nullptr;
|
||||
|
||||
StreamIO* result = new StreamIO( this, entry );
|
||||
result->fullName = name;
|
||||
StreamIO* stream = new StreamIO( this, entry );
|
||||
stream->fullName = name;
|
||||
|
||||
return result;
|
||||
return stream;
|
||||
}
|
||||
|
||||
std::size_t StorageIO::loadBigBlocks( std::vector<std::size_t> blocks,
|
||||
|
@ -851,7 +855,7 @@ std::size_t StorageIO::loadBigBlocks( std::vector<std::size_t> blocks,
|
|||
if( pos + p > filesize ) p = filesize - pos;
|
||||
//FSTREAM file.seekg( pos );
|
||||
//FSTREAM file.read( (char*)data + bytes, p );
|
||||
memcpy((char*)data + bytes, filedata + pos, p);
|
||||
memcpy(reinterpret_cast<char *>(data) + bytes, filedata + pos, p);
|
||||
bytes += p;
|
||||
}
|
||||
|
||||
|
@ -1094,8 +1098,8 @@ std::list<std::string> Storage::entries( const std::string& path )
|
|||
DirEntry* e = dt->entry( path, false );
|
||||
if( e && e->dir )
|
||||
{
|
||||
std::size_t parent = dt->indexOf( e );
|
||||
std::vector<std::size_t> children = dt->children( parent );
|
||||
auto parent = dt->indexOf( e );
|
||||
std::vector<std::size_t> children = dt->children( static_cast<std::size_t>(parent) );
|
||||
for( std::size_t i = 0; i < children.size(); i++ )
|
||||
result.push_back( dt->entry( children[i] )->name );
|
||||
}
|
||||
|
@ -1127,8 +1131,8 @@ std::list<DirEntry*> Storage::dirEntries( const std::string& path )
|
|||
DirEntry* e = dt->entry( path, false );
|
||||
if( e && e->dir )
|
||||
{
|
||||
std::size_t parent = dt->indexOf( e );
|
||||
std::vector<std::size_t> children = dt->children( parent );
|
||||
auto parent = dt->indexOf( e );
|
||||
std::vector<std::size_t> children = dt->children( static_cast<std::size_t>(parent) );
|
||||
for( std::size_t i = 0; i < children.size(); i++ )
|
||||
result.push_back( dt->entry( children[i] ) );
|
||||
}
|
|
@ -23,8 +23,7 @@
|
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef POLE_H
|
||||
#define POLE_H
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
@ -36,7 +35,6 @@
|
|||
|
||||
namespace POLE
|
||||
{
|
||||
|
||||
class StorageIO;
|
||||
class Stream;
|
||||
class StreamIO;
|
||||
|
@ -353,6 +351,3 @@ namespace POLE
|
|||
};
|
||||
|
||||
} // namespace POLE
|
||||
|
||||
|
||||
#endif // POLE_H
|
|
@ -42,7 +42,7 @@ namespace detail {
|
|||
|
||||
struct stylesheet
|
||||
{
|
||||
format create_format()
|
||||
format create_format(bool default_format)
|
||||
{
|
||||
format_impls.push_back(format_impl());
|
||||
auto &impl = format_impls.back();
|
||||
|
@ -55,13 +55,15 @@ struct stylesheet
|
|||
impl.font_id = 0;
|
||||
impl.number_format_id = 0;
|
||||
|
||||
impl.references = default_format ? 1 : 0;
|
||||
|
||||
return format(&impl);
|
||||
}
|
||||
|
||||
format get_format(std::size_t index)
|
||||
{
|
||||
auto iter = format_impls.begin();
|
||||
std::advance(iter, index);
|
||||
std::advance(iter, static_cast<std::list<format_impl>::difference_type>(index));
|
||||
return format(&*iter);
|
||||
}
|
||||
|
||||
|
@ -142,7 +144,7 @@ struct stylesheet
|
|||
|
||||
if (reference_counts.count(i) == 0 || reference_counts.at(i) == 0)
|
||||
{
|
||||
container.erase(container.begin() + i - unreferenced);
|
||||
container.erase(container.begin() + static_cast<typename std::vector<T>::difference_type>(i - unreferenced));
|
||||
unreferenced++;
|
||||
}
|
||||
}
|
||||
|
@ -150,40 +152,24 @@ struct stylesheet
|
|||
return id_map;
|
||||
}
|
||||
|
||||
void garbage_collect(std::size_t new_format, std::size_t old_format)
|
||||
void garbage_collect()
|
||||
{
|
||||
if (!garbage_collection_enabled) return;
|
||||
|
||||
std::unordered_map<std::size_t, std::size_t> format_reference_counts;
|
||||
auto format_iter = format_impls.begin();
|
||||
|
||||
for (const auto &impl : format_impls)
|
||||
while (format_iter != format_impls.end())
|
||||
{
|
||||
format_reference_counts[impl.id] = 0;
|
||||
auto &impl = *format_iter;
|
||||
|
||||
if (impl.references != 0)
|
||||
{
|
||||
++format_iter;
|
||||
}
|
||||
|
||||
format_reference_counts[new_format]++;
|
||||
|
||||
parent->apply_to_cells([&format_reference_counts](cell c)
|
||||
else
|
||||
{
|
||||
if (c.has_format())
|
||||
{
|
||||
format_reference_counts[c.format().id()]++;
|
||||
format_iter = format_impls.erase(format_iter);
|
||||
}
|
||||
});
|
||||
|
||||
if (format_reference_counts[old_format] > 0)
|
||||
{
|
||||
format_reference_counts[old_format]--;
|
||||
}
|
||||
|
||||
for (const auto &id_count_pair : format_reference_counts)
|
||||
{
|
||||
if (id_count_pair.second != 0) continue;
|
||||
|
||||
auto target_id = id_count_pair.first;
|
||||
auto target = std::find_if(format_impls.begin(), format_impls.end(),
|
||||
[=](const format_impl &impl) { return impl.id == target_id; });
|
||||
format_impls.erase(target);
|
||||
}
|
||||
|
||||
std::size_t new_id = 0;
|
||||
|
@ -195,6 +181,9 @@ struct stylesheet
|
|||
std::unordered_map<std::size_t, std::size_t> number_format_reference_counts;
|
||||
std::unordered_map<std::size_t, std::size_t> protection_reference_counts;
|
||||
|
||||
fill_reference_counts[0]++;
|
||||
fill_reference_counts[1]++;
|
||||
|
||||
for (auto &impl : format_impls)
|
||||
{
|
||||
impl.id = new_id++;
|
||||
|
@ -269,7 +258,6 @@ struct stylesheet
|
|||
auto border_id_map = garbage_collect(border_reference_counts, borders);
|
||||
auto fill_id_map = garbage_collect(fill_reference_counts, fills);
|
||||
auto font_id_map = garbage_collect(font_reference_counts, fonts);
|
||||
auto number_format_id_map = garbage_collect(number_format_reference_counts, number_formats);
|
||||
auto protection_id_map = garbage_collect(protection_reference_counts, protections);
|
||||
|
||||
for (auto &impl : format_impls)
|
||||
|
@ -294,9 +282,34 @@ struct stylesheet
|
|||
impl.font_id = font_id_map[impl.font_id.get()];
|
||||
}
|
||||
|
||||
if (impl.number_format_id.is_set())
|
||||
if (impl.protection_id.is_set())
|
||||
{
|
||||
impl.number_format_id = number_format_id_map[impl.number_format_id.get()];
|
||||
impl.protection_id = protection_id_map[impl.protection_id.get()];
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &name_impl : style_impls)
|
||||
{
|
||||
auto &impl = name_impl.second;
|
||||
|
||||
if (impl.alignment_id.is_set())
|
||||
{
|
||||
impl.alignment_id = alignment_id_map[impl.alignment_id.get()];
|
||||
}
|
||||
|
||||
if (impl.border_id.is_set())
|
||||
{
|
||||
impl.border_id = border_id_map[impl.border_id.get()];
|
||||
}
|
||||
|
||||
if (impl.fill_id.is_set())
|
||||
{
|
||||
impl.fill_id = fill_id_map[impl.fill_id.get()];
|
||||
}
|
||||
|
||||
if (impl.font_id.is_set())
|
||||
{
|
||||
impl.font_id = font_id_map[impl.font_id.get()];
|
||||
}
|
||||
|
||||
if (impl.protection_id.is_set())
|
||||
|
@ -306,11 +319,11 @@ struct stylesheet
|
|||
}
|
||||
}
|
||||
|
||||
format_impl *find_or_create(const format_impl &pattern)
|
||||
format_impl *find_or_create(format_impl &pattern)
|
||||
{
|
||||
auto iter = format_impls.begin();
|
||||
auto id = find_or_add(format_impls, pattern);
|
||||
std::advance(iter, id);
|
||||
std::advance(iter, static_cast<std::list<format_impl>::difference_type>(id));
|
||||
|
||||
auto &result = *iter;
|
||||
|
||||
|
@ -319,12 +332,22 @@ struct stylesheet
|
|||
|
||||
if (id != pattern.id)
|
||||
{
|
||||
garbage_collect(id, pattern.id);
|
||||
pattern.references -= pattern.references > 0 ? 1 : 0;
|
||||
++result.references;
|
||||
garbage_collect();
|
||||
}
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
format_impl *find_or_create_with(format_impl *pattern, const std::string &style_name)
|
||||
{
|
||||
format_impl new_format = *pattern;
|
||||
new_format.style = style_name;
|
||||
|
||||
return find_or_create(new_format);
|
||||
}
|
||||
|
||||
format_impl *find_or_create_with(format_impl *pattern, const alignment &new_alignment, bool applied)
|
||||
{
|
||||
format_impl new_format = *pattern;
|
||||
|
@ -381,8 +404,8 @@ struct stylesheet
|
|||
|
||||
std::size_t style_index(const std::string &name) const
|
||||
{
|
||||
return std::distance(style_names.begin(),
|
||||
std::find(style_names.begin(), style_names.end(), name));
|
||||
return static_cast<std::size_t>(std::distance(style_names.begin(),
|
||||
std::find(style_names.begin(), style_names.end(), name)));
|
||||
}
|
||||
|
||||
void clear()
|
||||
|
@ -402,16 +425,6 @@ struct stylesheet
|
|||
colors.clear();
|
||||
}
|
||||
|
||||
void enable_garbage_collection()
|
||||
{
|
||||
garbage_collection_enabled = true;
|
||||
}
|
||||
|
||||
void disable_garbage_collection()
|
||||
{
|
||||
garbage_collection_enabled = false;
|
||||
}
|
||||
|
||||
workbook *parent;
|
||||
|
||||
bool garbage_collection_enabled = true;
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
|
||||
/// <summary>
|
||||
/// Allows a std::vector to be read through a std::istream.
|
||||
/// </summary>
|
||||
|
@ -160,7 +163,7 @@ private:
|
|||
{
|
||||
if (c != traits_type::eof())
|
||||
{
|
||||
data_.push_back(c);
|
||||
data_.push_back(static_cast<std::uint8_t>(c));
|
||||
position_ = data_.size() - 1;
|
||||
}
|
||||
|
||||
|
@ -248,5 +251,7 @@ private:
|
|||
std::size_t position_;
|
||||
};
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -109,7 +109,7 @@ std::vector<xlnt::relationship> read_relationships(const xlnt::path &part, xlnt:
|
|||
|
||||
xlnt::uri source(part.string());
|
||||
|
||||
const auto xmlns = xlnt::constants::get_namespace("relationships");
|
||||
static const auto &xmlns = xlnt::constants::get_namespace("relationships");
|
||||
parser.next_expect(xml::parser::event_type::start_element, xmlns, "Relationships");
|
||||
parser.content(xml::content::complex);
|
||||
|
||||
|
@ -221,8 +221,30 @@ void xlsx_consumer::populate_workbook()
|
|||
read_volatile_dependencies();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case relationship::type::thumbnail: break;
|
||||
case relationship::type::calculation_chain: break;
|
||||
case relationship::type::worksheet: break;
|
||||
case relationship::type::shared_string_table: break;
|
||||
case relationship::type::styles: break;
|
||||
case relationship::type::theme: break;
|
||||
case relationship::type::hyperlink: break;
|
||||
case relationship::type::chartsheet: break;
|
||||
case relationship::type::comments: break;
|
||||
case relationship::type::vml_drawing: break;
|
||||
case relationship::type::unknown: break;
|
||||
case relationship::type::printer_settings: break;
|
||||
case relationship::type::custom_property: break;
|
||||
case relationship::type::dialogsheet: break;
|
||||
case relationship::type::drawings: break;
|
||||
case relationship::type::pivot_table_cache_definition: break;
|
||||
case relationship::type::pivot_table_cache_records: break;
|
||||
case relationship::type::query_table: break;
|
||||
case relationship::type::shared_workbook: break;
|
||||
case relationship::type::revision_log: break;
|
||||
case relationship::type::shared_workbook_user_data: break;
|
||||
case relationship::type::single_cell_table_definitions: break;
|
||||
case relationship::type::table_definition: break;
|
||||
case relationship::type::image: break;
|
||||
}
|
||||
|
||||
parser_ = nullptr;
|
||||
|
@ -235,9 +257,12 @@ void xlsx_consumer::populate_workbook()
|
|||
for (const auto &rel : manifest.get_relationships(workbook_rel.get_target().get_path()))
|
||||
{
|
||||
path part_path(rel.get_source().get_path().parent().append(rel.get_target().get_path()));
|
||||
auto receive = xml::parser::receive_default;
|
||||
auto using_namespaces = rel.get_type() == relationship::type::styles;
|
||||
auto receive = xml::parser::receive_default
|
||||
| (using_namespaces ? xml::parser::receive_namespace_decls : 0);
|
||||
if (using_namespaces)
|
||||
{
|
||||
receive |= xml::parser::receive_namespace_decls;
|
||||
}
|
||||
xml::parser parser(archive_->open(part_path.string()), part_path.string(), receive);
|
||||
parser_ = &parser;
|
||||
|
||||
|
@ -255,8 +280,38 @@ void xlsx_consumer::populate_workbook()
|
|||
read_theme();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case relationship::type::office_document: break;
|
||||
case relationship::type::thumbnail: break;
|
||||
case relationship::type::calculation_chain: break;
|
||||
case relationship::type::extended_properties: break;
|
||||
case relationship::type::core_properties: break;
|
||||
case relationship::type::worksheet: break;
|
||||
case relationship::type::hyperlink: break;
|
||||
case relationship::type::chartsheet: break;
|
||||
case relationship::type::comments: break;
|
||||
case relationship::type::vml_drawing: break;
|
||||
case relationship::type::unknown: break;
|
||||
case relationship::type::custom_properties: break;
|
||||
case relationship::type::printer_settings: break;
|
||||
case relationship::type::connections: break;
|
||||
case relationship::type::custom_property: break;
|
||||
case relationship::type::custom_xml_mappings: break;
|
||||
case relationship::type::dialogsheet: break;
|
||||
case relationship::type::drawings: break;
|
||||
case relationship::type::external_workbook_references: break;
|
||||
case relationship::type::metadata: break;
|
||||
case relationship::type::pivot_table: break;
|
||||
case relationship::type::pivot_table_cache_definition: break;
|
||||
case relationship::type::pivot_table_cache_records: break;
|
||||
case relationship::type::query_table: break;
|
||||
case relationship::type::shared_workbook_revision_headers: break;
|
||||
case relationship::type::shared_workbook: break;
|
||||
case relationship::type::revision_log: break;
|
||||
case relationship::type::shared_workbook_user_data: break;
|
||||
case relationship::type::single_cell_table_definitions: break;
|
||||
case relationship::type::table_definition: break;
|
||||
case relationship::type::volatile_dependencies: break;
|
||||
case relationship::type::image: break;
|
||||
}
|
||||
|
||||
parser_ = nullptr;
|
||||
|
@ -267,7 +322,8 @@ void xlsx_consumer::populate_workbook()
|
|||
for (const auto &rel : manifest.get_relationships(workbook_rel.get_target().get_path()))
|
||||
{
|
||||
path part_path(rel.get_source().get_path().parent().append(rel.get_target().get_path()));
|
||||
auto receive = xml::parser::receive_default | xml::parser::receive_namespace_decls;
|
||||
auto receive = xml::parser::receive_default;
|
||||
receive |= xml::parser::receive_namespace_decls;
|
||||
xml::parser parser(archive_->open(part_path.string()), rel.get_target().get_path().string(), receive);
|
||||
parser_ = &parser;
|
||||
|
||||
|
@ -285,8 +341,38 @@ void xlsx_consumer::populate_workbook()
|
|||
read_worksheet(rel.get_id());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case relationship::type::office_document: break;
|
||||
case relationship::type::thumbnail: break;
|
||||
case relationship::type::calculation_chain: break;
|
||||
case relationship::type::extended_properties: break;
|
||||
case relationship::type::core_properties: break;
|
||||
case relationship::type::shared_string_table: break;
|
||||
case relationship::type::styles: break;
|
||||
case relationship::type::theme: break;
|
||||
case relationship::type::hyperlink: break;
|
||||
case relationship::type::comments: break;
|
||||
case relationship::type::vml_drawing: break;
|
||||
case relationship::type::unknown: break;
|
||||
case relationship::type::custom_properties: break;
|
||||
case relationship::type::printer_settings: break;
|
||||
case relationship::type::connections: break;
|
||||
case relationship::type::custom_property: break;
|
||||
case relationship::type::custom_xml_mappings: break;
|
||||
case relationship::type::drawings: break;
|
||||
case relationship::type::external_workbook_references: break;
|
||||
case relationship::type::metadata: break;
|
||||
case relationship::type::pivot_table: break;
|
||||
case relationship::type::pivot_table_cache_definition: break;
|
||||
case relationship::type::pivot_table_cache_records: break;
|
||||
case relationship::type::query_table: break;
|
||||
case relationship::type::shared_workbook_revision_headers: break;
|
||||
case relationship::type::shared_workbook: break;
|
||||
case relationship::type::revision_log: break;
|
||||
case relationship::type::shared_workbook_user_data: break;
|
||||
case relationship::type::single_cell_table_definitions: break;
|
||||
case relationship::type::table_definition: break;
|
||||
case relationship::type::volatile_dependencies: break;
|
||||
case relationship::type::image: break;
|
||||
}
|
||||
|
||||
parser_ = nullptr;
|
||||
|
@ -312,7 +398,7 @@ void xlsx_consumer::read_manifest()
|
|||
auto package_rels = read_relationships(package_rels_path, *archive_);
|
||||
auto &manifest = target_.get_manifest();
|
||||
|
||||
static const auto xmlns = constants::get_namespace("content-types");
|
||||
static const auto &xmlns = constants::get_namespace("content-types");
|
||||
|
||||
xml::parser parser(archive_->open("[Content_Types].xml"), "[Content_Types].xml");
|
||||
parser.next_expect(xml::parser::event_type::start_element, xmlns, "Types");
|
||||
|
@ -364,7 +450,7 @@ void xlsx_consumer::read_manifest()
|
|||
|
||||
auto part_rels = read_relationships(relationship_source, *archive_);
|
||||
|
||||
for (const auto part_rel : part_rels)
|
||||
for (const auto &part_rel : part_rels)
|
||||
{
|
||||
path target_path(source_directory.append(part_rel.get_target().get_path()));
|
||||
manifest.register_relationship(source, part_rel.get_type(),
|
||||
|
@ -375,8 +461,8 @@ void xlsx_consumer::read_manifest()
|
|||
|
||||
void xlsx_consumer::read_extended_properties()
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("extended-properties");
|
||||
static const auto xmlns_vt = constants::get_namespace("vt");
|
||||
static const auto &xmlns = constants::get_namespace("extended-properties");
|
||||
static const auto &xmlns_vt = constants::get_namespace("vt");
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "Properties");
|
||||
parser().content(xml::parser::content_type::complex);
|
||||
|
@ -459,11 +545,10 @@ void xlsx_consumer::read_extended_properties()
|
|||
|
||||
void xlsx_consumer::read_core_properties()
|
||||
{
|
||||
static const auto xmlns_cp = constants::get_namespace("core-properties");
|
||||
static const auto xmlns_dc = constants::get_namespace("dc");
|
||||
static const auto xmlns_dcterms = constants::get_namespace("dcterms");
|
||||
static const auto xmlns_dcmitype = constants::get_namespace("dcmitype");
|
||||
static const auto xmlns_xsi = constants::get_namespace("xsi");
|
||||
static const auto &xmlns_cp = constants::get_namespace("core-properties");
|
||||
static const auto &xmlns_dc = constants::get_namespace("dc");
|
||||
static const auto &xmlns_dcterms = constants::get_namespace("dcterms");
|
||||
static const auto &xmlns_xsi = constants::get_namespace("xsi");
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns_cp, "coreProperties");
|
||||
parser().content(xml::parser::content_type::complex);
|
||||
|
@ -514,13 +599,13 @@ void xlsx_consumer::read_custom_file_properties()
|
|||
|
||||
void xlsx_consumer::read_workbook()
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("workbook");
|
||||
static const auto xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto xmlns_mx = constants::get_namespace("mx");
|
||||
static const auto xmlns_r = constants::get_namespace("r");
|
||||
static const auto xmlns_s = constants::get_namespace("worksheet");
|
||||
static const auto xmlns_x15 = constants::get_namespace("x15");
|
||||
static const auto xmlns_x15ac = constants::get_namespace("x15ac");
|
||||
static const auto &xmlns = constants::get_namespace("workbook");
|
||||
static const auto &xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto &xmlns_mx = constants::get_namespace("mx");
|
||||
static const auto &xmlns_r = constants::get_namespace("r");
|
||||
static const auto &xmlns_s = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns_x15 = constants::get_namespace("x15");
|
||||
static const auto &xmlns_x15ac = constants::get_namespace("x15ac");
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "workbook");
|
||||
parser().content(xml::parser::content_type::complex);
|
||||
|
@ -809,7 +894,7 @@ void xlsx_consumer::read_pivot_table()
|
|||
|
||||
void xlsx_consumer::read_shared_string_table()
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns = constants::get_namespace("worksheet");
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "sst");
|
||||
parser().content(xml::content::complex);
|
||||
|
@ -916,11 +1001,11 @@ void xlsx_consumer::read_shared_workbook_user_data()
|
|||
|
||||
void xlsx_consumer::read_stylesheet()
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
static const auto xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto xmlns_x14 = constants::get_namespace("x14");
|
||||
static const auto xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
static const auto xmlns_x15 = constants::get_namespace("x15");
|
||||
static const auto &xmlns = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto &xmlns_x14 = constants::get_namespace("x14");
|
||||
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
static const auto &xmlns_x15 = constants::get_namespace("x15");
|
||||
|
||||
auto &stylesheet = target_.impl().stylesheet_;
|
||||
|
||||
|
@ -1560,6 +1645,8 @@ void xlsx_consumer::read_stylesheet()
|
|||
new_format.id = record_index++;
|
||||
new_format.parent = &stylesheet;
|
||||
|
||||
++new_format.references;
|
||||
|
||||
if (record.style_id.second)
|
||||
{
|
||||
new_format.style = stylesheet.style_names[record.style_id.first];
|
||||
|
@ -1591,10 +1678,10 @@ void xlsx_consumer::read_volatile_dependencies()
|
|||
|
||||
void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
static const auto xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto xmlns_r = constants::get_namespace("r");
|
||||
static const auto xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
static const auto &xmlns = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto &xmlns_r = constants::get_namespace("r");
|
||||
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
|
||||
auto title = std::find_if(target_.d_->sheet_title_rel_id_map_.begin(),
|
||||
target_.d_->sheet_title_rel_id_map_.end(),
|
||||
|
@ -2033,8 +2120,40 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
read_comments(ws);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case relationship::type::office_document: break;
|
||||
case relationship::type::thumbnail: break;
|
||||
case relationship::type::calculation_chain: break;
|
||||
case relationship::type::extended_properties: break;
|
||||
case relationship::type::core_properties: break;
|
||||
case relationship::type::worksheet: break;
|
||||
case relationship::type::shared_string_table: break;
|
||||
case relationship::type::styles: break;
|
||||
case relationship::type::theme: break;
|
||||
case relationship::type::hyperlink: break;
|
||||
case relationship::type::chartsheet: break;
|
||||
case relationship::type::vml_drawing: break;
|
||||
case relationship::type::unknown: break;
|
||||
case relationship::type::custom_properties: break;
|
||||
case relationship::type::printer_settings: break;
|
||||
case relationship::type::connections: break;
|
||||
case relationship::type::custom_property: break;
|
||||
case relationship::type::custom_xml_mappings: break;
|
||||
case relationship::type::dialogsheet: break;
|
||||
case relationship::type::drawings: break;
|
||||
case relationship::type::external_workbook_references: break;
|
||||
case relationship::type::metadata: break;
|
||||
case relationship::type::pivot_table: break;
|
||||
case relationship::type::pivot_table_cache_definition: break;
|
||||
case relationship::type::pivot_table_cache_records: break;
|
||||
case relationship::type::query_table: break;
|
||||
case relationship::type::shared_workbook_revision_headers: break;
|
||||
case relationship::type::shared_workbook: break;
|
||||
case relationship::type::revision_log: break;
|
||||
case relationship::type::shared_workbook_user_data: break;
|
||||
case relationship::type::single_cell_table_definitions: break;
|
||||
case relationship::type::table_definition: break;
|
||||
case relationship::type::volatile_dependencies: break;
|
||||
case relationship::type::image: break;
|
||||
}
|
||||
|
||||
parser_ = nullptr;
|
||||
|
@ -2045,7 +2164,7 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
|
||||
void xlsx_consumer::read_comments(worksheet ws)
|
||||
{
|
||||
static const auto xmlns = xlnt::constants::get_namespace("worksheet");
|
||||
static const auto &xmlns = xlnt::constants::get_namespace("worksheet");
|
||||
|
||||
std::vector<std::string> authors;
|
||||
|
||||
|
|
|
@ -20,11 +20,13 @@
|
|||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <array>
|
||||
#include <pole.h>
|
||||
#include <botan_all.h>
|
||||
#include <include_libstudxml.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/include_botan.hpp>
|
||||
#include <detail/include_libstudxml.hpp>
|
||||
#include <detail/pole.hpp>
|
||||
#include <detail/vector_streambuf.hpp>
|
||||
#include <detail/xlsx_consumer.hpp>
|
||||
#include <detail/xlsx_producer.hpp>
|
||||
|
@ -34,6 +36,66 @@
|
|||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
enum class hash_algorithm
|
||||
{
|
||||
sha1,
|
||||
sha256,
|
||||
sha384,
|
||||
sha512,
|
||||
md5,
|
||||
md4,
|
||||
md2,
|
||||
ripemd128,
|
||||
ripemd160,
|
||||
whirlpool
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
||||
|
||||
namespace xml {
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::detail::hash_algorithm>
|
||||
{
|
||||
static xlnt::detail::hash_algorithm parse(std::string hash_algorithm_string, const parser &)
|
||||
{
|
||||
if (hash_algorithm_string == "SHA1") return xlnt::detail::hash_algorithm::sha1;
|
||||
else if (hash_algorithm_string == "SHA256") return xlnt::detail::hash_algorithm::sha256;
|
||||
else if (hash_algorithm_string == "SHA384") return xlnt::detail::hash_algorithm::sha384;
|
||||
else if (hash_algorithm_string == "SHA512") return xlnt::detail::hash_algorithm::sha512;
|
||||
else if (hash_algorithm_string == "MD5") return xlnt::detail::hash_algorithm::md5;
|
||||
else if (hash_algorithm_string == "MD4") return xlnt::detail::hash_algorithm::md4;
|
||||
else if (hash_algorithm_string == "MD2") return xlnt::detail::hash_algorithm::md2;
|
||||
else if (hash_algorithm_string == "Ripemd128") return xlnt::detail::hash_algorithm::ripemd128;
|
||||
else if (hash_algorithm_string == "Ripemd160") return xlnt::detail::hash_algorithm::ripemd160;
|
||||
else if (hash_algorithm_string == "Whirlpool") return xlnt::detail::hash_algorithm::whirlpool;
|
||||
throw xlnt::exception(hash_algorithm_string);
|
||||
}
|
||||
|
||||
static std::string serialize(xlnt::detail::hash_algorithm algorithm, const serializer &)
|
||||
{
|
||||
switch (algorithm)
|
||||
{
|
||||
case xlnt::detail::hash_algorithm::sha1: return "SHA1";
|
||||
case xlnt::detail::hash_algorithm::sha256: return "SHA256";
|
||||
case xlnt::detail::hash_algorithm::sha384: return "SHA384";
|
||||
case xlnt::detail::hash_algorithm::sha512: return "SHA512";
|
||||
case xlnt::detail::hash_algorithm::md5: return "MD5";
|
||||
case xlnt::detail::hash_algorithm::md4: return "MD4";
|
||||
case xlnt::detail::hash_algorithm::md2: return "MD2";
|
||||
case xlnt::detail::hash_algorithm::ripemd128: return "Ripemd128";
|
||||
case xlnt::detail::hash_algorithm::ripemd160: return "Ripemd160";
|
||||
case xlnt::detail::hash_algorithm::whirlpool: return "Whirlpool";
|
||||
}
|
||||
}
|
||||
}; // struct value_traits<>
|
||||
|
||||
} // namespace xml
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
struct crypto_helper
|
||||
{
|
||||
static const std::size_t segment_length = 4096;
|
||||
|
@ -62,20 +124,6 @@ struct crypto_helper
|
|||
decryption
|
||||
};
|
||||
|
||||
enum class hash_algorithm
|
||||
{
|
||||
sha1,
|
||||
sha256,
|
||||
sha384,
|
||||
sha512,
|
||||
md5,
|
||||
md4,
|
||||
md2,
|
||||
ripemd128,
|
||||
ripemd160,
|
||||
whirlpool
|
||||
};
|
||||
|
||||
static std::vector<std::uint8_t> aes(const std::vector<std::uint8_t> &key,
|
||||
const std::vector<std::uint8_t> &iv,
|
||||
const std::vector<std::uint8_t> &encrypted,
|
||||
|
@ -104,6 +152,15 @@ struct crypto_helper
|
|||
return std::vector<std::uint8_t>(decoded.begin(), decoded.end());
|
||||
}
|
||||
|
||||
static std::string encode_base64(const std::vector<std::uint8_t> &decoded)
|
||||
{
|
||||
Botan::Pipe pipe(new Botan::Base64_Encoder);
|
||||
pipe.process_msg(decoded);
|
||||
auto encoded = pipe.read_all();
|
||||
|
||||
return std::string(encoded.begin(), encoded.end());
|
||||
}
|
||||
|
||||
static std::vector<std::uint8_t> hash(hash_algorithm algorithm,
|
||||
const std::vector<std::uint8_t> &input)
|
||||
{
|
||||
|
@ -276,7 +333,7 @@ struct crypto_helper
|
|||
//todo: verify here
|
||||
|
||||
std::size_t package_offset = 0;
|
||||
auto decrypted_size = read_int<std::uint64_t>(package_offset, encrypted_package);
|
||||
auto decrypted_size = static_cast<std::size_t>(read_int<std::uint64_t>(package_offset, encrypted_package));
|
||||
auto decrypted = aes(key_derived, {}, std::vector<std::uint8_t>(
|
||||
encrypted_package.begin() + 8, encrypted_package.end()),
|
||||
cipher_chaining::ecb, cipher_direction::decryption);
|
||||
|
@ -323,12 +380,74 @@ struct crypto_helper
|
|||
} key_encryptor;
|
||||
};
|
||||
|
||||
static agile_encryption_info generate_agile_encryption_info(const std::string &password)
|
||||
{
|
||||
agile_encryption_info result;
|
||||
result.key_data.salt_value.assign(password.begin(), password.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::vector<std::uint8_t> write_agile_encryption_info(const std::string &password)
|
||||
{
|
||||
static const auto &xmlns = xlnt::constants::get_namespace("encryption");
|
||||
static const auto &xmlns_p = xlnt::constants::get_namespace("encryption-password");
|
||||
|
||||
std::vector<std::uint8_t> encryption_info;
|
||||
xlnt::detail::vector_ostreambuf encryption_info_buffer(encryption_info);
|
||||
std::ostream encryption_info_stream(&encryption_info_buffer);
|
||||
xml::serializer serializer(encryption_info_stream, "EncryptionInfo");
|
||||
|
||||
agile_encryption_info result = generate_agile_encryption_info(password);
|
||||
|
||||
serializer.start_element(xmlns, "encryption");
|
||||
|
||||
serializer.start_element(xmlns, "keyData");
|
||||
serializer.attribute("saltSize", result.key_data.salt_size);
|
||||
serializer.attribute("blockSize", result.key_data.block_size);
|
||||
serializer.attribute("keyBits", result.key_data.key_bits);
|
||||
serializer.attribute("hashSize", result.key_data.hash_size);
|
||||
serializer.attribute("cipherAlgorithm", result.key_data.cipher_algorithm);
|
||||
serializer.attribute("cipherChaining", result.key_data.cipher_chaining);
|
||||
serializer.attribute("hashAlgorithm", result.key_data.hash_algorithm);
|
||||
serializer.attribute("saltValue", encode_base64(result.key_data.salt_value));
|
||||
serializer.end_element(xmlns, "keyData");
|
||||
|
||||
serializer.start_element(xmlns, "dataIntegrity");
|
||||
serializer.attribute("encryptedHmacKey", encode_base64(result.data_integrity.hmac_key));
|
||||
serializer.attribute("encryptedHmacValue", encode_base64(result.data_integrity.hmac_value));
|
||||
serializer.end_element(xmlns, "dataIntegrity");
|
||||
|
||||
serializer.start_element(xmlns, "keyEncryptors");
|
||||
serializer.start_element(xmlns, "keyEncryptor");
|
||||
serializer.attribute("uri", "");
|
||||
serializer.start_element(xmlns_p, "encryptedKey");
|
||||
serializer.attribute("spinCount", result.key_encryptor.spin_count);
|
||||
serializer.attribute("saltSize", result.key_encryptor.salt_size);
|
||||
serializer.attribute("blockSize", result.key_encryptor.block_size);
|
||||
serializer.attribute("keyBits", result.key_encryptor.key_bits);
|
||||
serializer.attribute("hashSize", result.key_encryptor.hash_size);
|
||||
serializer.attribute("cipherAlgorithm", result.key_encryptor.cipher_algorithm);
|
||||
serializer.attribute("cipherChaining", result.key_encryptor.cipher_chaining);
|
||||
serializer.attribute("hashAlgorithm", result.key_encryptor.hash);
|
||||
serializer.attribute("saltValue", encode_base64(result.key_encryptor.salt_value));
|
||||
serializer.attribute("encryptedVerifierHashInput", encode_base64(result.key_encryptor.verifier_hash_input));
|
||||
serializer.attribute("encryptedVerifierHashValue", encode_base64(result.key_encryptor.verifier_hash_value));
|
||||
serializer.attribute("encryptedKeyValue", encode_base64(result.key_encryptor.encrypted_key_value));
|
||||
serializer.end_element(xmlns_p, "encryptedKey");
|
||||
serializer.end_element(xmlns, "keyEncryptor");
|
||||
serializer.end_element(xmlns, "keyEncryptors");
|
||||
|
||||
serializer.end_element(xmlns, "encryption");
|
||||
|
||||
return encryption_info;
|
||||
}
|
||||
|
||||
static std::vector<std::uint8_t> decrypt_xlsx_agile(const std::vector<std::uint8_t> &encryption_info,
|
||||
const std::string &password, const std::vector<std::uint8_t> &encrypted_package)
|
||||
{
|
||||
static const auto xmlns = std::string("http://schemas.microsoft.com/office/2006/encryption");
|
||||
static const auto xmlns_p = std::string("http://schemas.microsoft.com/office/2006/keyEncryptor/password");
|
||||
static const auto xmlns_c = std::string("http://schemas.microsoft.com/office/2006/keyEncryptor/certificate");
|
||||
static const auto &xmlns = xlnt::constants::get_namespace("encryption");
|
||||
static const auto &xmlns_p = xlnt::constants::get_namespace("encryption-password");
|
||||
//static const auto &xmlns_c = xlnt::constants::get_namespace("encryption-certificate");
|
||||
|
||||
agile_encryption_info result;
|
||||
|
||||
|
@ -585,6 +704,8 @@ struct crypto_helper
|
|||
throw xlnt::exception("empty file");
|
||||
}
|
||||
|
||||
generate_agile_encryption_info(password);
|
||||
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -52,7 +52,7 @@ const bool skip_unknown_elements = true;
|
|||
/// </summary>
|
||||
bool is_integral(long double d)
|
||||
{
|
||||
return d == static_cast<long long int>(d);
|
||||
return std::fabs(d - static_cast<long double>(static_cast<long long int>(d))) == 0.L;
|
||||
}
|
||||
|
||||
std::string fill(const std::string &string, std::size_t length = 2)
|
||||
|
@ -129,8 +129,37 @@ void xlsx_producer::populate_archive()
|
|||
write_workbook(rel);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case relationship::type::thumbnail: break;
|
||||
case relationship::type::calculation_chain: break;
|
||||
case relationship::type::worksheet: break;
|
||||
case relationship::type::shared_string_table: break;
|
||||
case relationship::type::styles: break;
|
||||
case relationship::type::theme: break;
|
||||
case relationship::type::hyperlink: break;
|
||||
case relationship::type::chartsheet: break;
|
||||
case relationship::type::comments: break;
|
||||
case relationship::type::vml_drawing: break;
|
||||
case relationship::type::unknown: break;
|
||||
case relationship::type::printer_settings: break;
|
||||
case relationship::type::connections: break;
|
||||
case relationship::type::custom_property: break;
|
||||
case relationship::type::custom_xml_mappings: break;
|
||||
case relationship::type::dialogsheet: break;
|
||||
case relationship::type::drawings: break;
|
||||
case relationship::type::external_workbook_references: break;
|
||||
case relationship::type::metadata: break;
|
||||
case relationship::type::pivot_table: break;
|
||||
case relationship::type::pivot_table_cache_definition: break;
|
||||
case relationship::type::pivot_table_cache_records: break;
|
||||
case relationship::type::query_table: break;
|
||||
case relationship::type::shared_workbook_revision_headers: break;
|
||||
case relationship::type::shared_workbook: break;
|
||||
case relationship::type::revision_log: break;
|
||||
case relationship::type::shared_workbook_user_data: break;
|
||||
case relationship::type::single_cell_table_definitions: break;
|
||||
case relationship::type::table_definition: break;
|
||||
case relationship::type::volatile_dependencies: break;
|
||||
case relationship::type::image: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +220,7 @@ void xlsx_producer::write_content_types()
|
|||
serializer().end_element(xmlns, "Types");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_extended_properties(const relationship &rel)
|
||||
void xlsx_producer::write_extended_properties(const relationship &/*rel*/)
|
||||
{
|
||||
const auto xmlns = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"s;
|
||||
const auto xmlns_vt = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"s;
|
||||
|
@ -247,13 +276,13 @@ void xlsx_producer::write_extended_properties(const relationship &rel)
|
|||
serializer().end_element(xmlns, "Properties");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_core_properties(const relationship &rel)
|
||||
void xlsx_producer::write_core_properties(const relationship &/*rel*/)
|
||||
{
|
||||
static const auto xmlns_cp = constants::get_namespace("core-properties");
|
||||
static const auto xmlns_dc = constants::get_namespace("dc");
|
||||
static const auto xmlns_dcterms = constants::get_namespace("dcterms");
|
||||
static const auto xmlns_dcmitype = constants::get_namespace("dcmitype");
|
||||
static const auto xmlns_xsi = constants::get_namespace("xsi");
|
||||
static const auto &xmlns_cp = constants::get_namespace("core-properties");
|
||||
static const auto &xmlns_dc = constants::get_namespace("dc");
|
||||
static const auto &xmlns_dcterms = constants::get_namespace("dcterms");
|
||||
static const auto &xmlns_dcmitype = constants::get_namespace("dcmitype");
|
||||
static const auto &xmlns_xsi = constants::get_namespace("xsi");
|
||||
|
||||
serializer().start_element(xmlns_cp, "coreProperties");
|
||||
serializer().namespace_decl(xmlns_cp, "cp");
|
||||
|
@ -289,7 +318,7 @@ void xlsx_producer::write_core_properties(const relationship &rel)
|
|||
serializer().end_element(xmlns_cp, "coreProperties");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_custom_properties(const relationship &rel)
|
||||
void xlsx_producer::write_custom_properties(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().element("Properties");
|
||||
}
|
||||
|
@ -319,13 +348,13 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
throw no_visible_worksheets();
|
||||
}
|
||||
|
||||
static const auto xmlns = constants::get_namespace("workbook");
|
||||
static const auto xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto xmlns_mx = constants::get_namespace("mx");
|
||||
static const auto xmlns_r = constants::get_namespace("r");
|
||||
static const auto xmlns_s = constants::get_namespace("worksheet");
|
||||
static const auto xmlns_x15 = constants::get_namespace("x15");
|
||||
static const auto xmlns_x15ac = constants::get_namespace("x15ac");
|
||||
static const auto &xmlns = constants::get_namespace("workbook");
|
||||
static const auto &xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto &xmlns_mx = constants::get_namespace("mx");
|
||||
static const auto &xmlns_r = constants::get_namespace("r");
|
||||
static const auto &xmlns_s = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns_x15 = constants::get_namespace("x15");
|
||||
static const auto &xmlns_x15ac = constants::get_namespace("x15ac");
|
||||
|
||||
serializer().start_element(xmlns, "workbook");
|
||||
serializer().namespace_decl(xmlns, "");
|
||||
|
@ -422,6 +451,8 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
serializer().element(xmlns, "definedNames", "");
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wrange-loop-analysis"
|
||||
for (const auto ws : source_)
|
||||
{
|
||||
auto sheet_rel_id = source_.d_->sheet_title_rel_id_map_[ws.get_title()];
|
||||
|
@ -453,6 +484,7 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
|
||||
serializer().end_element(xmlns, "sheet");
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
serializer().end_element(xmlns, "sheets");
|
||||
|
||||
|
@ -570,57 +602,76 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
write_worksheet(child_rel);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case relationship::type::office_document: break;
|
||||
case relationship::type::thumbnail: break;
|
||||
case relationship::type::extended_properties: break;
|
||||
case relationship::type::core_properties: break;
|
||||
case relationship::type::hyperlink: break;
|
||||
case relationship::type::comments: break;
|
||||
case relationship::type::vml_drawing: break;
|
||||
case relationship::type::unknown: break;
|
||||
case relationship::type::custom_properties: break;
|
||||
case relationship::type::printer_settings: break;
|
||||
case relationship::type::custom_property: break;
|
||||
case relationship::type::drawings: break;
|
||||
case relationship::type::pivot_table_cache_definition: break;
|
||||
case relationship::type::pivot_table_cache_records: break;
|
||||
case relationship::type::query_table: break;
|
||||
case relationship::type::shared_workbook: break;
|
||||
case relationship::type::revision_log: break;
|
||||
case relationship::type::shared_workbook_user_data: break;
|
||||
case relationship::type::single_cell_table_definitions: break;
|
||||
case relationship::type::table_definition: break;
|
||||
case relationship::type::image: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write Workbook Relationship Target Parts
|
||||
|
||||
void xlsx_producer::write_calculation_chain(const relationship &rel)
|
||||
void xlsx_producer::write_calculation_chain(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("calcChain");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_chartsheet(const relationship &rel)
|
||||
void xlsx_producer::write_chartsheet(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("chartsheet");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_connections(const relationship &rel)
|
||||
void xlsx_producer::write_connections(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("connections");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_custom_xml_mappings(const relationship &rel)
|
||||
void xlsx_producer::write_custom_xml_mappings(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("MapInfo");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_dialogsheet(const relationship &rel)
|
||||
void xlsx_producer::write_dialogsheet(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("dialogsheet");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_external_workbook_references(const relationship &rel)
|
||||
void xlsx_producer::write_external_workbook_references(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("externalLink");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_metadata(const relationship &rel)
|
||||
void xlsx_producer::write_metadata(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("metadata");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_pivot_table(const relationship &rel)
|
||||
void xlsx_producer::write_pivot_table(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("pivotTableDefinition");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_string_table(const relationship &rel)
|
||||
void xlsx_producer::write_shared_string_table(const relationship &/*rel*/)
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns = constants::get_namespace("worksheet");
|
||||
|
||||
serializer().start_element(xmlns, "sst");
|
||||
serializer().namespace_decl(xmlns, "");
|
||||
|
@ -628,6 +679,8 @@ void xlsx_producer::write_shared_string_table(const relationship &rel)
|
|||
// todo: is there a more elegant way to get this number?
|
||||
std::size_t string_count = 0;
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wrange-loop-analysis"
|
||||
for (const auto ws : source_)
|
||||
{
|
||||
auto dimension = ws.calculate_dimension();
|
||||
|
@ -646,6 +699,7 @@ void xlsx_producer::write_shared_string_table(const relationship &rel)
|
|||
}
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
serializer().attribute("count", string_count);
|
||||
serializer().attribute("uniqueCount", source_.get_shared_strings().size());
|
||||
|
@ -725,27 +779,27 @@ void xlsx_producer::write_shared_string_table(const relationship &rel)
|
|||
serializer().end_element(xmlns, "sst");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_workbook_revision_headers(const relationship &rel)
|
||||
void xlsx_producer::write_shared_workbook_revision_headers(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("headers");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_workbook(const relationship &rel)
|
||||
void xlsx_producer::write_shared_workbook(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("revisions");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_workbook_user_data(const relationship &rel)
|
||||
void xlsx_producer::write_shared_workbook_user_data(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("users");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_styles(const relationship &rel)
|
||||
void xlsx_producer::write_styles(const relationship &/*rel*/)
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
static const auto xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto xmlns_x14 = constants::get_namespace("x14");
|
||||
static const auto xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
static const auto &xmlns = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto &xmlns_x14 = constants::get_namespace("x14");
|
||||
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
|
||||
serializer().start_element(xmlns, "styleSheet");
|
||||
serializer().namespace_decl(xmlns, "");
|
||||
|
@ -794,12 +848,12 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
|
||||
auto num_known_fonts = std::count_if(fonts.begin(), fonts.end(), [](const xlnt::font &f)
|
||||
{
|
||||
static const auto known_fonts = std::vector<xlnt::font>
|
||||
static const auto known_fonts = new std::vector<xlnt::font>
|
||||
{
|
||||
xlnt::font().color(xlnt::theme_color(1)).scheme("minor").family(2)
|
||||
};
|
||||
|
||||
return std::find(known_fonts.begin(), known_fonts.end(), f) != known_fonts.end();
|
||||
return std::find(known_fonts->begin(), known_fonts->end(), f) != known_fonts->end();
|
||||
});
|
||||
|
||||
if (source_.x15_enabled())
|
||||
|
@ -917,27 +971,27 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
serializer().start_element(xmlns, "gradientFill");
|
||||
serializer().attribute("gradientType", gradient.type());
|
||||
|
||||
if (gradient.degree() != 0)
|
||||
if (gradient.degree() != 0.)
|
||||
{
|
||||
serializer().attribute("degree", gradient.degree());
|
||||
}
|
||||
|
||||
if (gradient.left() != 0)
|
||||
if (gradient.left() != 0.)
|
||||
{
|
||||
serializer().attribute("left", gradient.left());
|
||||
}
|
||||
|
||||
if (gradient.right() != 0)
|
||||
if (gradient.right() != 0.)
|
||||
{
|
||||
serializer().attribute("right", gradient.right());
|
||||
}
|
||||
|
||||
if (gradient.top() != 0)
|
||||
if (gradient.top() != 0.)
|
||||
{
|
||||
serializer().attribute("top", gradient.top());
|
||||
}
|
||||
|
||||
if (gradient.bottom() != 0)
|
||||
if (gradient.bottom() != 0.)
|
||||
{
|
||||
serializer().attribute("bottom", gradient.bottom());
|
||||
}
|
||||
|
@ -1021,9 +1075,9 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
serializer().start_element(xmlns, "cellStyleXfs");
|
||||
serializer().attribute("count", stylesheet.style_impls.size());
|
||||
|
||||
for (auto ¤t_style_name_impl : stylesheet.style_impls)
|
||||
for (const auto ¤t_style_name : stylesheet.style_names)
|
||||
{
|
||||
auto ¤t_style_impl = current_style_name_impl.second;
|
||||
const auto ¤t_style_impl = stylesheet.style_impls.at(current_style_name);
|
||||
|
||||
serializer().start_element(xmlns, "xf");
|
||||
serializer().attribute("numFmtId", current_style_impl.number_format_id.get());
|
||||
|
@ -1123,9 +1177,19 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
for (auto ¤t_format_impl : stylesheet.format_impls)
|
||||
{
|
||||
serializer().start_element(xmlns, "xf");
|
||||
|
||||
serializer().attribute("numFmtId", current_format_impl.number_format_id.get());
|
||||
serializer().attribute("fontId", current_format_impl.font_id.get());
|
||||
|
||||
if (current_format_impl.style)
|
||||
{
|
||||
serializer().attribute("fillId", stylesheet.style_impls.at(current_format_impl.style.get()).fill_id.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer().attribute("fillId", current_format_impl.fill_id.get());
|
||||
}
|
||||
|
||||
serializer().attribute("borderId", current_format_impl.border_id.get());
|
||||
|
||||
if (current_format_impl.number_format_applied)
|
||||
|
@ -1289,10 +1353,10 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
serializer().end_element(xmlns, "styleSheet");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_theme(const relationship &rel)
|
||||
void xlsx_producer::write_theme(const relationship &/*rel*/)
|
||||
{
|
||||
static const auto xmlns_a = constants::get_namespace("drawingml");
|
||||
static const auto xmlns_thm15 = constants::get_namespace("thm15");
|
||||
static const auto &xmlns_a = constants::get_namespace("drawingml");
|
||||
static const auto &xmlns_thm15 = constants::get_namespace("thm15");
|
||||
|
||||
serializer().start_element(xmlns_a, "theme");
|
||||
serializer().namespace_decl(xmlns_a, "a");
|
||||
|
@ -1353,7 +1417,7 @@ void xlsx_producer::write_theme(const relationship &rel)
|
|||
std::string minor;
|
||||
};
|
||||
|
||||
static const std::vector<font_scheme> font_schemes = {
|
||||
static const auto font_schemes = new std::vector<font_scheme> {
|
||||
{ true, "latin", "Calibri Light", "Calibri" },
|
||||
{ true, "ea", "", "" },
|
||||
{ true, "cs", "", "" },
|
||||
|
@ -1398,7 +1462,7 @@ void xlsx_producer::write_theme(const relationship &rel)
|
|||
{
|
||||
serializer().start_element(xmlns_a, major ? "majorFont" : "minorFont");
|
||||
|
||||
for (const auto scheme : font_schemes)
|
||||
for (const auto &scheme : *font_schemes)
|
||||
{
|
||||
const auto scheme_value = major ? scheme.major : scheme.minor;
|
||||
|
||||
|
@ -1759,17 +1823,17 @@ void xlsx_producer::write_theme(const relationship &rel)
|
|||
serializer().end_element(xmlns_a, "theme");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_volatile_dependencies(const relationship &rel)
|
||||
void xlsx_producer::write_volatile_dependencies(const relationship &/*rel*/)
|
||||
{
|
||||
serializer().start_element("volTypes");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_worksheet(const relationship &rel)
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
static const auto xmlns_r = constants::get_namespace("r");
|
||||
static const auto xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
static const auto &xmlns = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns_r = constants::get_namespace("r");
|
||||
static const auto &xmlns_mc = constants::get_namespace("mc");
|
||||
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
|
||||
|
||||
auto worksheet_part = rel.get_source().get_path().parent().append(rel.get_target().get_path());
|
||||
auto worksheet_rels = source_.get_manifest().get_relationships(worksheet_part);
|
||||
|
@ -1984,7 +2048,7 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
|||
serializer().attribute("customHeight", "1");
|
||||
auto height = ws.get_row_properties(row.front().get_row()).height;
|
||||
|
||||
if (height == std::floor(height))
|
||||
if (std::fabs(height - std::floor(height)) == 0.L)
|
||||
{
|
||||
serializer().attribute("ht", std::to_string(static_cast<long long int>(height)) + ".0");
|
||||
}
|
||||
|
@ -2227,17 +2291,17 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
|||
if (!ws.get_header_footer().is_default())
|
||||
{
|
||||
// todo: this shouldn't be hardcoded
|
||||
static const auto header_text =
|
||||
static const auto header_text = new std::string(
|
||||
"&L&\"Calibri,Regular\"&K000000Left Header Text&C&\"Arial,Regular\"&6&K445566Center Header "
|
||||
"Text&R&\"Arial,Bold\"&8&K112233Right Header Text"s;
|
||||
static const auto footer_text =
|
||||
"Text&R&\"Arial,Bold\"&8&K112233Right Header Text");
|
||||
static const auto footer_text = new std::string(
|
||||
"&L&\"Times New Roman,Regular\"&10&K445566Left Footer Text_x000D_And &D and &T&C&\"Times New "
|
||||
"Roman,Bold\"&12&K778899Center Footer Text &Z&F on &A&R&\"Times New Roman,Italic\"&14&KAABBCCRight Footer "
|
||||
"Text &P of &N"s;
|
||||
"Text &P of &N");
|
||||
|
||||
serializer().start_element(xmlns, "headerFooter");
|
||||
serializer().element(xmlns, "oddHeader", header_text);
|
||||
serializer().element(xmlns, "oddFooter", footer_text);
|
||||
serializer().element(xmlns, "oddHeader", *header_text);
|
||||
serializer().element(xmlns, "oddFooter", *footer_text);
|
||||
serializer().end_element(xmlns, "headerFooter");
|
||||
}
|
||||
|
||||
|
@ -2293,8 +2357,39 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
|||
write_vml_drawings(child_rel, ws, cells_with_comments);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case relationship::type::office_document: break;
|
||||
case relationship::type::thumbnail: break;
|
||||
case relationship::type::calculation_chain: break;
|
||||
case relationship::type::extended_properties: break;
|
||||
case relationship::type::core_properties: break;
|
||||
case relationship::type::worksheet: break;
|
||||
case relationship::type::shared_string_table: break;
|
||||
case relationship::type::styles: break;
|
||||
case relationship::type::theme: break;
|
||||
case relationship::type::hyperlink: break;
|
||||
case relationship::type::chartsheet: break;
|
||||
case relationship::type::unknown: break;
|
||||
case relationship::type::custom_properties: break;
|
||||
case relationship::type::printer_settings: break;
|
||||
case relationship::type::connections: break;
|
||||
case relationship::type::custom_property: break;
|
||||
case relationship::type::custom_xml_mappings: break;
|
||||
case relationship::type::dialogsheet: break;
|
||||
case relationship::type::drawings: break;
|
||||
case relationship::type::external_workbook_references: break;
|
||||
case relationship::type::metadata: break;
|
||||
case relationship::type::pivot_table: break;
|
||||
case relationship::type::pivot_table_cache_definition: break;
|
||||
case relationship::type::pivot_table_cache_records: break;
|
||||
case relationship::type::query_table: break;
|
||||
case relationship::type::shared_workbook_revision_headers: break;
|
||||
case relationship::type::shared_workbook: break;
|
||||
case relationship::type::revision_log: break;
|
||||
case relationship::type::shared_workbook_user_data: break;
|
||||
case relationship::type::single_cell_table_definitions: break;
|
||||
case relationship::type::table_definition: break;
|
||||
case relationship::type::volatile_dependencies: break;
|
||||
case relationship::type::image: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2302,10 +2397,10 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
|||
|
||||
// Sheet Relationship Target Parts
|
||||
|
||||
void xlsx_producer::write_comments(const relationship &rel, worksheet ws,
|
||||
void xlsx_producer::write_comments(const relationship &/*rel*/, worksheet ws,
|
||||
const std::vector<cell_reference> &cells)
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
static const auto &xmlns = constants::get_namespace("worksheet");
|
||||
|
||||
serializer().start_element(xmlns, "comments");
|
||||
serializer().namespace_decl(xmlns, "");
|
||||
|
@ -2418,10 +2513,10 @@ void xlsx_producer::write_comments(const relationship &rel, worksheet ws,
|
|||
void xlsx_producer::write_vml_drawings(const relationship &rel, worksheet ws,
|
||||
const std::vector<cell_reference> &cells)
|
||||
{
|
||||
static const auto xmlns_mv = std::string("http://macVmlSchemaUri");
|
||||
static const auto xmlns_o = std::string("urn:schemas-microsoft-com:office:office");
|
||||
static const auto xmlns_v = std::string("urn:schemas-microsoft-com:vml");
|
||||
static const auto xmlns_x = std::string("urn:schemas-microsoft-com:office:excel");
|
||||
static const auto &xmlns_mv = std::string("http://macVmlSchemaUri");
|
||||
static const auto &xmlns_o = std::string("urn:schemas-microsoft-com:office:office");
|
||||
static const auto &xmlns_v = std::string("urn:schemas-microsoft-com:vml");
|
||||
static const auto &xmlns_x = std::string("urn:schemas-microsoft-com:office:excel");
|
||||
|
||||
serializer().start_element("xml");
|
||||
serializer().namespace_decl(xmlns_v, "v");
|
||||
|
@ -2620,8 +2715,11 @@ void xlsx_producer::write_color(const xlnt::color &color)
|
|||
serializer().attribute("indexed", color.get_indexed().get_index());
|
||||
break;
|
||||
|
||||
case xlnt::color::type::auto_:
|
||||
serializer().attribute("auto", color.get_indexed().get_index());
|
||||
break;
|
||||
|
||||
case xlnt::color::type::rgb:
|
||||
default:
|
||||
serializer().attribute("rgb", color.get_rgb().get_hex_string());
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
|
@ -48,6 +49,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include <detail/zip.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
@ -168,16 +170,18 @@ void zip_file_header::Write(std::ostream &ostream, const bool global) const
|
|||
}
|
||||
}
|
||||
|
||||
static const std::size_t buffer_size = 512;
|
||||
|
||||
class ZipStreambufDecompress : public std::streambuf
|
||||
{
|
||||
static const unsigned int buffer_size = 512;
|
||||
std::istream &istream;
|
||||
|
||||
z_stream strm;
|
||||
unsigned char in[buffer_size], out[buffer_size];
|
||||
std::array<char, buffer_size> in;
|
||||
std::array<char, buffer_size> out;
|
||||
zip_file_header header;
|
||||
int total_read, total_uncompressed;
|
||||
// bool own_istream;
|
||||
std::size_t total_read;
|
||||
std::size_t total_uncompressed;
|
||||
bool valid;
|
||||
bool compressed_data;
|
||||
|
||||
|
@ -193,55 +197,75 @@ public:
|
|||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = 0;
|
||||
strm.next_in = Z_NULL;
|
||||
setg((char *)in, (char *)in, (char *)in);
|
||||
|
||||
setg(in.data(), in.data(), in.data());
|
||||
setp(0, 0);
|
||||
|
||||
// skip the header
|
||||
valid = header.read(istream, false);
|
||||
if (header.compression_type == DEFLATE)
|
||||
{
|
||||
compressed_data = true;
|
||||
}
|
||||
else if (header.compression_type == UNCOMPRESSED)
|
||||
{
|
||||
compressed_data = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
compressed_data = false;
|
||||
std::cerr << "ZIP: got unrecognized compressed data (Supported deflate/uncompressed)" << std::endl;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// initialize the inflate
|
||||
if (compressed_data && valid)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
int result = inflateInit2(&strm, -MAX_WBITS);
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
std::cerr << "gzip: inflateInit2 did not return Z_OK" << std::endl;
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
header = central_header;
|
||||
}
|
||||
|
||||
virtual ~ZipStreambufDecompress()
|
||||
{
|
||||
if (compressed_data && valid) inflateEnd(&strm);
|
||||
if (compressed_data && valid)
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
}
|
||||
}
|
||||
|
||||
int process()
|
||||
{
|
||||
if (!valid) return -1;
|
||||
|
||||
if (compressed_data)
|
||||
{
|
||||
strm.avail_out = buffer_size - 4;
|
||||
strm.next_out = (Bytef *)(out + 4);
|
||||
strm.next_out = reinterpret_cast<Bytef *>(out.data() + 4);
|
||||
|
||||
while (strm.avail_out != 0)
|
||||
{
|
||||
if (strm.avail_in == 0)
|
||||
{ // buffer empty, read some more from file
|
||||
istream.read((char *)in, std::min((unsigned int)buffer_size, header.compressed_size - total_read));
|
||||
strm.avail_in = istream.gcount();
|
||||
{
|
||||
// buffer empty, read some more from file
|
||||
istream.read(in.data(), static_cast<std::streamsize>(std::min(buffer_size, header.compressed_size - total_read)));
|
||||
strm.avail_in = static_cast<unsigned int>(istream.gcount());
|
||||
total_read += strm.avail_in;
|
||||
strm.next_in = (Bytef *)in;
|
||||
strm.next_in = reinterpret_cast<Bytef *>(in.data());
|
||||
}
|
||||
|
||||
int ret = inflate(&strm, Z_NO_FLUSH); // decompress
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case Z_STREAM_ERROR:
|
||||
|
@ -255,49 +279,50 @@ public:
|
|||
valid = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == Z_STREAM_END) break;
|
||||
}
|
||||
int unzip_count = buffer_size - strm.avail_out - 4;
|
||||
|
||||
auto unzip_count = buffer_size - strm.avail_out - 4;
|
||||
total_uncompressed += unzip_count;
|
||||
return unzip_count;
|
||||
return static_cast<int>(unzip_count);
|
||||
}
|
||||
else
|
||||
{ // uncompressed, so just read
|
||||
istream.read((char *)(out + 4), std::min(buffer_size - 4, header.uncompressed_size - total_read));
|
||||
int count = istream.gcount();
|
||||
total_read += count;
|
||||
return count;
|
||||
}
|
||||
return 1;
|
||||
|
||||
// uncompressed, so just read
|
||||
istream.read(out.data() + 4, static_cast<std::streamsize>(std::min(buffer_size - 4, header.uncompressed_size - total_read)));
|
||||
auto count = istream.gcount();
|
||||
total_read += static_cast<std::size_t>(count);
|
||||
return static_cast<int>(count);
|
||||
}
|
||||
|
||||
virtual int underflow()
|
||||
{
|
||||
if (gptr() && (gptr() < egptr()))
|
||||
return traits_type::to_int_type(*gptr()); // if we already have data just use it
|
||||
int put_back_count = gptr() - eback();
|
||||
auto put_back_count = gptr() - eback();
|
||||
if (put_back_count > 4) put_back_count = 4;
|
||||
std::memmove(out + (4 - put_back_count), gptr() - put_back_count, put_back_count);
|
||||
std::memmove(out.data() + (4 - put_back_count), gptr() - put_back_count, static_cast<std::size_t>(put_back_count));
|
||||
int num = process();
|
||||
setg((char *)(out + 4 - put_back_count), (char *)(out + 4), (char *)(out + 4 + num));
|
||||
setg(out.data() + 4 - put_back_count, out.data() + 4, out.data() + 4 + num);
|
||||
if (num <= 0) return EOF;
|
||||
return traits_type::to_int_type(*gptr());
|
||||
}
|
||||
|
||||
virtual int overflow(int c = EOF)
|
||||
{
|
||||
assert(false);
|
||||
return EOF;
|
||||
}
|
||||
virtual int overflow(int c = EOF);
|
||||
};
|
||||
|
||||
int ZipStreambufDecompress::overflow(int)
|
||||
{
|
||||
throw xlnt::exception("writing to read-only buffer");
|
||||
}
|
||||
|
||||
class ZipStreambufCompress : public std::streambuf
|
||||
{
|
||||
static const int buffer_size = 512;
|
||||
std::ostream &ostream; // owned when header==0 (when not part of zip file)
|
||||
|
||||
z_stream strm;
|
||||
unsigned char in[buffer_size], out[buffer_size];
|
||||
std::array<char, buffer_size> in;
|
||||
std::array<char, buffer_size> out;
|
||||
|
||||
zip_file_header *header;
|
||||
unsigned int uncompressed_size;
|
||||
|
@ -312,21 +337,29 @@ public:
|
|||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
int ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if (ret != Z_OK)
|
||||
{
|
||||
std::cerr << "libz: failed to deflateInit" << std::endl;
|
||||
valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
setg(0, 0, 0);
|
||||
setp((char *)in, (char *)(in + buffer_size - 4)); // we want to be 4 aligned
|
||||
setp(in.data(), in.data() + buffer_size - 4); // we want to be 4 aligned
|
||||
|
||||
// Write appropriate header
|
||||
if (header)
|
||||
{
|
||||
header->header_offset = stream.tellp();
|
||||
header->header_offset = static_cast<std::uint32_t>(stream.tellp());
|
||||
header->Write(ostream, false);
|
||||
}
|
||||
|
||||
uncompressed_size = crc = 0;
|
||||
}
|
||||
|
||||
|
@ -358,13 +391,17 @@ protected:
|
|||
int process(bool flush)
|
||||
{
|
||||
if (!valid) return -1;
|
||||
strm.next_in = (Bytef *)pbase();
|
||||
strm.avail_in = pptr() - pbase();
|
||||
|
||||
strm.next_in = reinterpret_cast<Bytef *>(pbase());
|
||||
strm.avail_in = static_cast<unsigned int>(pptr() - pbase());
|
||||
|
||||
while (strm.avail_in != 0 || flush)
|
||||
{
|
||||
strm.avail_out = buffer_size;
|
||||
strm.next_out = (Bytef *)out;
|
||||
strm.next_out = reinterpret_cast<Bytef *>(out.data());
|
||||
|
||||
int ret = deflate(&strm, flush ? Z_FINISH : Z_NO_FLUSH);
|
||||
|
||||
if (!(ret != Z_BUF_ERROR && ret != Z_STREAM_ERROR))
|
||||
{
|
||||
valid = false;
|
||||
|
@ -372,16 +409,19 @@ protected:
|
|||
;
|
||||
return -1;
|
||||
}
|
||||
int generated_output = strm.next_out - (Bytef *)out;
|
||||
ostream.write((char *)out, generated_output);
|
||||
if (header) header->compressed_size += generated_output;
|
||||
|
||||
auto generated_output = static_cast<int>(strm.next_out - reinterpret_cast<std::uint8_t *>(out.data()));
|
||||
ostream.write(out.data(), generated_output);
|
||||
if (header) header->compressed_size += static_cast<unsigned int>(generated_output);
|
||||
if (ret == Z_STREAM_END) break;
|
||||
}
|
||||
|
||||
// update counts, crc's and buffers
|
||||
int consumed_input = pptr() - pbase();
|
||||
auto consumed_input = static_cast<unsigned int>(pptr() - pbase());
|
||||
uncompressed_size += consumed_input;
|
||||
crc = crc32(crc, (Bytef *)in, consumed_input);
|
||||
crc = static_cast<unsigned int>(crc32(crc, reinterpret_cast<Bytef *>(in.data()), consumed_input));
|
||||
setp(pbase(), pbase() + buffer_size - 4);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -393,21 +433,22 @@ protected:
|
|||
|
||||
virtual int underflow()
|
||||
{
|
||||
std::runtime_error("Attempt to read write only ostream");
|
||||
return 0;
|
||||
throw std::runtime_error("Attempt to read write only ostream");
|
||||
}
|
||||
|
||||
virtual int overflow(int c = EOF)
|
||||
{
|
||||
virtual int overflow(int c = EOF);
|
||||
};
|
||||
|
||||
int ZipStreambufCompress::overflow(int c)
|
||||
{
|
||||
if (c != EOF)
|
||||
{
|
||||
*pptr() = c;
|
||||
*pptr() = static_cast<char>(c);
|
||||
pbump(1);
|
||||
}
|
||||
if (process(false) == EOF) return EOF;
|
||||
return c;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
zip_file_istream::zip_file_istream(std::unique_ptr<std::streambuf> &&buffer)
|
||||
: std::istream(&*buffer)
|
||||
|
@ -438,20 +479,23 @@ ZipFileWriter::~ZipFileWriter()
|
|||
{
|
||||
// Write all file headers
|
||||
std::ios::streampos final_position = target_stream_.tellp();
|
||||
|
||||
for (unsigned int i = 0; i < file_headers_.size(); i++)
|
||||
{
|
||||
file_headers_[i].Write(target_stream_, true);
|
||||
}
|
||||
|
||||
std::ios::streampos central_end = target_stream_.tellp();
|
||||
|
||||
// Write end of central
|
||||
write_int(target_stream_, (unsigned int)0x06054b50); // end of central
|
||||
write_int(target_stream_, (unsigned short)0); // this disk number
|
||||
write_int(target_stream_, (unsigned short)0); // this disk number
|
||||
write_int(target_stream_, (unsigned short)file_headers_.size()); // one entry in center in this disk
|
||||
write_int(target_stream_, (unsigned short)file_headers_.size()); // one entry in center
|
||||
write_int(target_stream_, (unsigned int)(central_end - final_position)); // size of header
|
||||
write_int(target_stream_, (unsigned int)final_position); // offset to header
|
||||
write_int(target_stream_, (unsigned short)0); // zip comment
|
||||
write_int(target_stream_, static_cast<std::uint32_t>(0x06054b50)); // end of central
|
||||
write_int(target_stream_, static_cast<std::uint16_t>(0)); // this disk number
|
||||
write_int(target_stream_, static_cast<std::uint16_t>(0)); // this disk number
|
||||
write_int(target_stream_, static_cast<std::uint16_t>(file_headers_.size())); // one entry in center in this disk
|
||||
write_int(target_stream_, static_cast<std::uint16_t>(file_headers_.size())); // one entry in center
|
||||
write_int(target_stream_, static_cast<std::uint32_t>(central_end - final_position)); // size of header
|
||||
write_int(target_stream_, static_cast<std::uint32_t>(final_position)); // offset to header
|
||||
write_int(target_stream_, static_cast<std::uint16_t>(0)); // zip comment
|
||||
}
|
||||
|
||||
std::ostream &ZipFileWriter::open(const std::string &filename)
|
||||
|
@ -496,20 +540,26 @@ bool ZipFileReader::read_central_header()
|
|||
|
||||
std::ios::streamoff read_start = max_comment_size + read_size_before_comment;
|
||||
|
||||
if (read_start > end_position) read_start = end_position;
|
||||
if (read_start > end_position)
|
||||
{
|
||||
read_start = end_position;
|
||||
}
|
||||
|
||||
source_stream_.seekg(end_position - read_start);
|
||||
std::vector<char> buf(static_cast<std::size_t>(read_start), '\0');
|
||||
|
||||
if (read_start <= 0)
|
||||
{
|
||||
std::cerr << "ZIP: Invalid read buffer size" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
source_stream_.read(buf.data(), read_start);
|
||||
|
||||
auto found_header = false;
|
||||
std::size_t header_index = 0;
|
||||
|
||||
for (std::size_t i = 0; i < read_start - 3; ++i)
|
||||
for (std::size_t i = 0; i < static_cast<std::size_t>(read_start - 3); ++i)
|
||||
{
|
||||
if (buf[i] == 0x50 && buf[i + 1] == 0x4b && buf[i + 2] == 0x05 && buf[i + 3] == 0x06)
|
||||
{
|
||||
|
|
|
@ -111,8 +111,10 @@ optional<border::border_property> border::side(border_side s) const
|
|||
case border_side::end: return end_;
|
||||
case border_side::vertical: return vertical_;
|
||||
case border_side::horizontal: return horizontal_;
|
||||
default:
|
||||
case border_side::diagonal: return diagonal_;
|
||||
#ifdef WIN32
|
||||
default: throw xlnt::exception("unhandled");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +128,6 @@ border &border::side(border_side s, const border_property &prop)
|
|||
case border_side::end: end_ = prop; break;
|
||||
case border_side::vertical: vertical_ = prop; break;
|
||||
case border_side::horizontal: horizontal_ = prop; break;
|
||||
default:
|
||||
case border_side::diagonal: diagonal_ = prop; break;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <xlnt/styles/color.hpp>
|
||||
|
@ -216,17 +217,22 @@ void color::assert_type(type t) const
|
|||
|
||||
XLNT_API bool color::operator==(const xlnt::color &other) const
|
||||
{
|
||||
if (type_ != other.type_ || tint_ != other.tint_) return false;
|
||||
if (type_ != other.type_ || std::fabs(tint_ - other.tint_) != 0.)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(type_)
|
||||
{
|
||||
case type::auto_:
|
||||
case type::indexed :
|
||||
case type::indexed:
|
||||
return indexed_.get_index() == other.indexed_.get_index();
|
||||
case type::theme:
|
||||
return theme_.get_index() == other.theme_.get_index();
|
||||
case type::rgb:
|
||||
return rgb_.get_hex_string() == other.rgb_.get_hex_string();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,27 +205,27 @@ XLNT_API bool operator==(const gradient_fill &left, const gradient_fill &right)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (left.degree() != right.degree())
|
||||
if (std::fabs(left.degree() - right.degree()) != 0.)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left.bottom() != right.bottom())
|
||||
if (std::fabs(left.bottom() - right.bottom()) != 0.)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left.right() != right.right())
|
||||
if (std::fabs(left.right() - right.right()) != 0.)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left.top() != right.top())
|
||||
if (std::fabs(left.top() - right.top()) != 0.)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left.left() != right.left())
|
||||
if (std::fabs(left.left() - right.left()) != 0.)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ void format::clear_style()
|
|||
|
||||
format format::style(const xlnt::style &new_style)
|
||||
{
|
||||
d_->style = new_style.name();
|
||||
d_ = d_->parent->find_or_create_with(d_, new_style.name());
|
||||
return format(d_);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace xlnt {
|
|||
|
||||
datetime datetime::from_number(long double raw_time, calendar base_date)
|
||||
{
|
||||
auto date_part = date::from_number((int)raw_time, base_date);
|
||||
auto date_part = date::from_number(static_cast<int>(raw_time), base_date);
|
||||
auto time_part = time::from_number(raw_time);
|
||||
|
||||
return datetime(date_part.year, date_part.month, date_part.day, time_part.hour, time_part.minute, time_part.second,
|
||||
|
|
|
@ -41,11 +41,23 @@ void exception::set_message(const std::string &message)
|
|||
message_ = message;
|
||||
}
|
||||
|
||||
missing_number_format::~missing_number_format()
|
||||
{
|
||||
}
|
||||
|
||||
unhandled_switch_case::~unhandled_switch_case()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_sheet_title::invalid_sheet_title(const std::string &title)
|
||||
: exception(std::string("bad worksheet title: ") + title)
|
||||
{
|
||||
}
|
||||
|
||||
invalid_sheet_title::~invalid_sheet_title()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_column_string_index::invalid_column_string_index()
|
||||
: exception("column string index error")
|
||||
{
|
||||
|
@ -60,11 +72,19 @@ invalid_data_type::invalid_data_type()
|
|||
{
|
||||
}
|
||||
|
||||
invalid_data_type::~invalid_data_type()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_file::invalid_file(const std::string &filename)
|
||||
: exception(std::string("couldn't open file: (") + filename + ")")
|
||||
{
|
||||
}
|
||||
|
||||
invalid_file::~invalid_file()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_cell_reference::invalid_cell_reference(column_t column, row_t row)
|
||||
: exception(std::string("bad cell coordinates: (") + std::to_string(column.index) + ", " + std::to_string(row) +
|
||||
")")
|
||||
|
@ -85,11 +105,19 @@ illegal_character::illegal_character(char c)
|
|||
{
|
||||
}
|
||||
|
||||
illegal_character::~illegal_character()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_parameter::invalid_parameter()
|
||||
: exception("invalid parameter")
|
||||
{
|
||||
}
|
||||
|
||||
invalid_parameter::~invalid_parameter()
|
||||
{
|
||||
}
|
||||
|
||||
invalid_attribute::invalid_attribute()
|
||||
: exception("bad attribute")
|
||||
{
|
||||
|
@ -104,14 +132,26 @@ key_not_found::key_not_found()
|
|||
{
|
||||
}
|
||||
|
||||
key_not_found::~key_not_found()
|
||||
{
|
||||
}
|
||||
|
||||
no_visible_worksheets::no_visible_worksheets()
|
||||
: exception("workbook needs at least one non-hidden worksheet to be saved")
|
||||
{
|
||||
}
|
||||
|
||||
no_visible_worksheets::~no_visible_worksheets()
|
||||
{
|
||||
}
|
||||
|
||||
unsupported::unsupported(const std::string &message)
|
||||
: exception(message)
|
||||
{
|
||||
}
|
||||
|
||||
unsupported::~unsupported()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -48,16 +48,16 @@ time time::from_number(long double raw_time)
|
|||
time result;
|
||||
|
||||
double integer_part;
|
||||
double fractional_part = std::modf((double)raw_time, &integer_part);
|
||||
double fractional_part = std::modf(static_cast<double>(raw_time), &integer_part);
|
||||
|
||||
fractional_part *= 24;
|
||||
result.hour = (int)fractional_part;
|
||||
result.hour = static_cast<int>(fractional_part);
|
||||
fractional_part = 60 * (fractional_part - result.hour);
|
||||
result.minute = (int)fractional_part;
|
||||
result.minute = static_cast<int>(fractional_part);
|
||||
fractional_part = 60 * (fractional_part - result.minute);
|
||||
result.second = (int)fractional_part;
|
||||
result.second = static_cast<int>(fractional_part);
|
||||
fractional_part = 1000000 * (fractional_part - result.second);
|
||||
result.microsecond = (int)fractional_part;
|
||||
result.microsecond = static_cast<int>(fractional_part);
|
||||
|
||||
if (result.microsecond == 999999 && fractional_part - result.microsecond > 0.5)
|
||||
{
|
||||
|
|
|
@ -65,15 +65,15 @@ timedelta timedelta::from_number(long double raw_time)
|
|||
result.days = static_cast<int>(integer_part);
|
||||
|
||||
fractional_part *= 24;
|
||||
result.hours = (int)fractional_part;
|
||||
result.hours = static_cast<int>(fractional_part);
|
||||
fractional_part = 60 * (fractional_part - result.hours);
|
||||
result.minutes = (int)fractional_part;
|
||||
result.minutes = static_cast<int>(fractional_part);
|
||||
fractional_part = 60 * (fractional_part - result.minutes);
|
||||
result.seconds = (int)fractional_part;
|
||||
result.seconds = static_cast<int>(fractional_part);
|
||||
fractional_part = 1000000 * (fractional_part - result.seconds);
|
||||
result.microseconds = (int)fractional_part;
|
||||
result.microseconds = static_cast<int>(fractional_part);
|
||||
|
||||
if (result.microseconds == 999999 && fractional_part - result.microseconds > 0.5)
|
||||
if (result.microseconds == 999999 && fractional_part - result.microseconds > 0.5L)
|
||||
{
|
||||
result.microseconds = 0;
|
||||
result.seconds += 1;
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wshadow"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||
#include <utf8.h>
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@ workbook workbook::empty_excel()
|
|||
.font(default_font, false)
|
||||
.number_format(xlnt::number_format::general(), false);
|
||||
|
||||
wb.create_format()
|
||||
wb.create_format(true)
|
||||
.border(default_border, false)
|
||||
.fill(default_fill, false)
|
||||
.font(default_font, false)
|
||||
|
@ -1085,10 +1085,10 @@ std::vector<named_range> workbook::get_named_ranges() const
|
|||
return named_ranges;
|
||||
}
|
||||
|
||||
format workbook::create_format()
|
||||
format workbook::create_format(bool default_format)
|
||||
{
|
||||
register_stylesheet_in_manifest();
|
||||
return d_->stylesheet_.create_format();
|
||||
return d_->stylesheet_.create_format(default_format);
|
||||
}
|
||||
|
||||
bool workbook::has_style(const std::string &name) const
|
||||
|
|
|
@ -27,9 +27,13 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
cell_iterator::cell_iterator(worksheet ws, const cell_reference &start_cell, major_order order)
|
||||
: ws_(ws), current_cell_(start_cell), range_(start_cell.to_range()), order_(order)
|
||||
cell_iterator::cell_iterator(worksheet ws, const cell_reference &start_cell, const range_reference &limits, major_order order)
|
||||
: ws_(ws), current_cell_(start_cell), range_(limits), order_(order)
|
||||
{
|
||||
if (!ws.has_cell(current_cell_))
|
||||
{
|
||||
(*this)++;
|
||||
}
|
||||
}
|
||||
|
||||
cell_iterator::cell_iterator(const cell_iterator &other)
|
||||
|
@ -52,10 +56,20 @@ cell_iterator &cell_iterator::operator--()
|
|||
if (order_ == major_order::row)
|
||||
{
|
||||
current_cell_.set_column_index(current_cell_.get_column_index() - 1);
|
||||
|
||||
while (!ws_.has_cell(current_cell_) && current_cell_.get_column() > range_.get_top_left().get_column())
|
||||
{
|
||||
current_cell_.set_column_index(current_cell_.get_column_index() - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current_cell_.set_row(current_cell_.get_row() - 1);
|
||||
|
||||
while (!ws_.has_cell(current_cell_) && current_cell_.get_row() > range_.get_top_left().get_row())
|
||||
{
|
||||
current_cell_.set_row(current_cell_.get_row() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -71,14 +85,30 @@ cell_iterator cell_iterator::operator--(int)
|
|||
cell_iterator &cell_iterator::operator++()
|
||||
{
|
||||
if (order_ == major_order::row)
|
||||
{
|
||||
if (current_cell_.get_column() <= range_.get_bottom_right().get_column())
|
||||
{
|
||||
current_cell_.set_column_index(current_cell_.get_column_index() + 1);
|
||||
}
|
||||
|
||||
while (!ws_.has_cell(current_cell_) && current_cell_.get_column() <= range_.get_bottom_right().get_column())
|
||||
{
|
||||
current_cell_.set_column_index(current_cell_.get_column_index() + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_cell_.get_row() <= range_.get_bottom_right().get_row())
|
||||
{
|
||||
current_cell_.set_row(current_cell_.get_row() + 1);
|
||||
}
|
||||
|
||||
while (!ws_.has_cell(current_cell_) && current_cell_.get_row() <= range_.get_bottom_right().get_row())
|
||||
{
|
||||
current_cell_.set_row(current_cell_.get_row() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace xlnt {
|
|||
|
||||
cell_vector::iterator cell_vector::begin()
|
||||
{
|
||||
return iterator(ws_, ref_.get_top_left(), order_);
|
||||
return iterator(ws_, ref_.get_top_left(), ref_, order_);
|
||||
}
|
||||
|
||||
cell_vector::iterator cell_vector::end()
|
||||
|
@ -38,12 +38,12 @@ cell_vector::iterator cell_vector::end()
|
|||
{
|
||||
auto past_end = ref_.get_bottom_right();
|
||||
past_end.set_column_index(past_end.get_column_index() + 1);
|
||||
return iterator(ws_, past_end, order_);
|
||||
return iterator(ws_, past_end, ref_, order_);
|
||||
}
|
||||
|
||||
auto past_end = ref_.get_bottom_right();
|
||||
past_end.set_row(past_end.get_row() + 1);
|
||||
return iterator(ws_, past_end, order_);
|
||||
return iterator(ws_, past_end, ref_, order_);
|
||||
}
|
||||
|
||||
cell_vector::const_iterator cell_vector::cbegin() const
|
||||
|
@ -109,10 +109,10 @@ cell cell_vector::get_cell(std::size_t index)
|
|||
{
|
||||
if (order_ == major_order::row)
|
||||
{
|
||||
return ws_.get_cell(ref_.get_top_left().make_offset((int)index, 0));
|
||||
return ws_.get_cell(ref_.get_top_left().make_offset(static_cast<int>(index), 0));
|
||||
}
|
||||
|
||||
return ws_.get_cell(ref_.get_top_left().make_offset(0, (int)index));
|
||||
return ws_.get_cell(ref_.get_top_left().make_offset(0, static_cast<int>(index)));
|
||||
}
|
||||
|
||||
std::size_t cell_vector::length() const
|
||||
|
|
|
@ -103,12 +103,12 @@ range::iterator range::begin()
|
|||
{
|
||||
cell_reference top_right(ref_.get_bottom_right().get_column_index(), ref_.get_top_left().get_row());
|
||||
range_reference row_range(ref_.get_top_left(), top_right);
|
||||
return iterator(ws_, row_range, order_);
|
||||
return iterator(ws_, row_range, ref_, order_);
|
||||
}
|
||||
|
||||
cell_reference bottom_left(ref_.get_top_left().get_column_index(), ref_.get_bottom_right().get_row());
|
||||
range_reference row_range(ref_.get_top_left(), bottom_left);
|
||||
return iterator(ws_, row_range, order_);
|
||||
return iterator(ws_, row_range, ref_, order_);
|
||||
}
|
||||
|
||||
range::iterator range::end()
|
||||
|
@ -118,13 +118,13 @@ range::iterator range::end()
|
|||
auto past_end_row_index = ref_.get_bottom_right().get_row() + 1;
|
||||
cell_reference bottom_left(ref_.get_top_left().get_column_index(), past_end_row_index);
|
||||
cell_reference bottom_right(ref_.get_bottom_right().get_column_index(), past_end_row_index);
|
||||
return iterator(ws_, range_reference(bottom_left, bottom_right), order_);
|
||||
return iterator(ws_, range_reference(bottom_left, bottom_right), ref_, order_);
|
||||
}
|
||||
|
||||
auto past_end_column_index = ref_.get_bottom_right().get_column_index() + 1;
|
||||
cell_reference top_right(past_end_column_index, ref_.get_top_left().get_row());
|
||||
cell_reference bottom_right(past_end_column_index, ref_.get_bottom_right().get_row());
|
||||
return iterator(ws_, range_reference(top_right, bottom_right), order_);
|
||||
return iterator(ws_, range_reference(top_right, bottom_right), ref_, order_);
|
||||
}
|
||||
|
||||
range::const_iterator range::cbegin() const
|
||||
|
|
|
@ -42,8 +42,8 @@ cell_vector range_iterator::operator*() const
|
|||
return cell_vector(ws_, reference, order_);
|
||||
}
|
||||
|
||||
range_iterator::range_iterator(worksheet &ws, const range_reference &start_cell, major_order order)
|
||||
: ws_(ws.d_), current_cell_(start_cell.get_top_left()), range_(start_cell), order_(order)
|
||||
range_iterator::range_iterator(worksheet &ws, const range_reference &start_cell, const range_reference &limits, major_order order)
|
||||
: ws_(ws), current_cell_(start_cell.get_top_left()), range_(limits), order_(order)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -87,8 +87,22 @@ range_iterator range_iterator::operator--(int)
|
|||
range_iterator &range_iterator::operator++()
|
||||
{
|
||||
if (order_ == major_order::row)
|
||||
{
|
||||
bool any_non_null = false;
|
||||
do
|
||||
{
|
||||
current_cell_.set_row(current_cell_.get_row() + 1);
|
||||
any_non_null = false;
|
||||
for (auto column = current_cell_.get_column(); column <= range_.get_bottom_right().get_column(); column++)
|
||||
{
|
||||
if (ws_.has_cell(cell_reference(column, current_cell_.get_row())))
|
||||
{
|
||||
any_non_null = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!any_non_null && current_cell_.get_row() <= range_.get_bottom_right().get_row());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1124,4 +1124,46 @@ public:
|
|||
TS_ASSERT_THROWS_NOTHING(ws.create_named_range("XFE1048576", "A2"));
|
||||
TS_ASSERT_THROWS_NOTHING(ws.create_named_range("XFD1048577", "A2"));
|
||||
}
|
||||
|
||||
void test_iteration_skip_empty()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
auto ws = wb.get_active_sheet();
|
||||
ws.get_cell("A1").set_value("A1");
|
||||
ws.get_cell("F6").set_value("F6");
|
||||
|
||||
{
|
||||
std::vector<xlnt::cell> cells;
|
||||
|
||||
for (auto row : ws)
|
||||
{
|
||||
for (auto cell : row)
|
||||
{
|
||||
cells.push_back(cell);
|
||||
}
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(cells.size(), 2);
|
||||
TS_ASSERT_EQUALS(cells[0].get_value<std::string>(), "A1");
|
||||
TS_ASSERT_EQUALS(cells[1].get_value<std::string>(), "F6");
|
||||
}
|
||||
|
||||
const auto ws_const = ws;
|
||||
|
||||
{
|
||||
std::vector<xlnt::cell> cells;
|
||||
|
||||
for (auto row : ws_const)
|
||||
{
|
||||
for (auto cell : row)
|
||||
{
|
||||
cells.push_back(cell);
|
||||
}
|
||||
}
|
||||
|
||||
TS_ASSERT_EQUALS(cells.size(), 2);
|
||||
TS_ASSERT_EQUALS(cells[0].get_value<std::string>(), "A1");
|
||||
TS_ASSERT_EQUALS(cells[1].get_value<std::string>(), "F6");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -702,7 +702,8 @@ bool worksheet::compare(const worksheet &other, bool reference) const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (this_cell.get_data_type() == xlnt::cell::type::numeric && this_cell.get_value<long double>() != other_cell.get_value<long double>())
|
||||
if (this_cell.get_data_type() == xlnt::cell::type::numeric
|
||||
&& std::fabs(this_cell.get_value<long double>() - other_cell.get_value<long double>()) > 0.L)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -831,16 +832,16 @@ std::vector<std::string> worksheet::get_formula_attributes() const
|
|||
|
||||
cell_reference worksheet::get_point_pos(int left, int top) const
|
||||
{
|
||||
static const double DefaultColumnWidth = 51.85;
|
||||
static const double DefaultRowHeight = 15.0;
|
||||
static const auto DefaultColumnWidth = 51.85L;
|
||||
static const auto DefaultRowHeight = 15.0L;
|
||||
|
||||
auto points_to_pixels = [](long double value, long double dpi)
|
||||
{
|
||||
return static_cast<int>(std::ceil(value * dpi / 72));
|
||||
};
|
||||
|
||||
auto default_height = points_to_pixels(DefaultRowHeight, 96.0);
|
||||
auto default_width = points_to_pixels(DefaultColumnWidth, 96.0);
|
||||
auto default_height = points_to_pixels(DefaultRowHeight, 96.0L);
|
||||
auto default_width = points_to_pixels(DefaultColumnWidth, 96.0L);
|
||||
|
||||
column_t current_column = 1;
|
||||
row_t current_row = 1;
|
||||
|
@ -858,7 +859,7 @@ cell_reference worksheet::get_point_pos(int left, int top) const
|
|||
|
||||
if (cdw >= 0)
|
||||
{
|
||||
left_pos += points_to_pixels(cdw, 96.0);
|
||||
left_pos += points_to_pixels(cdw, 96.0L);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -876,7 +877,7 @@ cell_reference worksheet::get_point_pos(int left, int top) const
|
|||
|
||||
if (cdh >= 0)
|
||||
{
|
||||
top_pos += points_to_pixels(cdh, 96.0);
|
||||
top_pos += points_to_pixels(cdh, 96.0L);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -938,7 +939,7 @@ worksheet::iterator worksheet::begin()
|
|||
cell_reference top_right(dimensions.get_bottom_right().get_column_index(), dimensions.get_top_left().get_row());
|
||||
range_reference row_range(dimensions.get_top_left(), top_right);
|
||||
|
||||
return iterator(*this, row_range, major_order::row);
|
||||
return iterator(*this, row_range, dimensions, major_order::row);
|
||||
}
|
||||
|
||||
worksheet::iterator worksheet::end()
|
||||
|
@ -948,7 +949,7 @@ worksheet::iterator worksheet::end()
|
|||
cell_reference bottom_left(dimensions.get_top_left().get_column_index(), past_end_row_index);
|
||||
cell_reference bottom_right(dimensions.get_bottom_right().get_column_index(), past_end_row_index);
|
||||
|
||||
return iterator(*this, range_reference(bottom_left, bottom_right), major_order::row);
|
||||
return iterator(*this, range_reference(bottom_left, bottom_right), dimensions, major_order::row);
|
||||
}
|
||||
|
||||
worksheet::const_iterator worksheet::cbegin() const
|
||||
|
|
|
@ -73,7 +73,7 @@ source_group(runner FILES ${RUNNER})
|
|||
target_link_libraries(${PROJECT_NAME} ${LIBRARY_NAME})
|
||||
|
||||
if(MSVC)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/wd\"4251\" /wd\"4275\"")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/wd\"4251\" /wd\"4275\" /wd\"4068\"")
|
||||
# Needed for PathFileExists in path_helper
|
||||
target_link_libraries(${PROJECT_NAME} Shlwapi)
|
||||
else()
|
||||
|
|
12
third-party/CMakeLists.txt
vendored
12
third-party/CMakeLists.txt
vendored
|
@ -4,7 +4,6 @@ project(${LIBRARY_NAME}.third-party VERSION ${LIBRARY_VERSION} LANGUAGES CXX C)
|
|||
# Includes
|
||||
include_directories(libstudxml
|
||||
utfcpp/source
|
||||
pole
|
||||
botan
|
||||
zlib
|
||||
${LIBRARY_SOURCE_DIR}/detail)
|
||||
|
@ -47,17 +46,13 @@ set(GENX
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/libstudxml/xml/details/genx/genx.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libstudxml/xml/details/genx/genx.h)
|
||||
|
||||
set(POLE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pole/pole.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pole/pole.h)
|
||||
|
||||
set(BOTAN
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/botan/botan_all.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/botan/botan_all_internal.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/botan/botan_all.h)
|
||||
|
||||
if(MSVC)
|
||||
set_source_files_properties(${BOTAN} PROPERTIES COMPILE_FLAGS "/wd\"4244\"")
|
||||
set_source_files_properties(${BOTAN} PROPERTIES COMPILE_FLAGS "/wd\"4244\" /wd\"4267\"")
|
||||
endif()
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
@ -95,9 +90,11 @@ set(ZLIB ${CMAKE_CURRENT_SOURCE_DIR}/zlib/adler32.c
|
|||
|
||||
if(NOT MSVC)
|
||||
set_source_files_properties(${ZLIB} PROPERTIES COMPILE_FLAGS "-Wno-implicit-function-declaration")
|
||||
else()
|
||||
set_source_files_properties(${ZLIB} PROPERTIES COMPILE_FLAGS "/wd\"4018\"")
|
||||
endif()
|
||||
|
||||
add_library(xlnt.third-party OBJECT ${LIBSTUDXML} ${GENX} ${EXPAT} ${POLE} ${BOTAN} ${ZLIB})
|
||||
add_library(xlnt.third-party OBJECT ${LIBSTUDXML} ${GENX} ${EXPAT} ${BOTAN} ${ZLIB})
|
||||
target_compile_definitions(xlnt.third-party PRIVATE LIBSTUDXML_STATIC_LIB=1)
|
||||
|
||||
if(NOT STATIC)
|
||||
|
@ -114,5 +111,4 @@ source_group(botan FILES ${BOTAN})
|
|||
source_group(libstudxml FILES ${LIBSTUDXML})
|
||||
source_group(libstudxml\\genx FILES ${GENX})
|
||||
source_group(libstudxml\\expat FILES ${EXPAT})
|
||||
source_group(pole FILES ${POLE})
|
||||
source_group(zlib FILES ${ZLIB})
|
||||
|
|
2
third-party/botan
vendored
2
third-party/botan
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 523b2a4ca48fa5cf04ea371aabe7167ce2e5cd13
|
||||
Subproject commit e6bf87b6b0d4d9c3877b79de53de58dc34a3acca
|
1
third-party/pole/AUTHORS
vendored
1
third-party/pole/AUTHORS
vendored
|
@ -1 +0,0 @@
|
|||
Ariya Hidayat <ariya@kde.org>
|
21
third-party/pole/COMPILERS.txt
vendored
21
third-party/pole/COMPILERS.txt
vendored
|
@ -1,21 +0,0 @@
|
|||
|
||||
Borland C++ Compiler 5.5.1
|
||||
------------------------------
|
||||
The command-line Borland C++ Compiler version 5.5.1 is available for free
|
||||
(as 'free' in 'free beer') from:
|
||||
http://www.borland.com/products/downloads/download_cbuilder.html
|
||||
|
||||
OpenWatcom 1.3
|
||||
------------------------------
|
||||
OpenWatcom 1.3 does not have STL implementation, therefore you need to
|
||||
install STLport (tested with version 4.6, earlier version may or may not
|
||||
work). Because mainstream STLport can not be used directly with OpenWatcom,
|
||||
please download and use the patched version from this site:
|
||||
http://www.ecet.vtc.edu/~pchapin/OW/index.html
|
||||
|
||||
Digital Mars 8.41n
|
||||
-------------------------------
|
||||
Digital Mars command-line C/C++ compilers are available for download
|
||||
from http://www.digitalmars.com. STLport is required and must be
|
||||
installed as well.
|
||||
|
24
third-party/pole/ChangeLog
vendored
24
third-party/pole/ChangeLog
vendored
|
@ -1,24 +0,0 @@
|
|||
POLE 0.3
|
||||
|
||||
* changed license to two-clause BSD license
|
||||
* fixed potential lock-up on corrupted file, bug reported by
|
||||
Andrew Ziem <ahziem1@mailbolt.com>
|
||||
* fixed error reading very huge file (larger than 13 MB)
|
||||
* ported POLEView to Qt 4, making it available also for Windows
|
||||
* assorted user-interface improvements in POLEView
|
||||
|
||||
POLE 0.2 (released March 2005)
|
||||
|
||||
* changed license to BSD license
|
||||
* poleview: graphical tool to view a structured storage
|
||||
* fixed occasional incorrect reading of big file
|
||||
* fixed rare memory problem, found by valgrind
|
||||
* fixed compile with Microsoft Visual C++ and Borland C++ (Windows)
|
||||
* modified storage to become stateless (with better API)
|
||||
* performance improvement, especially with very large file
|
||||
|
||||
POLE 0.1 (released March 2004)
|
||||
|
||||
* initial release
|
||||
* support for reading structured storages, even large ones
|
||||
* no support yet for creating or modifying a storage
|
25
third-party/pole/LICENSE
vendored
25
third-party/pole/LICENSE
vendored
|
@ -1,25 +0,0 @@
|
|||
POLE - Portable C++ library to access OLE Storage
|
||||
Copyright (C) 2002-2007 Ariya Hidayat (ariya@kde.org). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
72
third-party/pole/README
vendored
72
third-party/pole/README
vendored
|
@ -1,72 +0,0 @@
|
|||
POLE - portable library for structured storage
|
||||
|
||||
POLE is a portable C++ library to create and read structured storage. With a
|
||||
structured storage, you can store files inside another file, or you can even
|
||||
create complex directory tree, if you want to. The structured storage created by
|
||||
POLE is compatible with Microsoft structured storage, also sometimes called as
|
||||
OLE Compound Document, which are used among others in Microsoft Office. However,
|
||||
POLE has the advantage that it's portable (i.e you can read or write a
|
||||
structured storage in any supported platform), you don't need to rely on Windows
|
||||
library.
|
||||
|
||||
Download
|
||||
==========
|
||||
|
||||
Source code is available at http://developer.berlios.de/projects/pole/.
|
||||
Please always use the latest stable version.
|
||||
|
||||
Install
|
||||
========
|
||||
|
||||
To compile POLE, you need a C++ compiler, with standard C++ library which
|
||||
supports STL (Standard Template Library). On Linux and other Unices, g++ will do
|
||||
the job.
|
||||
|
||||
POLE is just a library, you have to integrate it as part of your
|
||||
application/project. Since it consists of one source file and one header file,
|
||||
it doesn't make much sense to compile POLE as separate library (either static or
|
||||
dynamic). Simply add these files to your project and you're done.
|
||||
|
||||
The source tarball of POLE demonstrates the use of POLE to build poledump, a
|
||||
small utility to extract any stream inside a structured storage. If you use g++
|
||||
as the compiler, you can compile poledump using the following command:
|
||||
|
||||
g++ -o poledump pole.cpp poledump.cpp
|
||||
|
||||
You may use poledump like the example below:
|
||||
|
||||
poledump budget.xls Workbook result.xls
|
||||
|
||||
The above command will extract a stream named Workbook inside Excel document
|
||||
(budget.xls) and save it as result.xls. File result.xls will still be recognized
|
||||
as a valid workbook (in raw format). Launch Microsoft Excel, open this file, and
|
||||
convince yourself.
|
||||
|
||||
Copyright and License
|
||||
=====================
|
||||
|
||||
POLE - Portable C++ library to access OLE Storage
|
||||
Copyright (C) 2002-2007 Ariya Hidayat (ariya@kde.org). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
2
third-party/pugixml
vendored
2
third-party/pugixml
vendored
|
@ -1 +1 @@
|
|||
Subproject commit a832e8a5eff11f58a00ca41ec51ff3895b0da165
|
||||
Subproject commit e4c43a0aa2d5cbc158dd279cb2bf6d21f2d27c83
|
2
third-party/utfcpp
vendored
2
third-party/utfcpp
vendored
|
@ -1 +1 @@
|
|||
Subproject commit a5ad5ec9d936d63e9c010d1054f8b11fed0fabbc
|
||||
Subproject commit 0232ab8188b16ae6f2293a5817f1d9b0030879a3
|
Loading…
Reference in New Issue
Block a user