diff --git a/include/cpp3ds/System/FileInputStream.hpp b/include/cpp3ds/System/FileInputStream.hpp new file mode 100644 index 0000000..987f96b --- /dev/null +++ b/include/cpp3ds/System/FileInputStream.hpp @@ -0,0 +1,154 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef CPP3DS_FILEINPUTSTREAM_HPP +#define CPP3DS_FILEINPUTSTREAM_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include + + +namespace cpp3ds +{ +//////////////////////////////////////////////////////////// +/// \brief Implementation of input stream based on a file +/// +//////////////////////////////////////////////////////////// +class FileInputStream : public InputStream, NonCopyable +{ +public: + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + FileInputStream(); + + //////////////////////////////////////////////////////////// + /// \brief Default destructor + /// + //////////////////////////////////////////////////////////// + virtual ~FileInputStream(); + + //////////////////////////////////////////////////////////// + /// \brief Open the stream from a file path + /// + /// \param filename Name of the file to open + /// + /// \return True on success, false on error + /// + //////////////////////////////////////////////////////////// + bool open(const std::string& filename); + + //////////////////////////////////////////////////////////// + /// \brief Read data from the stream + /// + /// After reading, the stream's reading position must be + /// advanced by the amount of bytes read. + /// + /// \param data Buffer where to copy the read data + /// \param size Desired number of bytes to read + /// + /// \return The number of bytes actually read, or -1 on error + /// + //////////////////////////////////////////////////////////// + virtual Int64 read(void* data, Int64 size); + + //////////////////////////////////////////////////////////// + /// \brief Change the current reading position + /// + /// \param position The position to seek to, from the beginning + /// + /// \return The position actually sought to, or -1 on error + /// + //////////////////////////////////////////////////////////// + virtual Int64 seek(Int64 position); + + //////////////////////////////////////////////////////////// + /// \brief Get the current reading position in the stream + /// + /// \return The current position, or -1 on error. + /// + //////////////////////////////////////////////////////////// + virtual Int64 tell(); + + //////////////////////////////////////////////////////////// + /// \brief Return the size of the stream + /// + /// \return The total number of bytes available in the stream, or -1 on error + /// + //////////////////////////////////////////////////////////// + virtual Int64 getSize(); + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + std::FILE* m_file; ///< stdio file stream +}; + +} // namespace cpp3ds + + +#endif // CPP3DS_FILEINPUTSTREAM_HPP + + +//////////////////////////////////////////////////////////// +/// \class FileInputStream +/// \ingroup system +/// +/// This class is a specialization of InputStream that +/// reads from a file on disk. +/// +/// It wraps a file in the common InputStream interface +/// and therefore allows to use generic classes or functions +/// that accept such a stream, with a file on disk as the data +/// source. +/// +/// In addition to the virtual functions inherited from +/// InputStream, FileInputStream adds a function to +/// specify the file to open. +/// +/// cpp3ds resource classes can usually be loaded directly from +/// a filename, so this class shouldn't be useful to you unless +/// you create your own algorithms that operate on a InputStream. +/// +/// Usage example: +/// \code +/// void process(InputStream& stream); +/// +/// FileStream stream; +/// if (stream.open("some_file.dat")) +/// process(stream); +/// \endcode +/// +/// InputStream, MemoryStream +/// +//////////////////////////////////////////////////////////// diff --git a/include/cpp3ds/System/MemoryInputStream.hpp b/include/cpp3ds/System/MemoryInputStream.hpp new file mode 100644 index 0000000..3460622 --- /dev/null +++ b/include/cpp3ds/System/MemoryInputStream.hpp @@ -0,0 +1,147 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef CPP3DS_MEMORYINPUTSTREAM_HPP +#define CPP3DS_MEMORYINPUTSTREAM_HPP + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include +#include + + +namespace cpp3ds +{ +//////////////////////////////////////////////////////////// +/// \brief Implementation of input stream based on a memory chunk +/// +//////////////////////////////////////////////////////////// +class MemoryInputStream : public InputStream +{ +public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + //////////////////////////////////////////////////////////// + MemoryInputStream(); + + //////////////////////////////////////////////////////////// + /// \brief Open the stream from its data + /// + /// \param data Pointer to the data in memory + /// \param sizeInBytes Size of the data, in bytes + /// + //////////////////////////////////////////////////////////// + void open(const void* data, std::size_t sizeInBytes); + + //////////////////////////////////////////////////////////// + /// \brief Read data from the stream + /// + /// After reading, the stream's reading position must be + /// advanced by the amount of bytes read. + /// + /// \param data Buffer where to copy the read data + /// \param size Desired number of bytes to read + /// + /// \return The number of bytes actually read, or -1 on error + /// + //////////////////////////////////////////////////////////// + virtual Int64 read(void* data, Int64 size); + + //////////////////////////////////////////////////////////// + /// \brief Change the current reading position + /// + /// \param position The position to seek to, from the beginning + /// + /// \return The position actually sought to, or -1 on error + /// + //////////////////////////////////////////////////////////// + virtual Int64 seek(Int64 position); + + //////////////////////////////////////////////////////////// + /// \brief Get the current reading position in the stream + /// + /// \return The current position, or -1 on error. + /// + //////////////////////////////////////////////////////////// + virtual Int64 tell(); + + //////////////////////////////////////////////////////////// + /// \brief Return the size of the stream + /// + /// \return The total number of bytes available in the stream, or -1 on error + /// + //////////////////////////////////////////////////////////// + virtual Int64 getSize(); + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + const char* m_data; ///< Pointer to the data in memory + Int64 m_size; ///< Total size of the data + Int64 m_offset; ///< Current reading position +}; + +} // namespace cpp3ds + + +#endif // CPP3DS_MEMORYINPUTSTREAM_HPP + + +//////////////////////////////////////////////////////////// +/// \class MemoryeInputStream +/// \ingroup system +/// +/// This class is a specialization of InputStream that +/// reads from data in memory. +/// +/// It wraps a memory chunk in the common InputStream interface +/// and therefore allows to use generic classes or functions +/// that accept such a stream, with content already loaded in memory. +/// +/// In addition to the virtual functions inherited from +/// InputStream, MemoryInputStream adds a function to +/// specify the pointer and size of the data in memory. +/// +/// cpp3ds resource classes can usually be loaded directly from +/// memory, so this class shouldn't be useful to you unless +/// you create your own algorithms that operate on a InputStream. +/// +/// Usage example: +/// \code +/// void process(InputStream& stream); +/// +/// MemoryStream stream; +/// stream.open(thePtr, theSize); +/// process(stream); +/// \endcode +/// +/// InputStream, FileStream +/// +//////////////////////////////////////////////////////////// diff --git a/src/cpp3ds/Graphics/ImageLoader.cpp b/src/cpp3ds/Graphics/ImageLoader.cpp index 5eb0db5..8ecf9c7 100644 --- a/src/cpp3ds/Graphics/ImageLoader.cpp +++ b/src/cpp3ds/Graphics/ImageLoader.cpp @@ -104,9 +104,14 @@ bool ImageLoader::loadImageFromFile(const std::string& filename, std::vector + + +namespace cpp3ds +{ +//////////////////////////////////////////////////////////// +FileInputStream::FileInputStream() +: m_file(NULL) +{ + +} + + +//////////////////////////////////////////////////////////// +FileInputStream::~FileInputStream() +{ + if (m_file) + std::fclose(m_file); +} + + +//////////////////////////////////////////////////////////// +bool FileInputStream::open(const std::string& filename) +{ + if (m_file) + std::fclose(m_file); + + #ifdef EMULATION + std::string rel_filename = "res/sdmc/" + filename; + m_file = std::fopen(rel_filename.c_str(), "rb"); + #else + m_file = std::fopen(filename.c_str(), "rb"); + #endif + + return m_file != NULL; +} + + +//////////////////////////////////////////////////////////// +Int64 FileInputStream::read(void* data, Int64 size) +{ + if (m_file) + return std::fread(data, 1, static_cast(size), m_file); + else + return -1; +} + + +//////////////////////////////////////////////////////////// +Int64 FileInputStream::seek(Int64 position) +{ + if (m_file) + { + std::fseek(m_file, static_cast(position), SEEK_SET); + return tell(); + } + else + { + return -1; + } +} + + +//////////////////////////////////////////////////////////// +Int64 FileInputStream::tell() +{ + if (m_file) + return std::ftell(m_file); + else + return -1; +} + + +//////////////////////////////////////////////////////////// +Int64 FileInputStream::getSize() +{ + if (m_file) + { + cpp3ds::Int64 position = tell(); + std::fseek(m_file, 0, SEEK_END); + cpp3ds::Int64 size = tell(); + seek(position); + return size; + } + else + { + return -1; + } +} + +} // namespace cpp3ds diff --git a/src/cpp3ds/System/MemoryInputStream.cpp b/src/cpp3ds/System/MemoryInputStream.cpp new file mode 100644 index 0000000..12a4f17 --- /dev/null +++ b/src/cpp3ds/System/MemoryInputStream.cpp @@ -0,0 +1,101 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace cpp3ds +{ +//////////////////////////////////////////////////////////// +MemoryInputStream::MemoryInputStream() : +m_data (NULL), +m_size (0), +m_offset(0) +{ +} + + +//////////////////////////////////////////////////////////// +void MemoryInputStream::open(const void* data, std::size_t sizeInBytes) +{ + m_data = static_cast(data); + m_size = sizeInBytes; + m_offset = 0; +} + + +//////////////////////////////////////////////////////////// +Int64 MemoryInputStream::read(void* data, Int64 size) +{ + if (!m_data) + return -1; + + Int64 endPosition = m_offset + size; + Int64 count = endPosition <= m_size ? size : m_size - m_offset; + + if (count > 0) + { + std::memcpy(data, m_data + m_offset, static_cast(count)); + m_offset += count; + } + + return count; +} + + +//////////////////////////////////////////////////////////// +Int64 MemoryInputStream::seek(Int64 position) +{ + if (!m_data) + return -1; + + m_offset = position < m_size ? position : m_size; + return m_offset; +} + + +//////////////////////////////////////////////////////////// +Int64 MemoryInputStream::tell() +{ + if (!m_data) + return -1; + + return m_offset; +} + + +//////////////////////////////////////////////////////////// +Int64 MemoryInputStream::getSize() +{ + if (!m_data) + return -1; + + return m_size; +} + +} // namespace cpp3ds