#pragma once #include "coding/varint.hpp" #include "base/buffer_vector.hpp" #include "std/string.hpp" #include "std/vector.hpp" #include "std/type_traits.hpp" namespace rw { template void Write(TSink & sink, uint32_t i) { WriteVarUint(sink, i); } template void Read(TSource & src, uint32_t & i) { i = ReadVarUint(src); } template void Write(TSink & sink, string const & s) { uint32_t const count = static_cast(s.size()); WriteVarUint(sink, count); if (!s.empty()) sink.Write(&s[0], count); } template void Read(TSource & src, string & s) { uint32_t const count = ReadVarUint(src); s.resize(count); if (count > 0) src.Read(&s[0], count); } namespace impl { template void WriteCont(TSink & sink, TCont const & v) { uint32_t const count = static_cast(v.size()); WriteVarUint(sink, count); for (uint32_t i = 0; i < count; ++i) Write(sink, v[i]); } template void ReadCont(TSource & src, TCont & v) { uint32_t const count = ReadVarUint(src); v.resize(count); for (size_t i = 0; i < count; ++i) Read(src, v[i]); } } template void Write(TSink & sink, vector const & v) { impl::WriteCont(sink, v); } template void Read(TSource & src, vector & v) { impl::ReadCont(src, v); } template void Write(TSink & sink, buffer_vector const & v) { impl::WriteCont(sink, v); } template void Read(TSource & src, buffer_vector & v) { impl::ReadCont(src, v); } template void ReadVectorOfPOD(TSource & src, TCont & v) { typedef typename TCont::value_type ValueT; /// This assert fails on std::pair and OsmID class. /// @todo Review this logic in future with new compiler abilities. /// https://trello.com/c/hzCc9bzN/1254-is-trivial-copy-read-write-utils-hpp //static_assert(is_trivially_copyable::value, ""); uint32_t const count = ReadVarUint(src); if (count > 0) { v.resize(count); src.Read(&v[0], count * sizeof(ValueT)); } } template void WriteVectorOfPOD(TSink & sink, TCont const & v) { typedef typename TCont::value_type ValueT; /// This assert fails on std::pair and OsmID class. /// @todo Review this logic in future with new compiler abilities. /// https://trello.com/c/hzCc9bzN/1254-is-trivial-copy-read-write-utils-hpp //static_assert(is_trivially_copyable::value, ""); uint32_t const count = static_cast(v.size()); WriteVarUint(sink, count); if (count > 0) sink.Write(&v[0], count * sizeof(ValueT)); } template void ReadAndWrite(ReaderT & reader, WriterT & writer, size_t bufferSize = 4*1024) { uint64_t size = reader.Size(); vector buffer(min(bufferSize, static_cast(size))); while (size > 0) { size_t const curr = min(bufferSize, static_cast(size)); reader.Read(&buffer[0], curr); writer.Write(&buffer[0], curr); size -= curr; } } }