20#ifndef PLYWOOT_BINARY_PARSER_POLICY_HPP
21#define PLYWOOT_BINARY_PARSER_POLICY_HPP
32namespace plywoot::detail {
37template<
typename Endianness>
38class BinaryParserPolicy
44 BinaryParserPolicy(std::istream &is) : is_{is} {}
50 void skipElement(
const PlyElement &e)
const
54 const std::vector<PlyProperty> &properties = e.properties();
55 if (std::all_of(properties.begin(), properties.end(), [](
const PlyProperty &p) { return !p.isList(); }))
58 e.size() * std::accumulate(
59 properties.begin(), properties.end(),
static_cast<std::size_t
>(0),
60 [](std::size_t acc,
const PlyProperty &p) { return acc + sizeOf(p.type()); }));
64 for (std::size_t i = 0; i < e.size(); ++i)
66 for (
const PlyProperty &p : e.properties()) { skipProperty(p); }
75 void skipProperty(
const PlyProperty &p)
const
77 if (!p.isList()) { is_.skip(
sizeOf(p.type())); }
83 case PlyDataType::Char:
84 size = readNumber<char>();
86 case PlyDataType::UChar:
87 size = readNumber<unsigned char>();
89 case PlyDataType::Short:
90 size = readNumber<short>();
92 case PlyDataType::UShort:
93 size = readNumber<unsigned short>();
95 case PlyDataType::Int:
96 size = readNumber<int>();
98 case PlyDataType::UInt:
99 size = readNumber<unsigned int>();
101 case PlyDataType::Float:
102 size = readNumber<float>();
104 case PlyDataType::Double:
105 size = readNumber<double>();
109 is_.skip(size *
sizeOf(p.type()));
117 template<
typename T,
typename EndiannessDependent = Endianness>
120 if constexpr (std::is_same_v<EndiannessDependent, HostEndian>) {
return is_.read<T>(); }
121 else {
return byte_swap(is_.read<T>()); }
132 template<
typename PlyT,
typename DestT, std::
size_t N,
typename EndiannessDependent = Endianness>
133 std::uint8_t *readNumbers(std::uint8_t *dest)
const
135 if constexpr (std::is_same_v<EndiannessDependent, HostEndian>) {
return is_.read<PlyT, DestT, N>(dest); }
138 std::uint8_t *result = is_.read<PlyT, DestT, N>(dest);
141 DestT *to =
reinterpret_cast<DestT *
>(dest);
142 for (std::size_t i = 0; i < N; ++i, ++to) { *to =
byte_swap(
static_cast<PlyT
>(*to)); }
150 void skipNumber()
const
158 void skipProperties(std::size_t n)
const { is_.skip(n); }
167 template<
typename... Ts,
typename EndiannessDependent = Endianness>
168 void memcpy(std::uint8_t *dest,
const PlyElement &element)
const
170 is_.memcpy(dest, element.size() * detail::sizeOf<Ts...>());
172 if constexpr (!std::is_same_v<EndiannessDependent, HostEndian>)
174 for (std::size_t i = 0; i < element.size(); ++i) { dest = byteSwap<Ts...>(dest); }
180 std::uint8_t *byteSwap(std::uint8_t *dest)
const
182 if constexpr (!detail::IsPack<T>::value)
184 auto ptr =
reinterpret_cast<T *
>(dest);
187 return dest +
sizeof(T);
191 auto ptr =
reinterpret_cast<typename T::DestT *
>(dest);
192 for (std::size_t i = 0; i < T::size; ++i, ++ptr) { *ptr =
byte_swap(*ptr); }
194 return dest + detail::sizeOf<T>();
198 template<
typename T,
typename U,
typename... Ts>
199 std::uint8_t *byteSwap(std::uint8_t *dest)
const
202 detail::isPacked<T, U, Ts...>(),
203 "converting endianness of possibly padded range of objects not implemented yet");
205 return byteSwap<U, Ts...>(byteSwap<T>(dest));
209 mutable detail::BufferedIStream is_;
BinaryParserPolicy< LittleEndian > BinaryLittleEndianParserPolicy
Convenience type alias for the binary little endian parser policy.
BinaryParserPolicy< BigEndian > BinaryBigEndianParserPolicy
Convenience type alias for the binary big endian parser policy.
constexpr std::size_t sizeOf()