21 #ifndef XAPIAN_INCLUDED_PACK_H 22 #define XAPIAN_INCLUDED_PACK_H 25 # error config.h must be included first in each C++ source file 30 #include <type_traits> 59 s += char(
'0' | static_cast<char>(value));
72 const char*& ptr = *p;
75 if (
rare(ptr == end || ((ch = *ptr++ -
'0') &~ 1))) {
79 *result =
static_cast<bool>(ch);
95 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
98 s += char(value & 0xff);
113 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
116 const char* ptr = *p;
121 if (
rare(end - ptr >
int(
sizeof(U)))) {
127 *result = (*result << 8) | U(static_cast<unsigned char>(*--end));
151 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
155 "Template type U too wide for database format");
158 char tmp[
sizeof(U) + 1];
159 char * p = tmp +
sizeof(tmp);
162 *--p = char(value & 0xff);
166 unsigned char len =
static_cast<unsigned char>(tmp +
sizeof(tmp) - p);
168 s.append(p, len + 1);
187 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
188 static_assert(
sizeof(U) < 256,
189 "Template type U too wide for database format");
192 const char * ptr = *p;
195 if (
rare(ptr == end)) {
199 unsigned char len_byte =
static_cast<unsigned char>(*ptr++);
203 if (
rare(
size_t(end - ptr) < len)) {
211 if (
rare(len >
int(
sizeof(U)))) {
216 *result = (*result << 8) | U(static_cast<unsigned char>(*ptr++));
222 #if HAVE_DECL___BUILTIN_CLZ && \ 223 HAVE_DECL___BUILTIN_CLZL && \ 224 HAVE_DECL___BUILTIN_CLZLL 228 extern int no_clz_builtin_for_this_type(T);
229 return no_clz_builtin_for_this_type(value);
234 do_clz(
unsigned value) {
235 return __builtin_clz(value);
240 do_clz(
unsigned long value) {
241 return __builtin_clzl(value);
246 do_clz(
unsigned long long value) {
247 return __builtin_clzll(value);
271 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
272 static_assert(
sizeof(U) <= 8,
273 "Template type U too wide for database format");
276 if (value < 0x8000) {
277 s.resize(s.size() + 2);
278 s[s.size() - 2] =
static_cast<unsigned char>(value >> 8);
279 Assert(s[s.size() - 2] !=
'\xff');
280 s[s.size() - 1] =
static_cast<unsigned char>(value);
285 size_t len = ((
sizeof(U) * 8 + 5) - do_clz(value)) / 7;
288 for (
auto x = value >> 22; x; x >>= 7) ++len;
290 unsigned mask = 0xff << (10 - len);
292 s.resize(s.size() + len);
293 for (
size_t i = 1; i != len; ++i) {
294 s[s.size() - i] =
static_cast<unsigned char>(value);
298 s[s.size() - len] =
static_cast<unsigned char>(value | mask);
299 Assert(s[s.size() - len] !=
'\xff');
320 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
321 static_assert(
sizeof(U) <= 8,
322 "Template type U too wide for database format");
325 const char* ptr = *p;
328 if (
rare(ptr == end)) {
332 unsigned char len_byte =
static_cast<unsigned char>(*ptr++);
333 if (len_byte < 0x80) {
334 *result = (U(len_byte) << 8) | static_cast<unsigned char>(*ptr++);
339 if (len_byte == 0xff) {
345 size_t len = do_clz(len_byte ^ 0xffu) + 9 -
sizeof(unsigned) * 8;
348 for (
unsigned char m = 0x40; len_byte & m; m >>= 1) ++len;
350 if (
rare(
size_t(end - ptr) < len)) {
353 unsigned mask = 0xff << (9 - len);
357 if (
rare(len >
int(
sizeof(U))))
return false;
358 if (
sizeof(U) != 8) {
360 if (
rare(len ==
int(
sizeof(U)) && len_byte != 0))
return false;
368 r = (r << 8) | U(static_cast<unsigned char>(*ptr++));
384 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
386 while (value >= 128) {
387 s +=
static_cast<char>(
static_cast<unsigned char>(value) | 0x80);
390 s +=
static_cast<char>(value);
402 s +=
static_cast<char>(value);
415 static_assert(std::is_unsigned<U>::value,
"Unsigned type required");
417 const char* ptr = *p;
419 const char* start = ptr;
423 if (
rare(ptr == end)) {
428 }
while (static_cast<unsigned char>(*ptr++) >= 128);
432 if (!result)
return true;
440 size_t maxbits = size_t(ptr - start) * 7;
441 if (maxbits <=
sizeof(U) * 8) {
444 unsigned char chunk =
static_cast<unsigned char>(*--ptr) & 0x7f;
445 *result = (*result << 7) | U(chunk);
446 }
while (ptr != start);
450 size_t minbits = maxbits - 6;
451 if (
rare(minbits >
sizeof(U) * 8)) {
456 while (--ptr != start) {
457 unsigned char chunk =
static_cast<unsigned char>(*--ptr) & 0x7f;
458 *result = (*result << 7) | U(chunk);
463 if (
rare(*result < tmp)) {
467 *result |= U(static_cast<unsigned char>(*ptr) & 0x7f);
492 size_t len = std::strlen(ptr);
511 const char*& ptr = *p;
512 if (
rare(len >
size_t(end - ptr))) {
517 result.assign(ptr, len);
542 std::string::size_type b = 0, e;
543 while ((e = value.find(
'\0', b)) != std::string::npos) {
545 s.append(value, b, e - b);
549 s.append(value, b, std::string::npos);
550 if (!last) s +=
'\0';
567 const char* ptr = *p;
572 if (
rare(ch ==
'\0')) {
573 if (
usual(ptr == end || *ptr !=
'\xff')) {
589 return std::string(
"\x00\xe0", 2);
601 std::string key(
"\x00\xe0", 2);
617 return std::string(
"\x00\xe0", 2);
629 std::string key(
"\x00\xe0", 2);
640 #endif // XAPIAN_INCLUDED_PACK_H void pack_bool(std::string &s, bool value)
Append an encoded bool to a string.
const unsigned int SORTABLE_UINT_1ST_BYTE_MASK
Calculated value used below.
const unsigned int SORTABLE_UINT_LOG2_MAX_BYTES
How many bits to store the length of a sortable uint in.
#define AssertRel(A, REL, B)
const unsigned int SORTABLE_UINT_MAX_BYTES
Calculated value used below.
void pack_uint_last(std::string &s, U value)
Append an encoded unsigned integer to a string as the last item.
void C_pack_uint_preserving_sort(std::string &s, U value)
Append an encoded unsigned integer to a string, preserving the sort order.
bool C_unpack_uint_preserving_sort(const char **p, const char *end, U *result)
Decode an "sort preserved" unsigned integer from a string.
bool unpack_string_preserving_sort(const char **p, const char *end, std::string &result)
Decode a "sort preserved" std::string from a string.
bool unpack_uint_preserving_sort(const char **p, const char *end, U *result)
Decode a "sort preserved" unsigned integer from a string.
std::string pack_chert_postlist_key(const std::string &term)
void pack_uint(std::string &s, U value)
Append an encoded unsigned integer to a string.
bool unpack_bool(const char **p, const char *end, bool *result)
Decode a bool from a string.
void pack_string(std::string &s, const std::string &value)
Append an encoded std::string to a string.
std::string pack_glass_postlist_key(const std::string &term)
bool unpack_uint_last(const char **p, const char *end, U *result)
Decode an unsigned integer as the last item in a string.
bool unpack_uint(const char **p, const char *end, U *result)
Decode an unsigned integer from a string.
Various assertion macros.
bool unpack_string(const char **p, const char *end, std::string &result)
Decode a std::string from a string.
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
void pack_string_preserving_sort(std::string &s, const std::string &value, bool last=false)
Append an encoded std::string to a string, preserving the sort order.
void pack_uint_preserving_sort(std::string &s, U value)
Append an encoded unsigned integer to a string, preserving the sort order.