src: replace naive search in Buffer::IndexOf
[platform/upstream/nodejs.git] / src / util.h
1 #ifndef SRC_UTIL_H_
2 #define SRC_UTIL_H_
3
4 #include "v8.h"
5
6 #include <assert.h>
7 #include <signal.h>
8 #include <stddef.h>
9 #include <stdlib.h>
10
11 namespace node {
12
13 #define FIXED_ONE_BYTE_STRING(isolate, string)                                \
14   (node::OneByteString((isolate), (string), sizeof(string) - 1))
15
16 #define DISALLOW_COPY_AND_ASSIGN(TypeName)                                    \
17   void operator=(const TypeName&) = delete;                                   \
18   void operator=(TypeName&&) = delete;                                        \
19   TypeName(const TypeName&) = delete;                                         \
20   TypeName(TypeName&&) = delete
21
22 // Windows 8+ does not like abort() in Release mode
23 #ifdef _WIN32
24 #define ABORT() raise(SIGABRT)
25 #else
26 #define ABORT() abort()
27 #endif
28
29 #if defined(NDEBUG)
30 # define ASSERT(expression)
31 # define CHECK(expression)                                                    \
32   do {                                                                        \
33     if (!(expression)) ABORT();                                               \
34   } while (0)
35 #else
36 # define ASSERT(expression)  assert(expression)
37 # define CHECK(expression)   assert(expression)
38 #endif
39
40 #define ASSERT_EQ(a, b) ASSERT((a) == (b))
41 #define ASSERT_GE(a, b) ASSERT((a) >= (b))
42 #define ASSERT_GT(a, b) ASSERT((a) > (b))
43 #define ASSERT_LE(a, b) ASSERT((a) <= (b))
44 #define ASSERT_LT(a, b) ASSERT((a) < (b))
45 #define ASSERT_NE(a, b) ASSERT((a) != (b))
46
47 #define CHECK_EQ(a, b) CHECK((a) == (b))
48 #define CHECK_GE(a, b) CHECK((a) >= (b))
49 #define CHECK_GT(a, b) CHECK((a) > (b))
50 #define CHECK_LE(a, b) CHECK((a) <= (b))
51 #define CHECK_LT(a, b) CHECK((a) < (b))
52 #define CHECK_NE(a, b) CHECK((a) != (b))
53
54 #define UNREACHABLE() ABORT()
55
56 // TAILQ-style intrusive list node.
57 template <typename T>
58 class ListNode;
59
60 template <typename T>
61 using ListNodeMember = ListNode<T> T::*;
62
63 // VS 2013 doesn't understand dependent templates.
64 #ifdef _MSC_VER
65 #define ListNodeMember(T) ListNodeMember
66 #else
67 #define ListNodeMember(T) ListNodeMember<T>
68 #endif
69
70 // TAILQ-style intrusive list head.
71 template <typename T, ListNodeMember(T) M>
72 class ListHead;
73
74 template <typename T>
75 class ListNode {
76  public:
77   inline ListNode();
78   inline ~ListNode();
79   inline void Remove();
80   inline bool IsEmpty() const;
81
82  private:
83   template <typename U, ListNodeMember(U) M> friend class ListHead;
84   ListNode* prev_;
85   ListNode* next_;
86   DISALLOW_COPY_AND_ASSIGN(ListNode);
87 };
88
89 template <typename T, ListNodeMember(T) M>
90 class ListHead {
91  public:
92   class Iterator {
93    public:
94     inline T* operator*() const;
95     inline const Iterator& operator++();
96     inline bool operator!=(const Iterator& that) const;
97
98    private:
99     friend class ListHead;
100     inline explicit Iterator(ListNode<T>* node);
101     ListNode<T>* node_;
102   };
103
104   inline ListHead() = default;
105   inline ~ListHead();
106   inline void MoveBack(ListHead* that);
107   inline void PushBack(T* element);
108   inline void PushFront(T* element);
109   inline bool IsEmpty() const;
110   inline T* PopFront();
111   inline Iterator begin() const;
112   inline Iterator end() const;
113
114  private:
115   ListNode<T> head_;
116   DISALLOW_COPY_AND_ASSIGN(ListHead);
117 };
118
119 // The helper is for doing safe downcasts from base types to derived types.
120 template <typename Inner, typename Outer>
121 class ContainerOfHelper {
122  public:
123   inline ContainerOfHelper(Inner Outer::*field, Inner* pointer);
124   template <typename TypeName>
125   inline operator TypeName*() const;
126  private:
127   Outer* const pointer_;
128 };
129
130 // Calculate the address of the outer (i.e. embedding) struct from
131 // the interior pointer to a data member.
132 template <typename Inner, typename Outer>
133 inline ContainerOfHelper<Inner, Outer> ContainerOf(Inner Outer::*field,
134                                                    Inner* pointer);
135
136 // If persistent.IsWeak() == false, then do not call persistent.Reset()
137 // while the returned Local<T> is still in scope, it will destroy the
138 // reference to the object.
139 template <class TypeName>
140 inline v8::Local<TypeName> PersistentToLocal(
141     v8::Isolate* isolate,
142     const v8::Persistent<TypeName>& persistent);
143
144 // Unchecked conversion from a non-weak Persistent<T> to Local<TLocal<T>,
145 // use with care!
146 //
147 // Do not call persistent.Reset() while the returned Local<T> is still in
148 // scope, it will destroy the reference to the object.
149 template <class TypeName>
150 inline v8::Local<TypeName> StrongPersistentToLocal(
151     const v8::Persistent<TypeName>& persistent);
152
153 template <class TypeName>
154 inline v8::Local<TypeName> WeakPersistentToLocal(
155     v8::Isolate* isolate,
156     const v8::Persistent<TypeName>& persistent);
157
158 // Convenience wrapper around v8::String::NewFromOneByte().
159 inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
160                                            const char* data,
161                                            int length = -1);
162
163 // For the people that compile with -funsigned-char.
164 inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
165                                            const signed char* data,
166                                            int length = -1);
167
168 inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
169                                            const unsigned char* data,
170                                            int length = -1);
171
172 inline void Wrap(v8::Local<v8::Object> object, void* pointer);
173
174 inline void ClearWrap(v8::Local<v8::Object> object);
175
176 template <typename TypeName>
177 inline TypeName* Unwrap(v8::Local<v8::Object> object);
178
179 class Utf8Value {
180   public:
181     explicit Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> value);
182
183     ~Utf8Value() {
184       if (str_ != str_st_)
185         free(str_);
186     }
187
188     char* operator*() {
189       return str_;
190     };
191
192     const char* operator*() const {
193       return str_;
194     };
195
196     size_t length() const {
197       return length_;
198     };
199
200   private:
201     size_t length_;
202     char* str_;
203     char str_st_[1024];
204 };
205
206 }  // namespace node
207
208 #endif  // SRC_UTIL_H_