1/*
2 * Copyright (C) 2013 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#pragma once
27
28#include "ArrayBuffer.h"
29#include "ArrayBufferView.h"
30
31namespace JSC {
32
33template<typename Adaptor>
34class GenericTypedArrayView final : public ArrayBufferView {
35protected:
36 GenericTypedArrayView(RefPtr<ArrayBuffer>&&, unsigned byteOffset, unsigned length);
37
38public:
39 static Ref<GenericTypedArrayView> create(unsigned length);
40 static Ref<GenericTypedArrayView> create(const typename Adaptor::Type* array, unsigned length);
41 static Ref<GenericTypedArrayView> create(RefPtr<ArrayBuffer>&&, unsigned byteOffset, unsigned length);
42 static RefPtr<GenericTypedArrayView> tryCreate(unsigned length);
43 static RefPtr<GenericTypedArrayView> tryCreate(const typename Adaptor::Type* array, unsigned length);
44 static RefPtr<GenericTypedArrayView> tryCreate(RefPtr<ArrayBuffer>&&, unsigned byteOffset, unsigned length);
45
46 static Ref<GenericTypedArrayView> createUninitialized(unsigned length);
47 static RefPtr<GenericTypedArrayView> tryCreateUninitialized(unsigned length);
48
49 typename Adaptor::Type* data() const { return static_cast<typename Adaptor::Type*>(baseAddress()); }
50
51 bool set(GenericTypedArrayView<Adaptor>* array, unsigned offset)
52 {
53 return setImpl(array, offset * sizeof(typename Adaptor::Type));
54 }
55
56 bool setRange(const typename Adaptor::Type* data, size_t count, unsigned offset)
57 {
58 return setRangeImpl(
59 reinterpret_cast<const char*>(data),
60 count * sizeof(typename Adaptor::Type),
61 offset * sizeof(typename Adaptor::Type));
62 }
63
64 bool zeroRange(unsigned offset, size_t count)
65 {
66 return zeroRangeImpl(offset * sizeof(typename Adaptor::Type), count * sizeof(typename Adaptor::Type));
67 }
68
69 void zeroFill() { zeroRange(0, length()); }
70
71 unsigned length() const
72 {
73 if (isNeutered())
74 return 0;
75 return byteLength() / sizeof(typename Adaptor::Type);
76 }
77
78 typename Adaptor::Type item(unsigned index) const
79 {
80 ASSERT_WITH_SECURITY_IMPLICATION(index < this->length());
81 return data()[index];
82 }
83
84 void set(unsigned index, double value) const
85 {
86 ASSERT_WITH_SECURITY_IMPLICATION(index < this->length());
87 data()[index] = Adaptor::toNativeFromDouble(value);
88 }
89
90 void setNative(unsigned index, typename Adaptor::Type value) const
91 {
92 ASSERT_WITH_SECURITY_IMPLICATION(index < this->length());
93 data()[index] = value;
94 }
95
96 bool getRange(typename Adaptor::Type* data, size_t count, unsigned offset)
97 {
98 return getRangeImpl(
99 reinterpret_cast<char*>(data),
100 count * sizeof(typename Adaptor::Type),
101 offset * sizeof(typename Adaptor::Type));
102 }
103
104 bool checkInboundData(unsigned offset, size_t count) const
105 {
106 unsigned length = this->length();
107 return (offset <= length
108 && offset + count <= length
109 // check overflow
110 && offset + count >= offset);
111 }
112
113 RefPtr<GenericTypedArrayView> subarray(int start) const;
114 RefPtr<GenericTypedArrayView> subarray(int start, int end) const;
115
116 TypedArrayType getType() const override
117 {
118 return Adaptor::typeValue;
119 }
120
121 JSArrayBufferView* wrap(ExecState*, JSGlobalObject*) override;
122};
123
124} // namespace JSC
125