Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move Chunk class to Lwo2Chunk and into separate file pair.
Refactoring and cleanup. Adjust Makefile.am.
- Loading branch information
1 parent
57ab1bd
commit e68ba42
Showing
7 changed files
with
204 additions
and
196 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#include "Lwo2Chunk.h" | ||
|
||
#include "bytestreamutils.h" | ||
|
||
namespace model | ||
{ | ||
|
||
Lwo2Chunk::Lwo2Chunk(const std::string& identifier_, Type type) : | ||
_chunkType(type), | ||
identifier(identifier_), | ||
stream(std::ios_base::in | std::ios_base::out | std::ios_base::binary) | ||
{ | ||
// FORM sub-chunks are normal chunks and have 4 bytes size info | ||
// whereas subchunks of e.g. CLIP use 2 bytes of size info | ||
_sizeDescriptorByteCount = _chunkType == Type::Chunk ? 4 : 2; | ||
} | ||
|
||
unsigned int Lwo2Chunk::getContentSize() const | ||
{ | ||
unsigned int totalSize = 0; | ||
|
||
// Start with the size of the contents | ||
// (don't use seek as we don't know if the client still wants to write stuff) | ||
totalSize += static_cast<unsigned int>(stream.str().length()); | ||
|
||
if (!subChunks.empty()) | ||
{ | ||
// Sum up the size of the subchunks | ||
for (const Lwo2Chunk::Ptr& chunk : subChunks) | ||
{ | ||
totalSize += 4; // ID (4 bytes) | ||
totalSize += chunk->_sizeDescriptorByteCount; // Subchunk Size Info (can be 4 or 2 bytes) | ||
|
||
// While the child chunk size itself doesn't include padding, we need to respect | ||
// it when calculating the size of this parent chunk | ||
unsigned int childChunkSize = chunk->getContentSize(); | ||
totalSize += childChunkSize + (childChunkSize % 2); // add 1 padding byte if odd | ||
} | ||
} | ||
|
||
// Chunk size can be odd, padding must be handled by client code | ||
return totalSize; | ||
} | ||
|
||
Lwo2Chunk::Ptr Lwo2Chunk::addChunk(const std::string& identifier_, Type type) | ||
{ | ||
subChunks.push_back(std::make_shared<Lwo2Chunk>(identifier_, type)); | ||
return subChunks.back(); | ||
} | ||
|
||
void Lwo2Chunk::flushBuffer() | ||
{ | ||
stream.flush(); | ||
|
||
for (const Lwo2Chunk::Ptr& chunk : subChunks) | ||
{ | ||
chunk->flushBuffer(); | ||
} | ||
} | ||
|
||
void Lwo2Chunk::writeToStream(std::ostream& output) | ||
{ | ||
// Flush all buffers before writing to the output stream | ||
flushBuffer(); | ||
|
||
output.write(identifier.c_str(), identifier.length()); | ||
|
||
if (_chunkType == Type::Chunk) | ||
{ | ||
stream::writeBigEndian<uint32_t>(output, getContentSize()); | ||
} | ||
else | ||
{ | ||
stream::writeBigEndian<uint16_t>(output, getContentSize()); | ||
} | ||
|
||
// Write the direct contents of this chunk | ||
std::string str = stream.str(); | ||
output.write(str.c_str(), str.length()); | ||
|
||
// Write all subchunks | ||
for (const Lwo2Chunk::Ptr& chunk : subChunks) | ||
{ | ||
chunk->writeToStream(output); | ||
|
||
// Add the padding byte after the chunk | ||
if (chunk->getContentSize() % 2 == 1) | ||
{ | ||
output.write("\0", 1); | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <memory> | ||
#include <vector> | ||
#include <sstream> | ||
|
||
namespace model | ||
{ | ||
|
||
// Represents a Chunk in the LWO2 file, accepting content | ||
// through the public stream member. | ||
// A Chunk can have contents and/or 1 or more subchunks. | ||
class Lwo2Chunk | ||
{ | ||
public: | ||
typedef std::shared_ptr<Lwo2Chunk> Ptr; | ||
|
||
enum class Type | ||
{ | ||
Chunk, | ||
SubChunk | ||
}; | ||
|
||
private: | ||
Type _chunkType; | ||
|
||
// The number of bytes used for the size info of this chunk | ||
unsigned int _sizeDescriptorByteCount; | ||
|
||
public: | ||
std::string identifier; // the 4-byte ID | ||
|
||
// Child chunks | ||
std::vector<Lwo2Chunk::Ptr> subChunks; | ||
|
||
// Stream binary data into here | ||
std::stringstream stream; | ||
|
||
Lwo2Chunk(const std::string& identifier_, Type type); | ||
|
||
// Returns the size of this Chunk's content | ||
// excluding this Chunk's ID (4 bytes) and Size info (4 bytes) | ||
unsigned int getContentSize() const; | ||
|
||
// Adds the specified empty Chunk and returns its reference | ||
Lwo2Chunk::Ptr addChunk(const std::string& identifier_, Type type); | ||
|
||
void flushBuffer(); | ||
|
||
void writeToStream(std::ostream& output); | ||
}; | ||
|
||
} |
Oops, something went wrong.