1 #include "common/platform.h"
2
3 #include <cassert>
4 #include <cstdlib>
5 #include <cstring>
6 #include <algorithm>
7
8 #include "master/hstring_memstorage.h"
9
10 using namespace hstorage;
11
12 #if !defined(NDEBUG) || defined(LIZARDFS_TEST_POINTER_OBFUSCATION)
13 std::set<char *> *MemStorage::debug_ptr_ = nullptr;
14 #endif
15
compare(const Handle & handle,const HString & str)16 bool MemStorage::compare(const Handle &handle, const HString &str) {
17 if (hash(handle) == static_cast<HashType>(str.hash())) {
18 return str == c_str(handle);
19 }
20 return false;
21 }
22
get(const Handle & handle)23 ::std::string MemStorage::get(const Handle &handle) {
24 return c_str(handle);
25 }
26
copy(Handle & handle,const Handle & other)27 void MemStorage::copy(Handle &handle, const Handle &other) {
28 char *copied = strdup(c_str(other));
29 if (!copied) {
30 throw std::bad_alloc();
31 }
32 handle.data() = encode(copied, hash(other));
33
34 #if !defined(NDEBUG) || defined(LIZARDFS_TEST_POINTER_OBFUSCATION)
35 if (!debug_ptr_) {
36 debug_ptr_ = new std::set<char *>();
37 }
38 debug_ptr_->insert(copied);
39 #endif
40 }
41
42 /*
43 * Binding hstring to handle:
44 * 1. Copy C-style string
45 * 2. Encode C-style string combined with its hash in an obfuscated pointer
46 */
bind(Handle & handle,const HString & str)47 void MemStorage::bind(Handle &handle, const HString &str) {
48 HString::size_type size = str.size() + 1;
49 char *copied = (char *)malloc(size * sizeof(HString::value_type));
50 if (!copied) {
51 throw std::bad_alloc();
52 }
53 memcpy(copied, str.c_str(), size);
54 handle.data() = encode(copied, str.hash());
55
56 #if !defined(NDEBUG) || defined(LIZARDFS_TEST_POINTER_OBFUSCATION)
57 if (!debug_ptr_) {
58 debug_ptr_ = new std::set<char *>();
59 }
60 debug_ptr_->insert(copied);
61 #endif
62 }
63
encode(const char * ptr,HashType hash)64 MemStorage::ValueType MemStorage::encode(const char *ptr, HashType hash) {
65 return static_cast<ValueType>(reinterpret_cast<uintptr_t>(ptr))
66 | (static_cast<ValueType>(hash) << kShift);
67 }
68
unbind(Handle & handle)69 void MemStorage::unbind(Handle &handle) {
70 #if !defined(NDEBUG) || defined(LIZARDFS_TEST_POINTER_OBFUSCATION)
71 char *ptr = c_str(handle);
72 if (ptr) {
73 if (!debug_ptr_) {
74 debug_ptr_ = new std::set<char *>();
75 }
76 auto it = debug_ptr_->find(ptr);
77 assert(it != debug_ptr_->end());
78 debug_ptr_->erase(it);
79 }
80 #endif
81 free(c_str(handle));
82 }
83
name() const84 ::std::string MemStorage::name() const {
85 return kName;
86 }
87