• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copied from node_object_wrap.h
3  * see http://www.nodejs.org/
4  *
5  * Node's license follows:
6  *
7  * Copyright 2009, 2010 Ryan Lienhart Dahl. All rights reserved.
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to
10  * deal in the Software without restriction, including without limitation the
11  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12  * sell copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24  * IN THE SOFTWARE.
25  */
26 
27 #ifndef MOCK_RIL_NODE_OBJECT_WRAP_H_
28 #define MOCK_RIL_NODE_OBJECT_WRAP_H_
29 
30 #include <v8.h>
31 #include <assert.h>
32 
33 class ObjectWrap {
34  public:
ObjectWrap()35   ObjectWrap ( ) {
36     refs_ = 0;
37   }
38 
~ObjectWrap()39   virtual ~ObjectWrap ( ) {
40     if (!handle_.IsEmpty()) {
41       assert(handle_.IsNearDeath());
42       handle_->SetInternalField(0, v8::Undefined());
43       handle_.Dispose();
44       handle_.Clear();
45     }
46   }
47 
48   template <class T>
Unwrap(v8::Handle<v8::Object> handle)49   static inline T* Unwrap (v8::Handle<v8::Object> handle)
50   {
51     assert(!handle.IsEmpty());
52     assert(handle->InternalFieldCount() > 0);
53     return static_cast<T*>(v8::Handle<v8::External>::Cast(
54         handle->GetInternalField(0))->Value());
55   }
56 
57   v8::Persistent<v8::Object> handle_; // ro
58 
59  protected:
Wrap(v8::Handle<v8::Object> handle)60   inline void Wrap (v8::Handle<v8::Object> handle)
61   {
62     assert(handle_.IsEmpty());
63     assert(handle->InternalFieldCount() > 0);
64     handle_ = v8::Persistent<v8::Object>::New(handle);
65     handle_->SetInternalField(0, v8::External::New(this));
66     MakeWeak();
67   }
68 
MakeWeak(void)69   inline void MakeWeak (void)
70   {
71     handle_.MakeWeak(this, WeakCallback);
72   }
73 
74   /* Ref() marks the object as being attached to an event loop.
75    * Refed objects will not be garbage collected, even if
76    * all references are lost.
77    */
Ref()78   virtual void Ref() {
79     assert(!handle_.IsEmpty());
80     refs_++;
81     handle_.ClearWeak();
82   }
83 
84   /* Unref() marks an object as detached from the event loop.  This is its
85    * default state.  When an object with a "weak" reference changes from
86    * attached to detached state it will be freed. Be careful not to access
87    * the object after making this call as it might be gone!
88    * (A "weak reference" means an object that only has a
89    * persistant handle.)
90    *
91    * DO NOT CALL THIS FROM DESTRUCTOR
92    */
Unref()93   virtual void Unref() {
94     assert(!handle_.IsEmpty());
95     assert(!handle_.IsWeak());
96     assert(refs_ > 0);
97     if (--refs_ == 0) { MakeWeak(); }
98   }
99 
100   int refs_; // ro
101 
102  private:
WeakCallback(v8::Persistent<v8::Value> value,void * data)103   static void WeakCallback (v8::Persistent<v8::Value> value, void *data)
104   {
105     ObjectWrap *obj = static_cast<ObjectWrap*>(data);
106     assert(value == obj->handle_);
107     assert(!obj->refs_);
108     if (value.IsNearDeath()) delete obj;
109   }
110 };
111 
112 #endif // MOCK_RIL_NODE_OBJECT_WRAP_H_
113