webengine/device/src/DeviceLiwMap.cpp
changeset 0 dd21522fd290
child 10 a359256acfc6
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <config.h>
       
    21 #include <lookup.h>
       
    22 #include <PropertyNameArray.h>
       
    23 #include "DeviceLiwMap.h"
       
    24 #include "DeviceLiwBinding.h"
       
    25 #include "array_instance.h"
       
    26 #include <liwvariant.h>
       
    27 
       
    28 const TInt KMaxKeySize = 255;
       
    29 
       
    30 using namespace KJS;
       
    31 const ClassInfo DeviceLiwMap::info = { "DeviceLiwMap", 0/*&ArrayInstance::info*/, 0, 0 };
       
    32 
       
    33 // ============================= LOCAL FUNCTIONS ===============================
       
    34 /*
       
    35 @begin DeviceLiwMapTable 1
       
    36     close DeviceLiwMap::close DontDelete|Function 0
       
    37 @end
       
    38 */
       
    39 
       
    40 // ============================ MEMBER FUNCTIONS ===============================
       
    41 
       
    42 // ----------------------------------------------------------------------------
       
    43 // DeviceLiwMap::DeviceLiwMap
       
    44 //
       
    45 // ----------------------------------------------------------------------------
       
    46 //
       
    47 DeviceLiwMap::DeviceLiwMap( JSValue* proto, const CLiwMap* liwMap, CDeviceLiwBinding* liwBinding)
       
    48     : JSObject(proto)
       
    49     {
       
    50         m_privateData = new DeviceLiwMapPrivate(liwMap, liwBinding);
       
    51         if (!m_privateData )
       
    52             m_valid = false;
       
    53         else
       
    54             {
       
    55             m_valid = true;
       
    56             // protect this object
       
    57             KJS::Collector::protect(this);   
       
    58             }            
       
    59     }
       
    60 
       
    61 
       
    62 
       
    63 // ----------------------------------------------------------------------------
       
    64 // DeviceLiwMap::~DeviceLiwMap
       
    65 //
       
    66 // ----------------------------------------------------------------------------
       
    67 //
       
    68 DeviceLiwMap::~DeviceLiwMap()
       
    69     {
       
    70         // only can be called by garbage collection after the 
       
    71         // DeviceLiwMap::Close() was called
       
    72     }
       
    73     
       
    74 // ----------------------------------------------------------------------------
       
    75 // DeviceLiwMap::Close()
       
    76 //
       
    77 // ----------------------------------------------------------------------------
       
    78 //
       
    79 void DeviceLiwMap::Close( ExecState* exec, bool unmark )
       
    80     {
       
    81     // avoid double close    
       
    82     if(!m_valid) 
       
    83         {   
       
    84         if(unmark) 
       
    85             {
       
    86             // unprotect this to allow the garbage collection to release this jsobject
       
    87             KJS::Collector::unprotect(this);
       
    88             }
       
    89         return;
       
    90         }        
       
    91     
       
    92     if (exec) 
       
    93         {
       
    94         PropertyNameArray propertyNames;
       
    95         this->getPropertyNames( exec, propertyNames );
       
    96         unsigned size = static_cast<unsigned>(propertyNames.size());
       
    97 
       
    98         for (unsigned i = 0; i < size; i++)
       
    99             {
       
   100             JSValue * jsvalue = this->get( exec, propertyNames[i] );
       
   101             if(jsvalue->isObject()) 
       
   102                 {
       
   103                 JSObject * prop = jsvalue->toObject( exec );            
       
   104                 
       
   105                 if (prop->inherits( &DeviceLiwIterable::info ))
       
   106                     {
       
   107                     (static_cast<DeviceLiwIterable*>(prop))->Close(exec, true);
       
   108                     }
       
   109                 else if (prop->inherits( &DeviceLiwMap::info ))
       
   110                     {
       
   111                     (static_cast<DeviceLiwMap*>(prop))->Close(exec, true);
       
   112                     }
       
   113                 }        
       
   114             }                
       
   115         }    
       
   116     
       
   117     delete m_privateData;
       
   118     m_privateData = NULL;
       
   119     m_valid = false;
       
   120     
       
   121     if(unmark) 
       
   122         {
       
   123         // unprotect this to allow the garbage collection to release this jsobject
       
   124         KJS::Collector::unprotect(this);
       
   125         }
       
   126     }
       
   127     
       
   128 // ----------------------------------------------------------------------------
       
   129 // Device::toString
       
   130 //
       
   131 //
       
   132 // ----------------------------------------------------------------------------
       
   133 //
       
   134 UString DeviceLiwMap::toString( ExecState* /*exec*/ ) const
       
   135     {
       
   136     return "[object DeviceLiwMap]";
       
   137     }
       
   138 
       
   139 // ----------------------------------------------------------------------------
       
   140 // DeviceLiwMap::getOwnPropertySlot
       
   141 //
       
   142 //
       
   143 // ----------------------------------------------------------------------------
       
   144 bool DeviceLiwMap::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
       
   145 {
       
   146     // When the DeviceLiwMap is valid, the check order is
       
   147     //      DeviceLiwMap table => own property => prototype property
       
   148     // When the DeviceLiwMap is invalid (after close), the check order is
       
   149     //      close function in table => prototype property
       
   150 
       
   151     // 1. when it is valid    
       
   152     if(m_valid) 
       
   153         {
       
   154         // 1.1 check DeviceLiwMap table
       
   155         const HashEntry* entry = Lookup::findEntry(&DeviceLiwMapTable, propertyName);
       
   156         if (entry)
       
   157             {
       
   158             slot.setStaticEntry(this, entry, staticValueGetter<DeviceLiwMap>);
       
   159             return true;
       
   160             }
       
   161 
       
   162         // 1.2 check own property
       
   163         m_privateData->m_propName = propertyName;
       
   164         if (!getDirect(propertyName))
       
   165             {
       
   166             // 1.3 check prototypes
       
   167             JSObject *proto = static_cast<JSObject *>(this->prototype());
       
   168 
       
   169             while (!proto->isNull() && proto->isObject()) {
       
   170                 if (proto->getOwnPropertySlot(exec, propertyName, slot))
       
   171                     return true;
       
   172 
       
   173                 proto = static_cast<JSObject *>(proto->prototype());
       
   174             }
       
   175 
       
   176             if (!m_privateData->m_liwMap)
       
   177                 return false;
       
   178 
       
   179             if ( propertyName.size() >= KMaxKeySize )
       
   180                 throwError( exec, GeneralError, "key name too long" );
       
   181 
       
   182             // Store the property in the object so we get the same one each time.
       
   183             TLiwVariant detail;
       
   184             char prop_name8[KMaxKeySize];
       
   185             UChar * u_propname = (UChar *)propertyName.data();
       
   186             for (int i = 0; i < propertyName.size(); i++)
       
   187             {
       
   188                 prop_name8[i] = u_propname[i].low();
       
   189             }
       
   190             prop_name8[propertyName.size()] = NULL;
       
   191             TBuf8<KMaxKeySize> prop_name((const unsigned char *)prop_name8);
       
   192 
       
   193             if (!m_privateData->m_liwMap->FindL(prop_name, detail))
       
   194                 return false;
       
   195             JSValue* result = m_privateData->m_liwBinding->LiwVariant2JsVal(exec, detail);
       
   196             if ( result->type() == UndefinedType || exec->hadException() )
       
   197                 return false;
       
   198             else
       
   199                 this->putDirect( propertyName, result, DontDelete|ReadOnly );
       
   200             }
       
   201         return JSObject::getOwnPropertySlot(exec, propertyName, slot);
       
   202         }
       
   203     // when it is invalid
       
   204     else
       
   205         {
       
   206         // 2.1 check close() function
       
   207         if (propertyName == "close")
       
   208             {
       
   209             const HashEntry* entry = Lookup::findEntry(&DeviceLiwMapTable, propertyName);
       
   210             if (entry)
       
   211                 {
       
   212                 slot.setStaticEntry(this, entry, staticValueGetter<DeviceLiwMap>);
       
   213                 return true;
       
   214                 }
       
   215             }
       
   216 
       
   217         // 2.2 check prototypes
       
   218         JSObject *proto = static_cast<JSObject *>(this->prototype());
       
   219         while (!proto->isNull() && proto->isObject())
       
   220             {
       
   221             if (proto->getOwnPropertySlot(exec, propertyName, slot))
       
   222                 return true;
       
   223 
       
   224             proto = static_cast<JSObject *>(proto->prototype());
       
   225             }
       
   226         }
       
   227 
       
   228     return false;
       
   229 }
       
   230 
       
   231 
       
   232 // ----------------------------------------------------------------------------
       
   233 // DeviceLiwMap::getValueProperty
       
   234 //
       
   235 // ----------------------------------------------------------------------------
       
   236 JSValue* DeviceLiwMap::getValueProperty(ExecState *exec, int token) const
       
   237     {
       
   238     switch (token)
       
   239             {
       
   240             case close:
       
   241                 {
       
   242                 return new DeviceLiwMapFunc(exec, token);;
       
   243                 }
       
   244             default:
       
   245                 if(m_valid)
       
   246                     return getDirect(m_privateData->m_propName);
       
   247                 else
       
   248                     return jsUndefined();                
       
   249             }
       
   250     }
       
   251     
       
   252 // ---------------------------------------------------------------------------
       
   253 // DeviceLiwMapPrivate constructor
       
   254 //
       
   255 // ---------------------------------------------------------------------------
       
   256 DeviceLiwMapPrivate::DeviceLiwMapPrivate(const CLiwMap* liwMap, CDeviceLiwBinding* liwBinding)
       
   257     {
       
   258     TRAP_IGNORE(
       
   259             m_liwBinding = liwBinding;    
       
   260             m_liwMap = (CLiwMap*) liwMap;
       
   261             if ( m_liwMap )
       
   262                 m_liwMap->IncRef();
       
   263             )
       
   264     }
       
   265     
       
   266 // ---------------------------------------------------------------------------
       
   267 // DeviceLiwMapPrivate::Close
       
   268 //
       
   269 // ---------------------------------------------------------------------------
       
   270 void DeviceLiwMapPrivate::Close()
       
   271     {
       
   272        m_liwBinding = NULL;
       
   273         
       
   274     // release the map    
       
   275     if ( m_liwMap ) 
       
   276         {
       
   277         m_liwMap->DecRef();
       
   278         m_liwMap = NULL;
       
   279         }        
       
   280     }
       
   281     
       
   282 // ----------------------------------------------------------------------------
       
   283 // DeviceLiwMapFunc::DeviceLiwMapFunc
       
   284 //
       
   285 // ----------------------------------------------------------------------------
       
   286 //
       
   287 DeviceLiwMapFunc::DeviceLiwMapFunc( ExecState* exec, int token )
       
   288     : JSObject( exec->lexicalInterpreter()->builtinObjectPrototype() ),
       
   289     m_func( token )
       
   290     {
       
   291     }
       
   292 
       
   293 // ----------------------------------------------------------------------------
       
   294 // DeviceLiwMapFunc::call
       
   295 //
       
   296 // ----------------------------------------------------------------------------
       
   297 //
       
   298 JSValue* DeviceLiwMapFunc::callAsFunction(ExecState* exec, JSObject *thisObj, const List& aArgs )
       
   299     {
       
   300         if (!thisObj->inherits(&DeviceLiwMap::info)) {
       
   301             return throwError(exec, GeneralError);
       
   302         }
       
   303 
       
   304         DeviceLiwMap *map = static_cast<DeviceLiwMap *>(thisObj);
       
   305 
       
   306         if ( m_func == DeviceLiwMap::close ) 
       
   307             {
       
   308             map->Close(exec, false);
       
   309             }
       
   310         return jsUndefined();
       
   311     }
       
   312 
       
   313 //END OF FILE
       
   314 
       
   315 
       
   316 
       
   317