#ifndef SRC_UTIL_INL_H_ #define SRC_UTIL_INL_H_ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include "util.h" namespace node { template ListNode::ListNode() : prev_(this), next_(this) {} template ListNode::~ListNode() { Remove(); } template void ListNode::Remove() { prev_->next_ = next_; next_->prev_ = prev_; prev_ = this; next_ = this; } template bool ListNode::IsEmpty() const { return prev_ == this; } template ListHead::Iterator::Iterator(ListNode* node) : node_(node) {} template T* ListHead::Iterator::operator*() const { return ContainerOf(M, node_); } template const typename ListHead::Iterator& ListHead::Iterator::operator++() { node_ = node_->next_; return *this; } template bool ListHead::Iterator::operator!=(const Iterator& that) const { return node_ != that.node_; } template ListHead::~ListHead() { while (IsEmpty() == false) head_.next_->Remove(); } template void ListHead::MoveBack(ListHead* that) { if (IsEmpty()) return; ListNode* to = &that->head_; head_.next_->prev_ = to->prev_; to->prev_->next_ = head_.next_; head_.prev_->next_ = to; to->prev_ = head_.prev_; head_.prev_ = &head_; head_.next_ = &head_; } template void ListHead::PushBack(T* element) { ListNode* that = &(element->*M); head_.prev_->next_ = that; that->prev_ = head_.prev_; that->next_ = &head_; head_.prev_ = that; } template void ListHead::PushFront(T* element) { ListNode* that = &(element->*M); head_.next_->prev_ = that; that->prev_ = &head_; that->next_ = head_.next_; head_.next_ = that; } template bool ListHead::IsEmpty() const { return head_.IsEmpty(); } template T* ListHead::PopFront() { if (IsEmpty()) return nullptr; ListNode* node = head_.next_; node->Remove(); return ContainerOf(M, node); } template typename ListHead::Iterator ListHead::begin() const { return Iterator(head_.next_); } template typename ListHead::Iterator ListHead::end() const { return Iterator(const_cast*>(&head_)); } template ContainerOfHelper::ContainerOfHelper(Inner Outer::*field, Inner* pointer) : pointer_(reinterpret_cast( reinterpret_cast(pointer) - reinterpret_cast(&(static_cast(0)->*field)))) { } template template ContainerOfHelper::operator TypeName*() const { return static_cast(pointer_); } template inline ContainerOfHelper ContainerOf(Inner Outer::*field, Inner* pointer) { return ContainerOfHelper(field, pointer); } template inline v8::Local PersistentToLocal( v8::Isolate* isolate, const v8::Persistent& persistent) { if (persistent.IsWeak()) { return WeakPersistentToLocal(isolate, persistent); } else { return StrongPersistentToLocal(persistent); } } template inline v8::Local StrongPersistentToLocal( const v8::Persistent& persistent) { return *reinterpret_cast*>( const_cast*>(&persistent)); } template inline v8::Local WeakPersistentToLocal( v8::Isolate* isolate, const v8::Persistent& persistent) { return v8::Local::New(isolate, persistent); } inline v8::Local OneByteString(v8::Isolate* isolate, const char* data, int length) { return v8::String::NewFromOneByte(isolate, reinterpret_cast(data), v8::NewStringType::kNormal, length).ToLocalChecked(); } inline v8::Local OneByteString(v8::Isolate* isolate, const signed char* data, int length) { return v8::String::NewFromOneByte(isolate, reinterpret_cast(data), v8::NewStringType::kNormal, length).ToLocalChecked(); } inline v8::Local OneByteString(v8::Isolate* isolate, const unsigned char* data, int length) { return v8::String::NewFromOneByte(isolate, reinterpret_cast(data), v8::NewStringType::kNormal, length).ToLocalChecked(); } template void Wrap(v8::Local object, TypeName* pointer) { CHECK_EQ(false, object.IsEmpty()); CHECK_GT(object->InternalFieldCount(), 0); object->SetAlignedPointerInInternalField(0, pointer); } void ClearWrap(v8::Local object) { Wrap(object, nullptr); } template TypeName* Unwrap(v8::Local object) { CHECK_EQ(false, object.IsEmpty()); CHECK_GT(object->InternalFieldCount(), 0); void* pointer = object->GetAlignedPointerFromInternalField(0); return static_cast(pointer); } void SwapBytes(uint16_t* dst, const uint16_t* src, size_t buflen) { for (size_t i = 0; i < buflen; i += 1) dst[i] = (src[i] << 8) | (src[i] >> 8); } char ToLower(char c) { return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; } bool StringEqualNoCase(const char* a, const char* b) { do { if (*a == '\0') return *b == '\0'; if (*b == '\0') return *a == '\0'; } while (ToLower(*a++) == ToLower(*b++)); return false; } } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #endif // SRC_UTIL_INL_H_