1 /** @file length.h
2  * @brief length encoded as a string
3  */
4 /* Copyright (C) 2006,2007,2008,2009,2012,2015 Olly Betts
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20 
21 #ifndef XAPIAN_INCLUDED_LENGTH_H
22 #define XAPIAN_INCLUDED_LENGTH_H
23 
24 #include <string>
25 
26 /** Encode a length as a variable-length string.
27  *
28  *  The encoding specifies its own length.
29  *
30  *  @param len	The length to encode.
31  *
32  *  @return	The encoded length.
33  */
34 template<class T>
35 std::string
encode_length(T len)36 encode_length(T len)
37 {
38     std::string result;
39     if (len < 255) {
40 	result += static_cast<unsigned char>(len);
41     } else {
42 	result += '\xff';
43 	len -= 255;
44 	while (true) {
45 	    unsigned char b = static_cast<unsigned char>(len & 0x7f);
46 	    len >>= 7;
47 	    if (!len) {
48 		result += char(b | static_cast<unsigned char>(0x80));
49 		break;
50 	    }
51 	    result += b;
52 	}
53     }
54     return result;
55 }
56 
57 /** Decode a length encoded by encode_length.
58  *
59  *  @param p	Pointer to a pointer to the string, which will be advanced past
60  *		the encoded length.
61  *  @param end	Pointer to the end of the string.
62  *  @param[out] out	The decoded length.
63  */
64 void decode_length(const char ** p, const char *end, unsigned & out);
65 
66 void decode_length(const char ** p, const char *end, unsigned long & out);
67 
68 void decode_length(const char ** p, const char *end, unsigned long long & out);
69 
70 /** Decode a length encoded by encode_length.
71  *
72  *  Also checks the result against the amount of data remaining after the
73  *  length has been decoded.
74  *
75  *  @param p	Pointer to a pointer to the string, which will be advanced past
76  *		the encoded length.
77  *  @param end	Pointer to the end of the string.
78  *  @param[out] out	The decoded length.
79  */
80 void decode_length_and_check(const char ** p, const char *end, unsigned & out);
81 
82 void decode_length_and_check(const char ** p, const char *end,
83 			     unsigned long & out);
84 
85 void decode_length_and_check(const char ** p, const char *end,
86 			     unsigned long long & out);
87 
88 #endif // XAPIAN_INCLUDED_LENGTH_H
89