1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* |
3 | Copyright(C) 2011-2016 Brazil |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License version 2.1 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this library; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #pragma once |
20 | |
21 | #include "string.hpp" |
22 | |
23 | namespace grn { |
24 | namespace dat { |
25 | |
26 | class GRN_DAT_API Key { |
27 | public: |
28 | const UInt8 &operator[](UInt32 i) const { |
29 | GRN_DAT_DEBUG_THROW_IF(i >= length()); |
30 | return buf_[i]; |
31 | } |
32 | |
33 | bool is_valid() const { |
34 | return id() != INVALID_KEY_ID; |
35 | } |
36 | |
37 | String str() const { |
38 | return String(ptr(), length()); |
39 | } |
40 | |
41 | const void *ptr() const { |
42 | return buf_; |
43 | } |
44 | UInt32 length() const { |
45 | return (length_high_ << 4) | (id_and_length_low_ & 0x0F); |
46 | } |
47 | UInt32 id() const { |
48 | return id_and_length_low_ >> 4; |
49 | } |
50 | |
51 | bool equals_to(const void *ptr, UInt32 length, UInt32 offset = 0) const { |
52 | if (length != this->length()) { |
53 | return false; |
54 | } |
55 | for ( ; offset < length; ++offset) { |
56 | if ((*this)[offset] != static_cast<const UInt8 *>(ptr)[offset]) { |
57 | return false; |
58 | } |
59 | } |
60 | return true; |
61 | } |
62 | |
63 | // Creates an object of Key from given parameters. Then, the created object |
64 | // is embedded into a specified buffer. |
65 | static const Key &create(UInt32 *buf, UInt32 key_id, |
66 | const void *key_ptr, UInt32 key_length) { |
67 | GRN_DAT_DEBUG_THROW_IF(buf == NULL); |
68 | GRN_DAT_DEBUG_THROW_IF(key_id > MAX_KEY_ID); |
69 | GRN_DAT_DEBUG_THROW_IF((key_ptr == NULL) && (key_length != 0)); |
70 | GRN_DAT_DEBUG_THROW_IF(key_length > MAX_KEY_LENGTH); |
71 | |
72 | *buf = (key_id << 4) | (key_length & 0x0F); |
73 | UInt8 *ptr = reinterpret_cast<UInt8 *>(buf + 1); |
74 | *ptr++ = key_length >> 4; |
75 | for (UInt32 i = 0; i < key_length; ++i) { |
76 | ptr[i] = static_cast<const UInt8 *>(key_ptr)[i]; |
77 | } |
78 | return *reinterpret_cast<const Key *>(buf); |
79 | } |
80 | |
81 | // Calculates how many UInt32s are required for a string. It is guaranteed |
82 | // that the estimated size is not less than the actual size. |
83 | static UInt32 estimate_size(UInt32 length) { |
84 | return 2 + (length / sizeof(UInt32)); |
85 | } |
86 | |
87 | // Returns a reference to an invalid key. |
88 | static const Key &invalid_key() { |
89 | static const Key invalid_key; |
90 | return invalid_key; |
91 | // static const UInt32 invalid_key_buf[2] = { INVALID_KEY_ID << 4, 0 }; |
92 | // return *reinterpret_cast<const Key *>(invalid_key_buf); |
93 | } |
94 | |
95 | private: |
96 | UInt32 id_and_length_low_; |
97 | UInt8 length_high_; |
98 | UInt8 buf_[3]; |
99 | |
100 | // Disallows instantiation. |
101 | Key() : id_and_length_low_(INVALID_KEY_ID << 4), length_high_(0) {} |
102 | ~Key() {} |
103 | |
104 | // Disallows copy and assignment. |
105 | Key(const Key &); |
106 | Key &operator=(const Key &); |
107 | }; |
108 | |
109 | } // namespace dat |
110 | } // namespace grn |
111 | |