Home | History | Annotate | Download | only in wtf
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Copyright (c) 2010, Google Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #ifndef TypedArrayBase_h
     28 #define TypedArrayBase_h
     29 
     30 #include "wtf/ArrayBuffer.h"
     31 #include "wtf/ArrayBufferView.h"
     32 
     33 namespace WTF {
     34 
     35 template <typename T>
     36 class TypedArrayBase : public ArrayBufferView {
     37   public:
     38     T* data() const { return static_cast<T*>(baseAddress()); }
     39 
     40     bool set(TypedArrayBase<T>* array, unsigned offset)
     41     {
     42         return setImpl(array, offset * sizeof(T));
     43     }
     44 
     45     bool setRange(const T* data, size_t dataLength, unsigned offset)
     46     {
     47         return setRangeImpl(reinterpret_cast<const char*>(data), dataLength * sizeof(T), offset * sizeof(T));
     48     }
     49 
     50     bool zeroRange(unsigned offset, size_t length)
     51     {
     52         return zeroRangeImpl(offset * sizeof(T), length * sizeof(T));
     53     }
     54 
     55     // Overridden from ArrayBufferView. This must be public because of
     56     // rules about inheritance of members in template classes, and
     57     // because it is accessed via pointers to subclasses.
     58     unsigned length() const
     59     {
     60         return m_length;
     61     }
     62 
     63     virtual unsigned byteLength() const
     64     {
     65         return m_length * sizeof(T);
     66     }
     67 
     68     // Invoked by the indexed getter. Does not perform range checks; caller
     69     // is responsible for doing so and returning undefined as necessary.
     70     T item(unsigned index) const
     71     {
     72         ASSERT_WITH_SECURITY_IMPLICATION(index < TypedArrayBase<T>::m_length);
     73         return TypedArrayBase<T>::data()[index];
     74     }
     75 
     76     bool checkInboundData(unsigned offset, unsigned pos) const
     77     {
     78         return (offset <= m_length
     79             && offset + pos <= m_length
     80             // check overflow
     81             && offset + pos >= offset);
     82     }
     83 
     84 protected:
     85     TypedArrayBase(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
     86         : ArrayBufferView(buffer, byteOffset)
     87         , m_length(length)
     88     {
     89     }
     90 
     91     template <class Subclass>
     92     static PassRefPtr<Subclass> create(unsigned length)
     93     {
     94         RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(T));
     95         if (!buffer.get())
     96             return 0;
     97         return create<Subclass>(buffer, 0, length);
     98     }
     99 
    100     template <class Subclass>
    101     static PassRefPtr<Subclass> create(const T* array, unsigned length)
    102     {
    103         RefPtr<Subclass> a = create<Subclass>(length);
    104         if (a)
    105             for (unsigned i = 0; i < length; ++i)
    106                 a->set(i, array[i]);
    107         return a;
    108     }
    109 
    110     template <class Subclass>
    111     static PassRefPtr<Subclass> create(PassRefPtr<ArrayBuffer> buffer,
    112                                        unsigned byteOffset,
    113                                        unsigned length)
    114     {
    115         RefPtr<ArrayBuffer> buf(buffer);
    116         if (!verifySubRange<T>(buf, byteOffset, length))
    117             return 0;
    118 
    119         return adoptRef(new Subclass(buf, byteOffset, length));
    120     }
    121 
    122     template <class Subclass>
    123     static PassRefPtr<Subclass> createUninitialized(unsigned length)
    124     {
    125         RefPtr<ArrayBuffer> buffer = ArrayBuffer::createUninitialized(length, sizeof(T));
    126         if (!buffer.get())
    127             return 0;
    128         return create<Subclass>(buffer, 0, length);
    129     }
    130 
    131     template <class Subclass>
    132     PassRefPtr<Subclass> subarrayImpl(int start, int end) const
    133     {
    134         unsigned offset, length;
    135         calculateOffsetAndLength(start, end, m_length, &offset, &length);
    136         clampOffsetAndNumElements<T>(buffer(), m_byteOffset, &offset, &length);
    137         return create<Subclass>(buffer(), offset, length);
    138     }
    139 
    140     virtual void neuter()
    141     {
    142         ArrayBufferView::neuter();
    143         m_length = 0;
    144     }
    145 
    146     // We do not want to have to access this via a virtual function in subclasses,
    147     // which is why it is protected rather than private.
    148     unsigned m_length;
    149 };
    150 
    151 } // namespace WTF
    152 
    153 using WTF::TypedArrayBase;
    154 
    155 #endif // TypedArrayBase_h
    156