MemoryStreamImpl.cpp trio/streams/MemoryStreamImpl.h pma/PolyAllocator.h cassert cstdint cstring trio::anonymous_namespace{MemoryStreamImpl.cpp}::MemoryReader trio::anonymous_namespace{MemoryStreamImpl.cpp}::MemoryWriter trio trio::anonymous_namespace{MemoryStreamImpl.cpp} //CopyrightEpicGames,Inc.AllRightsReserved. #include"trio/streams/MemoryStreamImpl.h" #include<pma/PolyAllocator.h> #ifdef_MSC_VER #pragmawarning(push) #pragmawarning(disable:43654987) #endif #include<cassert> #include<cstdint> #include<cstring> #ifdef_MSC_VER #pragmawarning(pop) #endif namespacetrio{ namespace{ classMemoryReader:publicReadable{ public: explicitMemoryReader(constchar*source_):source{source_}{ } std::size_tread(char*destination,std::size_tsize)override{ std::memcpy(destination,source,size); source+=size; returnsize; } std::size_tread(Writable*destination,std::size_tsize)override{ destination->write(source,size); source+=size; returnsize; } private: constchar*source; }; classMemoryWriter:publicWritable{ public: explicitMemoryWriter(char*destination_):destination{destination_}{ } std::size_twrite(constchar*source,std::size_tsize)override{ std::memcpy(destination,source,size); destination+=size; returnsize; } std::size_twrite(Readable*source,std::size_tsize)override{ source->read(destination,size); destination+=size; returnsize; } private: char*destination; }; }//namespace MemoryStream::~MemoryStream()=default; MemoryStream*MemoryStream::create(MemoryResource*memRes){ returncreate(0ul,memRes); } MemoryStream*MemoryStream::create(std::size_tinitialSize,MemoryResource*memRes){ pma::PolyAllocator<MemoryStreamImpl>alloc{memRes}; returnalloc.newObject(initialSize,memRes); } voidMemoryStream::destroy(MemoryStream*instance){ //NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast) autostream=static_cast<MemoryStreamImpl*>(instance); pma::PolyAllocator<MemoryStreamImpl>alloc{stream->getMemoryResource()}; alloc.deleteObject(stream); } MemoryStreamImpl::MemoryStreamImpl(std::size_tinitialSize,MemoryResource*memRes_): data{initialSize,static_cast<char>(0),memRes_}, position{}, memRes{memRes_}{ } voidMemoryStreamImpl::open(){ position=0ul; } voidMemoryStreamImpl::close(){ position=0ul; } std::uint64_tMemoryStreamImpl::tell(){ returnposition; } voidMemoryStreamImpl::seek(std::uint64_tposition_){ if((position_==0ul)||(position_<=size())){ #if!defined(__clang__)&&defined(__GNUC__) #pragmaGCCdiagnosticpush #pragmaGCCdiagnosticignored"-Wuseless-cast" #endif position=static_cast<std::size_t>(position_); #if!defined(__clang__)&&defined(__GNUC__) #pragmaGCCdiagnosticpop #endif }else{ status->set(SeekError); } } std::size_tMemoryStreamImpl::read(char*destination,std::size_tsize){ if(destination==nullptr){ status->set(ReadError); return0ul; } MemoryWriterwriter{destination}; returnread(&writer,size); } std::size_tMemoryStreamImpl::read(Writable*destination,std::size_tsize){ if(destination==nullptr){ status->set(ReadError); return0ul; } conststd::size_tavailable=data.size()-position; conststd::size_tbytesToRead=std::min(size,available); conststd::size_tbytesCopied=(bytesToRead>0ul?destination->write(&data[position],bytesToRead):0ul); position+=bytesCopied; returnbytesCopied; } std::size_tMemoryStreamImpl::write(constchar*source,std::size_tsize){ if(source==nullptr){ status->set(WriteError); return0ul; } MemoryReaderreader{source}; returnwrite(&reader,size); } std::size_tMemoryStreamImpl::write(Readable*source,std::size_tsize){ if(source==nullptr){ status->set(WriteError); return0ul; } conststd::size_tavailable=data.size()-position; if(available<size){ conststd::size_tnewSize=data.size()+(size-available); //Checkforoverflow/wrap-around if(newSize<data.size()){ status->set(WriteError); return0ul; } data.resize(newSize); } conststd::size_tbytesCopied=source->read(&data[position],size); position+=bytesCopied; returnbytesCopied; } std::uint64_tMemoryStreamImpl::size(){ returndata.size(); } MemoryResource*MemoryStreamImpl::getMemoryResource(){ returnmemRes; } }//namespacetrio