<tt.rantala@gmail.com>
namespace rantala {
template <typename CharT>
inline CharT
get_char(unsigned char* ptr, size_t depth);
template <>
inline unsigned char
get_char<unsigned char>(unsigned char* ptr, size_t depth)
{
assert(ptr);
return ptr[depth];
}
template <>
inline uint16_t
get_char<uint16_t>(unsigned char* ptr, size_t depth)
{
assert(ptr);
uint16_t ch = ptr[depth];
if (ch) ch = (ch << 8) | ptr[depth+1];
return ch;
}
template <>
inline uint32_t
get_char<uint32_t>(unsigned char* ptr, size_t depth)
{
assert(ptr);
uint32_t c = 0;
ptr += depth;
if (*ptr == 0) return c;
c = (uint32_t(*ptr++) << 24);
if (*ptr == 0) return c;
c |= (uint32_t(*ptr++) << 16);
if (*ptr == 0) return c;
c |= (uint32_t(*ptr++) << 8 );
return c | *ptr;
}
template <>
inline uint64_t
get_char<uint64_t>(unsigned char* ptr, size_t depth)
{
uint64_t c = 0;
if (ptr[depth] == 0) return c;
c = (uint64_t(ptr[depth]) << 56); ++ptr;
if (ptr[depth] == 0) return c;
c |= (uint64_t(ptr[depth]) << 48); ++ptr;
if (ptr[depth] == 0) return c;
c |= (uint64_t(ptr[depth]) << 40); ++ptr;
if (ptr[depth] == 0) return c;
c |= (uint64_t(ptr[depth]) << 32); ++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 24); ++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 16); ++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 8); ++ptr;
c |= ptr[depth];
return c;
}
template <typename CharT, int depth>
static inline CharT
get_char(unsigned char* ptr)
{
if (sizeof(CharT) == 1) {
return ptr[depth];
}
else if (sizeof(CharT) == 2) {
if (ptr[depth] == 0) return 0;
else return (ptr[depth] << 8) | ptr[depth+1];
}
else if (sizeof(CharT) == 4) {
CharT c = 0;
if (ptr[depth] == 0) return c;
c = (ptr[depth] << 24);
++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 16);
++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 8);
++ptr;
c |= ptr[depth];
return c;
}
else if (sizeof(CharT) == 8) {
CharT c = 0;
if (ptr[depth] == 0) return c;
c = (uint64_t(ptr[depth]) << 56); ++ptr;
if (ptr[depth] == 0) return c;
c |= (uint64_t(ptr[depth]) << 48); ++ptr;
if (ptr[depth] == 0) return c;
c |= (uint64_t(ptr[depth]) << 40); ++ptr;
if (ptr[depth] == 0) return c;
c |= (uint64_t(ptr[depth]) << 32); ++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 24); ++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 16); ++ptr;
if (ptr[depth] == 0) return c;
c |= (ptr[depth] << 8); ++ptr;
c |= ptr[depth];
return c;
}
else {
assert(0);
}
}
template <typename CharT>
inline bool is_end(CharT c);
template <> inline bool is_end(unsigned char c)
{
return c==0;
}
template <> inline bool is_end(uint16_t c)
{
return (c&0xFF)==0;
}
template <> inline bool is_end(uint32_t c)
{
return (c&0xFF)==0;
}
template <> inline bool is_end(uint64_t c)
{
return (c&0xFF)==0;
}
}