Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / tools / 3d / pipeline_max / storage_chunks.cpp
blobb8cfbbd03bcebcf602d97bf4a84e42d6807191e0
1 /**
2 * \file storage_chunks.cpp
3 * \brief CStorageChunks
4 * \date 2012-08-18 09:20GMT
5 * \author Jan Boon (Kaetemi)
6 * CStorageChunks
7 */
9 /*
10 * Copyright (C) 2012 by authors
12 * This file is part of RYZOM CORE PIPELINE.
13 * RYZOM CORE PIPELINE is free software: you can redistribute it
14 * and/or modify it under the terms of the GNU Affero General Public
15 * License as published by the Free Software Foundation, either
16 * version 3 of the License, or (at your option) any later version.
18 * RYZOM CORE PIPELINE is distributed in the hope that it will be
19 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
20 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Affero General Public License for more details.
23 * You should have received a copy of the GNU Affero General Public
24 * License along with RYZOM CORE PIPELINE. If not, see
25 * <http://www.gnu.org/licenses/>.
28 #include <nel/misc/types_nl.h>
29 #include "storage_chunks.h"
31 // STL includes
33 // NeL includes
34 #include <nel/misc/debug.h>
36 // Project includes
38 // using namespace std;
39 // using namespace NLMISC;
41 // #define NL_DEBUG_STORAGE
43 namespace PIPELINE {
44 namespace MAX {
46 CStorageChunks::CStorageChunks(NLMISC::IStream &stream, sint64 size) : m_Stream(stream), m_Is64Bit(false)
48 if (size >= 2147483647L)
49 throw NLMISC::EStream("64bit chunks not supported");
50 m_Chunks.reserve(64);
51 m_Chunks.resize(1);
52 m_Chunks[0].HeaderSize = 0;
53 m_Chunks[0].OffsetBegin = stream.getPos();
54 if (stream.isReading())
56 m_Chunks[0].Id = 0;
57 m_Chunks[0].Size = 0x80000000 | (uint32)(size);
59 else
61 m_Chunks[0].Id = 1;
62 m_Chunks[0].Size = 0;
66 CStorageChunks::~CStorageChunks()
68 #ifdef NL_DEBUG_STORAGE
69 if (m_Chunks.size() != 1)
70 nldebug("Not all chunks were closed");
71 #endif
74 bool CStorageChunks::enterChunk()
76 if (m_Stream.isReading())
78 // input logic
79 if (!isChunkContainer())
81 #ifdef NL_DEBUG_STORAGE
82 nldebug("Current chunk is not a container, cannot enter");
83 #endif
84 return false;
86 if (endOfChunk())
88 #ifdef NL_DEBUG_STORAGE
89 nldebug("End of chunk, cannot enter");
90 #endif
91 return false;
93 m_Chunks.resize(m_Chunks.size() + 1);
94 CChunk *chunk = currentChunk();
95 chunk->OffsetBegin = m_Stream.getPos();
96 m_Stream.serial(chunk->Id);
97 m_Stream.serial(chunk->Size);
98 chunk->HeaderSize = 6;
99 if (chunk->Size == 0)
101 // this is a 64bit chunk
102 uint64 size64;
103 m_Stream.serial(size64);
104 chunk->HeaderSize += 8;
105 bool iscont = (size64 & 0x8000000000000000) == 0x8000000000000000;
106 size64 &= 0x7FFFFFFFFFFFFFFF;
107 if (size64 >= 2147483647L)
108 throw NLMISC::EStream("64bit chunks not supported");
109 // downgrade to 32 bit chunk
110 chunk->Size = (uint32)size64;
111 if (iscont) chunk->Size |= 0x80000000;
112 m_Is64Bit = true; // it's true
114 #ifdef NL_DEBUG_STORAGE
115 nldebug("Entered reading chunk of size %i", chunk->Size);
116 #endif
117 return true;
119 else
121 #ifdef NL_DEBUG_STORAGE
122 nldebug("No input, this function cannot output, throw exception");
123 #endif
124 throw NLMISC::EStream();
128 bool CStorageChunks::enterChunk(uint16 id, bool container)
130 if (!m_Stream.isReading())
132 #ifdef NL_DEBUG_STORAGE
133 nldebug("Writing, enter chunk");
134 #endif
136 if (m_Is64Bit)
137 throw NLMISC::EStream("64bit chunks not supported");
139 // enter the new chunk
140 m_Chunks.resize(m_Chunks.size() + 1);
141 CChunk *chunk = currentChunk();
142 uint32 sizeDummy = 0xFFFFFFFF;
143 chunk->Id = container ? 1 : 0;
144 chunk->OffsetBegin = m_Stream.getPos(); // store current pos
146 // write header
147 m_Stream.serial(id); // write the id
148 m_Stream.serial(sizeDummy); // write 32 bit size placeholder
149 return true;
151 else // input or exception
153 while (enterChunk())
155 if (getChunkId() == id)
156 return true;
157 leaveChunk(); // skip data
159 return false;
163 sint32 CStorageChunks::leaveChunk()
165 if (m_Stream.isReading())
167 // input logic
168 sint32 skipped = currentChunk()->endOfChunk() - m_Stream.getPos();
169 if (skipped)
171 m_Stream.seek(currentChunk()->endOfChunk(), NLMISC::IStream::begin);
172 #ifdef NL_DEBUG_STORAGE
173 nldebug("Skipped %i bytes in the current chunk", skipped);
174 #endif
176 m_Chunks.resize(m_Chunks.size() - 1);
177 return skipped;
179 else
181 #ifdef NL_DEBUG_STORAGE
182 nldebug("Writing, leave chunk");
183 #endif
184 sint32 pos = m_Stream.getPos();
185 sint32 sizeWithHeader = pos - currentChunk()->OffsetBegin;
186 sint32 sizePos = currentChunk()->OffsetBegin + 2;
187 m_Stream.seek(sizePos, NLMISC::IStream::begin); // hopefully this correctly overwrites!!!
188 uint32 sizeField = (uint32)sizeWithHeader | (uint32)currentChunk()->Id << 31; // add container flag
189 m_Stream.serial(sizeField);
190 m_Stream.seek(pos, NLMISC::IStream::begin);
191 m_Chunks.resize(m_Chunks.size() - 1);
192 #ifdef NL_DEBUG_STORAGE
193 nldebug("Size: %i, Field: %x", sizeWithHeader, sizeField);
194 #endif
195 return sizeWithHeader;
199 } /* namespace MAX */
200 } /* namespace PIPELINE */
202 /* end of file */