KHtml

kjs_arraybuffer.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2013 Bernd Buschinski <[email protected]>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include "ecma/kjs_arraybuffer.h"
21 
22 #include <kjs/operations.h>
23 
24 #include "kjs_arraybuffer.lut.h"
25 
26 namespace KJS
27 {
28 
29 ArrayBufferConstructorImp::ArrayBufferConstructorImp(ExecState *exec, DOM::DocumentImpl *d)
30  : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), doc(d)
31 {
32 }
33 
34 bool ArrayBufferConstructorImp::implementsConstruct() const
35 {
36  return true;
37 }
38 
39 JSObject *ArrayBufferConstructorImp::construct(ExecState * /*exec*/, const List &args)
40 {
41  double sizeF = 0.0;
42  size_t size = 0;
43  if (args[0]->getNumber(sizeF)) {
44  if (!KJS::isNaN(sizeF) && !KJS::isInf(sizeF) && sizeF > 0) {
45  size = static_cast<size_t>(sizeF);
46  }
47  }
48 
49  return new ArrayBuffer(size);
50 }
51 
52 /* Source for ArrayBufferProtoTable.
53 
54 @begin ArrayBufferProtoTable 1
55  splice ArrayBuffer::Splice Function|DontDelete 1
56 @end
57 
58 */
59 
60 KJS_DEFINE_PROTOTYPE(ArrayBufferProto)
61 KJS_IMPLEMENT_PROTOFUNC(ArrayBufferProtoFunc)
62 KJS_IMPLEMENT_PROTOTYPE("ArrayBuffer", ArrayBufferProto, ArrayBufferProtoFunc, ObjectPrototype)
63 
64 const ClassInfo ArrayBuffer::info = { "ArrayBuffer", nullptr, &ArrayBufferTable, nullptr };
65 
66 /* Source for ArrayBufferTable.
67 
68 @begin ArrayBufferTable 1
69  byteLength ArrayBuffer::ByteLength ReadOnly|DontDelete
70 @end
71 
72 */
73 
74 ArrayBuffer::ArrayBuffer(size_t size)
75  : JSObject(),
76  m_size(size),
77  m_buffer(nullptr)
78 {
79  if (m_size > 0) {
80  m_buffer = new uint8_t[m_size];
81  memset(m_buffer, 0, m_size);
82  }
83 }
84 
85 ArrayBuffer::ArrayBuffer(uint8_t *buffer, size_t size)
86  : JSObject(),
87  m_size(size),
88  m_buffer(nullptr)
89 {
90  if (m_size > 0) {
91  m_buffer = new uint8_t[m_size];
92  memcpy(m_buffer, buffer, m_size);
93  }
94 }
95 
96 ArrayBuffer::~ArrayBuffer()
97 {
98  delete[] m_buffer;
99 }
100 
101 bool ArrayBuffer::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot)
102 {
103  return getStaticValueSlot<ArrayBuffer, JSObject>(exec, &ArrayBufferTable, this, propertyName, slot);
104 }
105 
106 JSValue *ArrayBuffer::getValueProperty(ExecState * /*exec*/, int token) const
107 {
108  switch (token) {
109  case ByteLength:
110  return jsNumber(m_size);
111  default:
112  return jsUndefined();
113  }
114 }
115 
116 // -------------------------- ArrayBufferProtoFunc ----------------------------
117 
118 JSValue *ArrayBufferProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
119 {
120  if (thisObj->inherits(&ArrayBuffer::info)) {
121  return throwError(exec, TypeError);
122  }
123 
124  ArrayBuffer *arraybuf = static_cast<ArrayBuffer *>(thisObj);
125  switch (id) {
126  case ArrayBuffer::Splice: {
127  // Slice takes max long/signed size_t
128  // If start or end are negative, it refers to an index from the end of the array
129  ssize_t start = 0;
130  ssize_t end = 0;
131  double tmp;
132  if (args[0]->getNumber(tmp)) {
133  start = static_cast<ssize_t>(tmp);
134  }
135  if (args.size() >= 2 && args[1]->getNumber(tmp)) {
136  end = static_cast<ssize_t>(tmp);
137  }
138 
139  // turn negative start/end into a valid positive index
140  if (start < 0 && arraybuf->byteLength() > static_cast<size_t>(-start)) {
141  start = arraybuf->byteLength() + start;
142  }
143  if (end < 0 && arraybuf->byteLength() > static_cast<size_t>(-end)) {
144  end = arraybuf->byteLength() + end;
145  }
146 
147  if (static_cast<size_t>(start) > arraybuf->byteLength()) {
148  start = arraybuf->byteLength();
149  }
150  if (static_cast<size_t>(end) > arraybuf->byteLength()) {
151  end = 0;
152  }
153 
154  size_t length = 0;
155  if (start < end) {
156  length = end - start;
157  } else if (args.size() < 2 && start > 0 && arraybuf->byteLength() > static_cast<size_t>(start)) {
158  length = arraybuf->byteLength() - start;
159  }
160 
161  ArrayBuffer *ret = new ArrayBuffer(length);
162  memcpy(ret->buffer(), arraybuf->buffer() + start, length);
163  return ret;
164  }
165  default:
166  return jsUndefined();
167  }
168 }
169 
170 } // namespace KJS
QSize size() const const
const QList< QKeySequence > & end()
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:47:56 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.