Warning, file /frameworks/khtml/src/ecma/kjs_arraybuffer.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 2013 Bernd Buschinski <b.buschinski@googlemail.com> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public 0016 * License along with this library; if not, write to the Free Software 0017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0018 */ 0019 0020 #include "ecma/kjs_arraybuffer.h" 0021 0022 #include <kjs/operations.h> 0023 0024 #include "kjs_arraybuffer.lut.h" 0025 0026 namespace KJS 0027 { 0028 0029 ArrayBufferConstructorImp::ArrayBufferConstructorImp(ExecState *exec, DOM::DocumentImpl *d) 0030 : JSObject(exec->lexicalInterpreter()->builtinObjectPrototype()), doc(d) 0031 { 0032 } 0033 0034 bool ArrayBufferConstructorImp::implementsConstruct() const 0035 { 0036 return true; 0037 } 0038 0039 JSObject *ArrayBufferConstructorImp::construct(ExecState * /*exec*/, const List &args) 0040 { 0041 double sizeF = 0.0; 0042 size_t size = 0; 0043 if (args[0]->getNumber(sizeF)) { 0044 if (!KJS::isNaN(sizeF) && !KJS::isInf(sizeF) && sizeF > 0) { 0045 size = static_cast<size_t>(sizeF); 0046 } 0047 } 0048 0049 return new ArrayBuffer(size); 0050 } 0051 0052 /* Source for ArrayBufferProtoTable. 0053 0054 @begin ArrayBufferProtoTable 1 0055 splice ArrayBuffer::Splice Function|DontDelete 1 0056 @end 0057 0058 */ 0059 0060 KJS_DEFINE_PROTOTYPE(ArrayBufferProto) 0061 KJS_IMPLEMENT_PROTOFUNC(ArrayBufferProtoFunc) 0062 KJS_IMPLEMENT_PROTOTYPE("ArrayBuffer", ArrayBufferProto, ArrayBufferProtoFunc, ObjectPrototype) 0063 0064 const ClassInfo ArrayBuffer::info = { "ArrayBuffer", nullptr, &ArrayBufferTable, nullptr }; 0065 0066 /* Source for ArrayBufferTable. 0067 0068 @begin ArrayBufferTable 1 0069 byteLength ArrayBuffer::ByteLength ReadOnly|DontDelete 0070 @end 0071 0072 */ 0073 0074 ArrayBuffer::ArrayBuffer(size_t size) 0075 : JSObject(), 0076 m_size(size), 0077 m_buffer(nullptr) 0078 { 0079 if (m_size > 0) { 0080 m_buffer = new uint8_t[m_size]; 0081 memset(m_buffer, 0, m_size); 0082 } 0083 } 0084 0085 ArrayBuffer::ArrayBuffer(uint8_t *buffer, size_t size) 0086 : JSObject(), 0087 m_size(size), 0088 m_buffer(nullptr) 0089 { 0090 if (m_size > 0) { 0091 m_buffer = new uint8_t[m_size]; 0092 memcpy(m_buffer, buffer, m_size); 0093 } 0094 } 0095 0096 ArrayBuffer::~ArrayBuffer() 0097 { 0098 delete[] m_buffer; 0099 } 0100 0101 bool ArrayBuffer::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) 0102 { 0103 return getStaticValueSlot<ArrayBuffer, JSObject>(exec, &ArrayBufferTable, this, propertyName, slot); 0104 } 0105 0106 JSValue *ArrayBuffer::getValueProperty(ExecState * /*exec*/, int token) const 0107 { 0108 switch (token) { 0109 case ByteLength: 0110 return jsNumber(m_size); 0111 default: 0112 return jsUndefined(); 0113 } 0114 } 0115 0116 // -------------------------- ArrayBufferProtoFunc ---------------------------- 0117 0118 JSValue *ArrayBufferProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) 0119 { 0120 if (thisObj->inherits(&ArrayBuffer::info)) { 0121 return throwError(exec, TypeError); 0122 } 0123 0124 ArrayBuffer *arraybuf = static_cast<ArrayBuffer *>(thisObj); 0125 switch (id) { 0126 case ArrayBuffer::Splice: { 0127 // Slice takes max long/signed size_t 0128 // If start or end are negative, it refers to an index from the end of the array 0129 ssize_t start = 0; 0130 ssize_t end = 0; 0131 double tmp; 0132 if (args[0]->getNumber(tmp)) { 0133 start = static_cast<ssize_t>(tmp); 0134 } 0135 if (args.size() >= 2 && args[1]->getNumber(tmp)) { 0136 end = static_cast<ssize_t>(tmp); 0137 } 0138 0139 // turn negative start/end into a valid positive index 0140 if (start < 0 && arraybuf->byteLength() > static_cast<size_t>(-start)) { 0141 start = arraybuf->byteLength() + start; 0142 } 0143 if (end < 0 && arraybuf->byteLength() > static_cast<size_t>(-end)) { 0144 end = arraybuf->byteLength() + end; 0145 } 0146 0147 if (static_cast<size_t>(start) > arraybuf->byteLength()) { 0148 start = arraybuf->byteLength(); 0149 } 0150 if (static_cast<size_t>(end) > arraybuf->byteLength()) { 0151 end = 0; 0152 } 0153 0154 size_t length = 0; 0155 if (start < end) { 0156 length = end - start; 0157 } else if (args.size() < 2 && start > 0 && arraybuf->byteLength() > static_cast<size_t>(start)) { 0158 length = arraybuf->byteLength() - start; 0159 } 0160 0161 ArrayBuffer *ret = new ArrayBuffer(length); 0162 memcpy(ret->buffer(), arraybuf->buffer() + start, length); 0163 return ret; 0164 } 0165 default: 0166 return jsUndefined(); 0167 } 0168 } 0169 0170 } // namespace KJS