Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All Rights Reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef JSByteArray_h
     27 #define JSByteArray_h
     28 
     29 #include "JSObject.h"
     30 
     31 #include <wtf/ByteArray.h>
     32 
     33 namespace JSC {
     34 
     35     class JSByteArray : public JSObject {
     36         friend class JSGlobalData;
     37     public:
     38         bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
     39         JSValue getIndex(ExecState* exec, unsigned i)
     40         {
     41             ASSERT(canAccessIndex(i));
     42             return jsNumber(exec, m_storage->data()[i]);
     43         }
     44 
     45         void setIndex(unsigned i, int value)
     46         {
     47             ASSERT(canAccessIndex(i));
     48             if (value & ~0xFF) {
     49                 if (value < 0)
     50                     value = 0;
     51                 else
     52                     value = 255;
     53             }
     54             m_storage->data()[i] = static_cast<unsigned char>(value);
     55         }
     56 
     57         void setIndex(unsigned i, double value)
     58         {
     59             ASSERT(canAccessIndex(i));
     60             if (!(value > 0)) // Clamp NaN to 0
     61                 value = 0;
     62             else if (value > 255)
     63                 value = 255;
     64             m_storage->data()[i] = static_cast<unsigned char>(value + 0.5);
     65         }
     66 
     67         void setIndex(ExecState* exec, unsigned i, JSValue value)
     68         {
     69             double byteValue = value.toNumber(exec);
     70             if (exec->hadException())
     71                 return;
     72             if (canAccessIndex(i))
     73                 setIndex(i, byteValue);
     74         }
     75 
     76         JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure>, WTF::ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo);
     77         static PassRefPtr<Structure> createStructure(JSValue prototype);
     78 
     79         virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
     80         virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
     81         virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
     82         virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
     83         virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);
     84 
     85         virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
     86 
     87         virtual const ClassInfo* classInfo() const { return m_classInfo; }
     88         static const ClassInfo s_defaultInfo;
     89 
     90         size_t length() const { return m_storage->length(); }
     91 
     92         WTF::ByteArray* storage() const { return m_storage.get(); }
     93 
     94 #if !ASSERT_DISABLED
     95         virtual ~JSByteArray();
     96 #endif
     97 
     98     protected:
     99         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
    100 
    101     private:
    102         enum VPtrStealingHackType { VPtrStealingHack };
    103         JSByteArray(VPtrStealingHackType)
    104             : JSObject(createStructure(jsNull()))
    105             , m_classInfo(0)
    106         {
    107         }
    108 
    109         RefPtr<WTF::ByteArray> m_storage;
    110         const ClassInfo* m_classInfo;
    111     };
    112 
    113     JSByteArray* asByteArray(JSValue value);
    114     inline JSByteArray* asByteArray(JSValue value)
    115     {
    116         return static_cast<JSByteArray*>(asCell(value));
    117     }
    118 
    119     inline bool isJSByteArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsByteArrayVPtr; }
    120 
    121 } // namespace JSC
    122 
    123 #endif // JSByteArray_h
    124