2 * \file storage_chunks.cpp
3 * \brief CStorageChunks
4 * \date 2012-08-18 09:20GMT
5 * \author Jan Boon (Kaetemi)
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"
34 #include <nel/misc/debug.h>
38 // using namespace std;
39 // using namespace NLMISC;
41 // #define NL_DEBUG_STORAGE
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");
52 m_Chunks
[0].HeaderSize
= 0;
53 m_Chunks
[0].OffsetBegin
= stream
.getPos();
54 if (stream
.isReading())
57 m_Chunks
[0].Size
= 0x80000000 | (uint32
)(size
);
66 CStorageChunks::~CStorageChunks()
68 #ifdef NL_DEBUG_STORAGE
69 if (m_Chunks
.size() != 1)
70 nldebug("Not all chunks were closed");
74 bool CStorageChunks::enterChunk()
76 if (m_Stream
.isReading())
79 if (!isChunkContainer())
81 #ifdef NL_DEBUG_STORAGE
82 nldebug("Current chunk is not a container, cannot enter");
88 #ifdef NL_DEBUG_STORAGE
89 nldebug("End of chunk, cannot enter");
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;
101 // this is a 64bit chunk
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
);
121 #ifdef NL_DEBUG_STORAGE
122 nldebug("No input, this function cannot output, throw exception");
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");
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
147 m_Stream
.serial(id
); // write the id
148 m_Stream
.serial(sizeDummy
); // write 32 bit size placeholder
151 else // input or exception
155 if (getChunkId() == id
)
157 leaveChunk(); // skip data
163 sint32
CStorageChunks::leaveChunk()
165 if (m_Stream
.isReading())
168 sint32 skipped
= currentChunk()->endOfChunk() - m_Stream
.getPos();
171 m_Stream
.seek(currentChunk()->endOfChunk(), NLMISC::IStream::begin
);
172 #ifdef NL_DEBUG_STORAGE
173 nldebug("Skipped %i bytes in the current chunk", skipped
);
176 m_Chunks
.resize(m_Chunks
.size() - 1);
181 #ifdef NL_DEBUG_STORAGE
182 nldebug("Writing, leave chunk");
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
);
195 return sizeWithHeader
;
199 } /* namespace MAX */
200 } /* namespace PIPELINE */