diff --git a/include/data/buffered_placeholder_writer.hpp b/include/data/buffered_placeholder_writer.hpp new file mode 100644 index 0000000..ee4a8af --- /dev/null +++ b/include/data/buffered_placeholder_writer.hpp @@ -0,0 +1,89 @@ +/* +Copyright (c) 2017-2018 Adubbz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#include +#include +#include + +#include "nx/ncm.hpp" +#include "nx/nca_writer.h" + +namespace tin::data +{ + static const size_t BUFFER_SEGMENT_DATA_SIZE = 0x800000; // Approximately 8MB + extern int NUM_BUFFER_SEGMENTS; + + struct BufferSegment + { + std::atomic_bool isFinalized = false; + u64 writeOffset = 0; + u8 data[BUFFER_SEGMENT_DATA_SIZE] = {0}; + }; + + // Receives data in a circular buffer split into 8MB segments + class BufferedPlaceholderWriter + { + private: + size_t m_totalDataSize = 0; + size_t m_sizeBuffered = 0; + size_t m_sizeWrittenToPlaceholder = 0; + + // The current segment to which further data will be appended + u64 m_currentFreeSegment = 0; + BufferSegment* m_currentFreeSegmentPtr = NULL; + // The current segment that will be written to the placeholder + u64 m_currentSegmentToWrite = 0; + BufferSegment* m_currentSegmentToWritePtr = NULL; + + std::unique_ptr m_bufferSegments; + + std::shared_ptr m_contentStorage; + NcmContentId m_ncaId; + NcaWriter m_writer; + + public: + BufferedPlaceholderWriter(std::shared_ptr& contentStorage, NcmContentId ncaId, size_t totalDataSize); + + void AppendData(void* source, size_t length); + bool CanAppendData(size_t length); + + void WriteSegmentToPlaceholder(); + bool CanWriteSegmentToPlaceholder(); + + // Determine the number of segments required to fit data of this size + u32 CalcNumSegmentsRequired(size_t size); + + // Check if there are enough free segments to fit data of this size + bool IsSizeAvailable(size_t size); + + bool IsBufferDataComplete(); + bool IsPlaceholderComplete(); + + size_t GetTotalDataSize(); + size_t GetSizeBuffered(); + size_t GetSizeWrittenToPlaceholder(); + + void DebugPrintBuffers(); + }; +} \ No newline at end of file diff --git a/include/data/byte_buffer.hpp b/include/data/byte_buffer.hpp new file mode 100644 index 0000000..8c67676 --- /dev/null +++ b/include/data/byte_buffer.hpp @@ -0,0 +1,72 @@ +/* +Copyright (c) 2017-2018 Adubbz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#include +#include +#include + +namespace tin::data +{ + class ByteBuffer + { + private: + std::vector m_buffer; + + public: + ByteBuffer(size_t reserveSize=0); + + size_t GetSize(); + u8* GetData(); // TODO: Remove this, it shouldn't be needed + void Resize(size_t size); + + void DebugPrintContents(); + + template + T Read(u64 offset) + { + if (offset + sizeof(T) <= m_buffer.size()) + return *((T*)&m_buffer.data()[offset]); + + T def; + memset(&def, 0, sizeof(T)); + return def; + } + + template + void Write(T data, u64 offset) + { + size_t requiredSize = offset + sizeof(T); + + if (requiredSize > m_buffer.size()) + m_buffer.resize(requiredSize, 0); + + memcpy(m_buffer.data() + offset, &data, sizeof(T)); + } + template + void Append(T data) + { + this->Write(data, this->GetSize()); + } + }; +} \ No newline at end of file diff --git a/include/data/byte_stream.hpp b/include/data/byte_stream.hpp new file mode 100644 index 0000000..40861c7 --- /dev/null +++ b/include/data/byte_stream.hpp @@ -0,0 +1,51 @@ +/* +Copyright (c) 2017-2018 Adubbz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#include +#include "data/byte_buffer.hpp" + +namespace tin::data +{ + class ByteStream + { + protected: + u64 m_offset = 0; + + public: + virtual void ReadBytes(void* dest, size_t length) = 0; + }; + + // NOTE: This isn't generally useful, it's mainly for things like libpng + // which rely on streams + class BufferedByteStream : public ByteStream + { + private: + ByteBuffer m_byteBuffer; + + public: + BufferedByteStream(ByteBuffer buffer); + + void ReadBytes(void* dest, size_t length) override; + }; +} \ No newline at end of file