1/*
2Open Asset Import Library (assimp)
3----------------------------------------------------------------------
4
5Copyright (c) 2006-2017, assimp team
6
7All rights reserved.
8
9Redistribution and use of this software in source and binary forms,
10with or without modification, are permitted provided that the
11following conditions are met:
12
13* Redistributions of source code must retain the above
14copyright notice, this list of conditions and the
15following disclaimer.
16
17* Redistributions in binary form must reproduce the above
18copyright notice, this list of conditions and the
19following disclaimer in the documentation and/or other
20materials provided with the distribution.
21
22* Neither the name of the assimp team, nor the names of its
23contributors may be used to endorse or promote products
24derived from this software without specific prior
25written permission of the assimp team.
26
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39----------------------------------------------------------------------
40*/
41
42#ifndef INCLUDED_AI_IRRXML_WRAPPER
43#define INCLUDED_AI_IRRXML_WRAPPER
44
45// some long includes ....
46#include <irrXML.h>
47#include "./../include/assimp/IOStream.hpp"
48#include "BaseImporter.h"
49#include <vector>
50
51namespace Assimp {
52
53// ---------------------------------------------------------------------------------
54/** @brief Utility class to make IrrXML work together with our custom IO system
55 * See the IrrXML docs for more details.
56 *
57 * Construct IrrXML-Reader in BaseImporter::InternReadFile():
58 * @code
59 * // open the file
60 * std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
61 * if( file.get() == NULL) {
62 * throw DeadlyImportError( "Failed to open file " + pFile + ".");
63 * }
64 *
65 * // generate a XML reader for it
66 * std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
67 * mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
68 * if( !mReader) {
69 * ThrowException( "xxxx: Unable to open file.");
70 * }
71 * @endcode
72 **/
73class CIrrXML_IOStreamReader : public irr::io::IFileReadCallBack {
74public:
75
76 // ----------------------------------------------------------------------------------
77 //! Construction from an existing IOStream
78 explicit CIrrXML_IOStreamReader(IOStream* _stream)
79 : stream (_stream)
80 , t (0)
81 {
82
83 // Map the buffer into memory and convert it to UTF8. IrrXML provides its
84 // own conversion, which is merely a cast from uintNN_t to uint8_t. Thus,
85 // it is not suitable for our purposes and we have to do it BEFORE IrrXML
86 // gets the buffer. Sadly, this forces us to map the whole file into
87 // memory.
88
89 data.resize(stream->FileSize());
90 stream->Read(&data[0],data.size(),1);
91
92 // Remove null characters from the input sequence otherwise the parsing will utterly fail
93 unsigned int size = 0;
94 unsigned int size_max = static_cast<unsigned int>(data.size());
95 for(unsigned int i = 0; i < size_max; i++) {
96 if(data[i] != '\0') {
97 data[size++] = data[i];
98 }
99 }
100 data.resize(size);
101
102 BaseImporter::ConvertToUTF8(data);
103 }
104
105 // ----------------------------------------------------------------------------------
106 //! Virtual destructor
107 virtual ~CIrrXML_IOStreamReader() {}
108
109 // ----------------------------------------------------------------------------------
110 //! Reads an amount of bytes from the file.
111 /** @param buffer: Pointer to output buffer.
112 * @param sizeToRead: Amount of bytes to read
113 * @return Returns how much bytes were read. */
114 virtual int read(void* buffer, int sizeToRead) {
115 if(sizeToRead<0) {
116 return 0;
117 }
118 if(t+sizeToRead>data.size()) {
119 sizeToRead = static_cast<int>(data.size()-t);
120 }
121
122 memcpy(buffer,&data.front()+t,sizeToRead);
123
124 t += sizeToRead;
125 return sizeToRead;
126 }
127
128 // ----------------------------------------------------------------------------------
129 //! Returns size of file in bytes
130 virtual int getSize() {
131 return (int)data.size();
132 }
133
134private:
135 IOStream* stream;
136 std::vector<char> data;
137 size_t t;
138
139}; // ! class CIrrXML_IOStreamReader
140
141} // ! Assimp
142
143#endif // !! INCLUDED_AI_IRRXML_WRAPPER
144