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