Added: #1440 Max file utility library
--HG-- branch : build_pipeline_v3hg/feature/build_pipeline_v3
parent
4e35b4f551
commit
4b1a310dfb
@ -0,0 +1,39 @@
|
||||
|
||||
FIND_PACKAGE(LIBGSF)
|
||||
|
||||
IF (NOT (LIBGSF_INCLUDE_DIR AND LIBGSF_LIBRARIES))
|
||||
MESSAGE(FATAL_ERROR "LIBGSF not found!")
|
||||
ENDIF (NOT (LIBGSF_INCLUDE_DIR AND LIBGSF_LIBRARIES))
|
||||
|
||||
FIND_PACKAGE(GLIB2)
|
||||
|
||||
if (NOT GLIB2_FOUND)
|
||||
MESSAGE(FATAL_ERROR "GLIB2 not found!")
|
||||
ENDIF (NOT GLIB2_FOUND)
|
||||
|
||||
INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${LIBGSF_INCLUDE_DIR})
|
||||
|
||||
FILE(GLOB SRCS *.cpp)
|
||||
FILE(GLOB HDRS *.h)
|
||||
|
||||
NL_TARGET_LIB(pipeline_max
|
||||
${SRCS}
|
||||
${HDRS}
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(pipeline_max
|
||||
${LIBGSF_LIBRARIES}
|
||||
${GLIB2_LIBRARIES}
|
||||
nelmisc
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(pipeline_max PROPERTIES LINK_INTERFACE_LIBRARIES "")
|
||||
|
||||
NL_DEFAULT_PROPS(pipeline_max "NeL, Tools, Pipeline: Max (Library)")
|
||||
NL_ADD_LIB_SUFFIX(pipeline_max)
|
||||
NL_ADD_RUNTIME_FLAGS(pipeline_max)
|
||||
|
||||
IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC)
|
||||
INSTALL(TARGETS pipeline_max LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries)
|
||||
ENDIF((WITH_INSTALL_LIBRARIES AND WITH_STATIC) OR NOT WITH_STATIC)
|
@ -0,0 +1,236 @@
|
||||
/**
|
||||
* \file storage_stream.cpp
|
||||
* \brief CStorageStream
|
||||
* \date 2012-08-16 22:06GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStorageStream
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 by authors
|
||||
*
|
||||
* This file is part of RYZOM CORE PIPELINE.
|
||||
* RYZOM CORE PIPELINE is free software: you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Affero General Public
|
||||
* License as published by the Free Software Foundation, either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RYZOM CORE PIPELINE is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with RYZOM CORE PIPELINE. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "storage_stream.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// 3rd Party includes
|
||||
#include <gsf/gsf-input-stdio.h>
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
|
||||
// Project includes
|
||||
|
||||
using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
// #define NL_DEBUG_STORAGE_STREAM
|
||||
|
||||
namespace PIPELINE {
|
||||
namespace MAX {
|
||||
|
||||
CStorageStream::CStorageStream(GsfInput *input) : NLMISC::IStream(true), m_Input(input), m_Output(NULL), m_Is64Bit(false)
|
||||
{
|
||||
m_Chunks.reserve(64);
|
||||
m_Chunks.resize(1);
|
||||
m_Chunks[0].OffsetBegin = -6;
|
||||
m_Chunks[0].Id = 0;
|
||||
m_Chunks[0].Size = 0x80000000;
|
||||
}
|
||||
|
||||
CStorageStream::~CStorageStream()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CStorageStream::seek(sint32 offset, NLMISC::IStream::TSeekOrigin origin) const
|
||||
{
|
||||
if (m_Input)
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case begin:
|
||||
return gsf_input_seek(m_Input, offset, G_SEEK_SET);
|
||||
case current:
|
||||
return gsf_input_seek(m_Input, offset, G_SEEK_CUR);
|
||||
case end:
|
||||
return gsf_input_seek(m_Input, offset, G_SEEK_END);
|
||||
}
|
||||
}
|
||||
return NLMISC::IStream::seek(offset, origin);
|
||||
}
|
||||
|
||||
sint32 CStorageStream::getPos() const
|
||||
{
|
||||
if (m_Input)
|
||||
{
|
||||
gsf_off_t res = gsf_input_tell(m_Input);
|
||||
if (res < 2147483647L) // exception when larger
|
||||
return (sint32)res;
|
||||
}
|
||||
return NLMISC::IStream::getPos();
|
||||
}
|
||||
|
||||
void CStorageStream::serialBuffer(uint8 *buf, uint len)
|
||||
{
|
||||
if (!len)
|
||||
{
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("Serial 0 size buffer");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (m_Input)
|
||||
{
|
||||
if (!gsf_input_read(m_Input, len, buf))
|
||||
{
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("Cannot read from input, throw exception");
|
||||
#endif
|
||||
throw NLMISC::EStream();
|
||||
}
|
||||
}
|
||||
else if (m_Output)
|
||||
{
|
||||
throw NLMISC::EStream(); // not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("No input or output, should not happen, throw exception");
|
||||
#endif
|
||||
throw NLMISC::EStream();
|
||||
}
|
||||
}
|
||||
|
||||
void CStorageStream::serialBit(bool &bit)
|
||||
{
|
||||
uint8 var = (uint8)bit;
|
||||
serial(var);
|
||||
bit = (bool)var;
|
||||
}
|
||||
|
||||
bool CStorageStream::eof()
|
||||
{
|
||||
return gsf_input_eof(m_Input);
|
||||
}
|
||||
|
||||
bool CStorageStream::enterChunk()
|
||||
{
|
||||
if (m_Input)
|
||||
{
|
||||
// input logic
|
||||
if (!isChunkContainer())
|
||||
{
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("Current chunk is not a container, cannot enter");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
if (endOfChunk())
|
||||
{
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("End of chunk, cannot enter");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
m_Chunks.resize(m_Chunks.size() + 1);
|
||||
CChunk *chunk = currentChunk();
|
||||
chunk->OffsetBegin = CStorageStream::getPos();
|
||||
serial(chunk->Id);
|
||||
serial(chunk->Size);
|
||||
chunk->HeaderSize = 6;
|
||||
if (chunk->Size == 0)
|
||||
{
|
||||
// this is a 64bit chunk
|
||||
uint64 size64;
|
||||
serial(size64);
|
||||
chunk->HeaderSize += 8;
|
||||
bool iscont = (size64 & 0x8000000000000000) == 0x8000000000000000;
|
||||
size64 &= 0x7FFFFFFFFFFFFFFF;
|
||||
if (size64 >= 2147483647L)
|
||||
throw NLMISC::EStream("64bit chunks not supported");
|
||||
// downgrade to 32 bit chunk
|
||||
chunk->Size = (uint32)size64;
|
||||
if (iscont) chunk->Size |= 0x80000000;
|
||||
m_Is64Bit = true; // it's true
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("No input, this function cannot output, throw exception");
|
||||
#endif
|
||||
throw NLMISC::EStream();
|
||||
}
|
||||
}
|
||||
|
||||
bool CStorageStream::enterChunk(uint16 id)
|
||||
{
|
||||
if (m_Output)
|
||||
{
|
||||
throw NLMISC::EStream(); // not yet implemented
|
||||
}
|
||||
else // input or exception
|
||||
{
|
||||
while (enterChunk())
|
||||
{
|
||||
if (getChunkId() == id)
|
||||
return true;
|
||||
leaveChunk(); // skip data
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sint32 CStorageStream::leaveChunk()
|
||||
{
|
||||
if (m_Input)
|
||||
{
|
||||
// input logic
|
||||
sint32 skipped = currentChunk()->endOfChunk() - CStorageStream::getPos();
|
||||
if (skipped)
|
||||
{
|
||||
CStorageStream::seek(currentChunk()->endOfChunk(), begin);
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("Skipped %i bytes in the current chunk", skipped);
|
||||
#endif
|
||||
}
|
||||
m_Chunks.resize(m_Chunks.size() - 1);
|
||||
return skipped;
|
||||
}
|
||||
else if (m_Output)
|
||||
{
|
||||
throw NLMISC::EStream(); // not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef NL_DEBUG_STORAGE_STREAM
|
||||
nldebug("No input or output, should not happen, throw exception");
|
||||
#endif
|
||||
throw NLMISC::EStream();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace MAX */
|
||||
} /* namespace PIPELINE */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* \file storage_stream.h
|
||||
* \brief CStorageStream
|
||||
* \date 2012-08-16 22:06GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStorageStream
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012 by authors
|
||||
*
|
||||
* This file is part of RYZOM CORE PIPELINE.
|
||||
* RYZOM CORE PIPELINE is free software: you can redistribute it
|
||||
* and/or modify it under the terms of the GNU Affero General Public
|
||||
* License as published by the Free Software Foundation, either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RYZOM CORE PIPELINE is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with RYZOM CORE PIPELINE. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIPELINE_STORAGE_STREAM_H
|
||||
#define PIPELINE_STORAGE_STREAM_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
#include <map>
|
||||
|
||||
// 3rd Party includes
|
||||
#include <gsf/gsf-infile.h>
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/stream.h>
|
||||
|
||||
// Project includes
|
||||
|
||||
namespace PIPELINE {
|
||||
namespace MAX {
|
||||
|
||||
/**
|
||||
* \brief CStorageStream
|
||||
* \date 2012-08-16 22:06GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CStorageStream
|
||||
*/
|
||||
class CStorageStream : public NLMISC::IStream
|
||||
{
|
||||
private:
|
||||
struct CChunk
|
||||
{
|
||||
// Size of the chunk header, 6 for 32 bit, 14 for 64 bit
|
||||
uint8 HeaderSize;
|
||||
// Where the header starts
|
||||
sint32 OffsetBegin;
|
||||
|
||||
// Identifier
|
||||
uint16 Id;
|
||||
// Size including header size
|
||||
uint32 Size;
|
||||
|
||||
inline sint32 getSizeWithHeader() { return (sint32)(Size & 0x7FFFFFFF); }
|
||||
inline sint32 getSize() { return getSizeWithHeader() - (sint32)HeaderSize; }
|
||||
inline bool isContainer() { return (Size & 0x80000000) == 0x80000000; }
|
||||
inline sint32 endOfChunk() { return OffsetBegin + getSizeWithHeader(); }
|
||||
inline sint32 getDataBegin() { return OffsetBegin + (sint32)HeaderSize; }
|
||||
};
|
||||
|
||||
public:
|
||||
CStorageStream(GsfInput *input);
|
||||
virtual ~CStorageStream();
|
||||
|
||||
virtual bool seek(sint32 offset, TSeekOrigin origin) const;
|
||||
virtual sint32 getPos() const;
|
||||
// virtual std::string getStreamName() const; // char const * gsf_input_name (GsfInput *input);
|
||||
virtual void serialBuffer(uint8 *buf, uint len);
|
||||
virtual void serialBit(bool &bit);
|
||||
|
||||
bool eof();
|
||||
|
||||
// Returns true if there's another chunk, false if no more chunks in this container or if the current chunk is not a container
|
||||
bool enterChunk();
|
||||
// Reads and skips chunks until the one with given id is found, or writes a chunk with this id
|
||||
bool enterChunk(uint16 id);
|
||||
// Returns the number of skipped bytes in read more, returns chunk size including header in write mode
|
||||
sint32 leaveChunk();
|
||||
|
||||
inline bool is64Bit() const { return m_Is64Bit; }
|
||||
inline void set64Bit(bool enabled = true) { m_Is64Bit = enabled; }
|
||||
|
||||
inline uint16 getChunkId() { return currentChunk()->Id; }
|
||||
inline sint32 getChunkSize() { return currentChunk()->getSize(); }
|
||||
inline bool isChunkContainer() { return currentChunk()->isContainer(); }
|
||||
inline bool endOfChunk() { return m_Chunks.size() == 1 ? eof() : CStorageStream::getPos() >= currentChunk()->endOfChunk(); }
|
||||
|
||||
private:
|
||||
inline CChunk *currentChunk() { return &m_Chunks[m_Chunks.size() - 1]; }
|
||||
|
||||
private:
|
||||
GsfInput *m_Input;
|
||||
void *m_Output; // todo
|
||||
std::vector<CChunk> m_Chunks;
|
||||
bool m_Is64Bit;
|
||||
|
||||
/* there exist compressed max files, so maybe we will need this at some point
|
||||
GsfInput * gsf_input_uncompress (GsfInput *src);
|
||||
*/
|
||||
|
||||
}; /* class CStorageStream */
|
||||
|
||||
} /* namespace MAX */
|
||||
} /* namespace PIPELINE */
|
||||
|
||||
#endif /* #ifndef PIPELINE_STORAGE_STREAM_H */
|
||||
|
||||
/* end of file */
|
Loading…
Reference in New Issue