18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#ifndef ArrayBufferView_h
276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#define ArrayBufferView_h
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "ArrayBuffer.h"
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ExceptionCode.h"
31dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
32dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <algorithm>
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <limits.h>
34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/PassRefPtr.h>
35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/RefCounted.h>
36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/RefPtr.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenclass ArrayBufferView : public RefCounted<ArrayBufferView> {
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block  public:
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual bool isByteArray() const { return false; }
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual bool isUnsignedByteArray() const { return false; }
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual bool isShortArray() const { return false; }
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual bool isUnsignedShortArray() const { return false; }
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual bool isIntArray() const { return false; }
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual bool isUnsignedIntArray() const { return false; }
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual bool isFloatArray() const { return false; }
4937da970a4978c0729b6a37c13d0ebc6a17c6d573Ben Murdoch    virtual bool isDoubleArray() const { return false; }
504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    virtual bool isDataView() const { return false; }
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    PassRefPtr<ArrayBuffer> buffer() const
536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return m_buffer;
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    void* baseAddress() const
586c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return m_baseAddress;
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    unsigned byteOffset() const
636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return m_byteOffset;
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    virtual unsigned byteLength() const = 0;
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    virtual ~ArrayBufferView();
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block  protected:
726c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    ArrayBufferView(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset);
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    void setImpl(ArrayBufferView* array, unsigned byteOffset, ExceptionCode& ec);
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
765abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    void setRangeImpl(const char* data, size_t dataByteLength, unsigned byteOffset, ExceptionCode& ec);
775abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
785abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    void zeroRangeImpl(unsigned byteOffset, size_t rangeByteLength, ExceptionCode& ec);
795abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static void calculateOffsetAndLength(int start, int end, unsigned arraySize,
816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                                         unsigned* offset, unsigned* length);
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Helper to verify that a given sub-range of an ArrayBuffer is
84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // within range.
85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    template <typename T>
866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static bool verifySubRange(PassRefPtr<ArrayBuffer> buffer,
87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                               unsigned byteOffset,
88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                               unsigned numElements)
89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!buffer)
91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (sizeof(T) > 1 && byteOffset % sizeof(T))
93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (byteOffset > buffer->byteLength())
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        unsigned remainingElements = (buffer->byteLength() - byteOffset) / sizeof(T);
97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (numElements > remainingElements)
98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return false;
99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Input offset is in number of elements from this array's view;
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // output offset is in number of bytes from the underlying buffer's view.
104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    template <typename T>
1056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static void clampOffsetAndNumElements(PassRefPtr<ArrayBuffer> buffer,
106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                                          unsigned arrayByteOffset,
107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                                          unsigned *offset,
108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                                          unsigned *numElements)
109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        unsigned maxOffset = (UINT_MAX - arrayByteOffset) / sizeof(T);
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (*offset > maxOffset) {
112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            *offset = buffer->byteLength();
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            *numElements = 0;
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return;
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *offset = arrayByteOffset + *offset * sizeof(T);
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *offset = std::min(buffer->byteLength(), *offset);
118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        unsigned remainingElements = (buffer->byteLength() - *offset) / sizeof(T);
119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        *numElements = std::min(remainingElements, *numElements);
120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // This is the address of the ArrayBuffer's storage, plus the byte offset.
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    void* m_baseAddress;
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    unsigned m_byteOffset;
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block  private:
1286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    RefPtr<ArrayBuffer> m_buffer;
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block};
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#endif // ArrayBufferView_h
134