1 | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
4 | // |
5 | // Slice is a simple structure containing a pointer into some external |
6 | // storage and a size. The user of a Slice must ensure that the slice |
7 | // is not used after the corresponding external storage has been |
8 | // deallocated. |
9 | // |
10 | // Multiple threads can invoke const methods on a Slice without |
11 | // external synchronization, but if any of the threads may call a |
12 | // non-const method, all threads accessing the same Slice must use |
13 | // external synchronization. |
14 | |
15 | #ifndef STORAGE_LEVELDB_INCLUDE_SLICE_H_ |
16 | #define STORAGE_LEVELDB_INCLUDE_SLICE_H_ |
17 | |
18 | #include <cassert> |
19 | #include <cstddef> |
20 | #include <cstring> |
21 | #include <string> |
22 | |
23 | #include "leveldb/export.h" |
24 | |
25 | namespace leveldb { |
26 | |
27 | class LEVELDB_EXPORT Slice { |
28 | public: |
29 | // Create an empty slice. |
30 | Slice() : data_("" ), size_(0) {} |
31 | |
32 | // Create a slice that refers to d[0,n-1]. |
33 | Slice(const char* d, size_t n) : data_(d), size_(n) {} |
34 | |
35 | // Create a slice that refers to the contents of "s" |
36 | Slice(const std::string& s) : data_(s.data()), size_(s.size()) {} |
37 | |
38 | // Create a slice that refers to s[0,strlen(s)-1] |
39 | Slice(const char* s) : data_(s), size_(strlen(s)) {} |
40 | |
41 | // Intentionally copyable. |
42 | Slice(const Slice&) = default; |
43 | Slice& operator=(const Slice&) = default; |
44 | |
45 | // Return a pointer to the beginning of the referenced data |
46 | const char* data() const { return data_; } |
47 | |
48 | // Return the length (in bytes) of the referenced data |
49 | size_t size() const { return size_; } |
50 | |
51 | // Return true iff the length of the referenced data is zero |
52 | bool empty() const { return size_ == 0; } |
53 | |
54 | // Return the ith byte in the referenced data. |
55 | // REQUIRES: n < size() |
56 | char operator[](size_t n) const { |
57 | assert(n < size()); |
58 | return data_[n]; |
59 | } |
60 | |
61 | // Change this slice to refer to an empty array |
62 | void clear() { |
63 | data_ = "" ; |
64 | size_ = 0; |
65 | } |
66 | |
67 | // Drop the first "n" bytes from this slice. |
68 | void remove_prefix(size_t n) { |
69 | assert(n <= size()); |
70 | data_ += n; |
71 | size_ -= n; |
72 | } |
73 | |
74 | // Return a string that contains the copy of the referenced data. |
75 | std::string ToString() const { return std::string(data_, size_); } |
76 | |
77 | // Three-way comparison. Returns value: |
78 | // < 0 iff "*this" < "b", |
79 | // == 0 iff "*this" == "b", |
80 | // > 0 iff "*this" > "b" |
81 | int compare(const Slice& b) const; |
82 | |
83 | // Return true iff "x" is a prefix of "*this" |
84 | bool starts_with(const Slice& x) const { |
85 | return ((size_ >= x.size_) && (memcmp(data_, x.data_, x.size_) == 0)); |
86 | } |
87 | |
88 | private: |
89 | const char* data_; |
90 | size_t size_; |
91 | }; |
92 | |
93 | inline bool operator==(const Slice& x, const Slice& y) { |
94 | return ((x.size() == y.size()) && |
95 | (memcmp(x.data(), y.data(), x.size()) == 0)); |
96 | } |
97 | |
98 | inline bool operator!=(const Slice& x, const Slice& y) { return !(x == y); } |
99 | |
100 | inline int Slice::compare(const Slice& b) const { |
101 | const size_t min_len = (size_ < b.size_) ? size_ : b.size_; |
102 | int r = memcmp(data_, b.data_, min_len); |
103 | if (r == 0) { |
104 | if (size_ < b.size_) |
105 | r = -1; |
106 | else if (size_ > b.size_) |
107 | r = +1; |
108 | } |
109 | return r; |
110 | } |
111 | |
112 | } // namespace leveldb |
113 | |
114 | #endif // STORAGE_LEVELDB_INCLUDE_SLICE_H_ |
115 | |