• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "icing/store/namespace-fingerprint-identifier.h"
16 
17 #include <cstdint>
18 #include <string>
19 #include <string_view>
20 
21 #include "icing/text_classifier/lib3/utils/base/statusor.h"
22 #include "icing/text_classifier/lib3/utils/hash/farmhash.h"
23 #include "icing/absl_ports/canonical_errors.h"
24 #include "icing/absl_ports/str_cat.h"
25 #include "icing/store/namespace-id.h"
26 #include "icing/util/encode-util.h"
27 
28 namespace icing {
29 namespace lib {
30 
31 /* static */ libtextclassifier3::StatusOr<NamespaceFingerprintIdentifier>
DecodeFromCString(std::string_view encoded_cstr)32 NamespaceFingerprintIdentifier::DecodeFromCString(
33     std::string_view encoded_cstr) {
34   if (encoded_cstr.size() < kMinEncodedLength) {
35     return absl_ports::InvalidArgumentError("Invalid length");
36   }
37 
38   NamespaceId namespace_id = encode_util::DecodeIntFromCString(
39       encoded_cstr.substr(0, kEncodedNamespaceIdLength));
40   uint64_t fingerprint = encode_util::DecodeIntFromCString(
41       encoded_cstr.substr(kEncodedNamespaceIdLength));
42   return NamespaceFingerprintIdentifier(namespace_id, fingerprint);
43 }
44 
NamespaceFingerprintIdentifier(NamespaceId namespace_id,std::string_view target_str)45 NamespaceFingerprintIdentifier::NamespaceFingerprintIdentifier(
46     NamespaceId namespace_id, std::string_view target_str)
47     : namespace_id_(namespace_id),
48       fingerprint_(tc3farmhash::Fingerprint64(target_str)) {}
49 
EncodeToCString() const50 std::string NamespaceFingerprintIdentifier::EncodeToCString() const {
51   // encoded_namespace_id_str should be 1 to 3 bytes based on the value of
52   // namespace_id.
53   std::string encoded_namespace_id_str =
54       encode_util::EncodeIntToCString(namespace_id_);
55   // Make encoded_namespace_id_str to fixed kEncodedNamespaceIdLength bytes.
56   while (encoded_namespace_id_str.size() < kEncodedNamespaceIdLength) {
57     // C string cannot contain 0 bytes, so we append it using 1, just like what
58     // we do in encode_util::EncodeIntToCString.
59     //
60     // The reason that this works is because DecodeIntToString decodes a byte
61     // value of 0x01 as 0x00. When EncodeIntToCString returns an encoded
62     // namespace id that is less than 3 bytes, it means that the id contains
63     // unencoded leading 0x00. So here we're explicitly encoding those bytes as
64     // 0x01.
65     encoded_namespace_id_str.push_back(1);
66   }
67 
68   return absl_ports::StrCat(encoded_namespace_id_str,
69                             encode_util::EncodeIntToCString(fingerprint_));
70 }
71 
72 }  // namespace lib
73 }  // namespace icing
74