1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.nashorn.internal.objects; 27 28 import java.util.Arrays; 29 import jdk.nashorn.internal.objects.annotations.Attribute; 30 import jdk.nashorn.internal.objects.annotations.Constructor; 31 import jdk.nashorn.internal.objects.annotations.Function; 32 import jdk.nashorn.internal.objects.annotations.Getter; 33 import jdk.nashorn.internal.objects.annotations.ScriptClass; 34 import jdk.nashorn.internal.runtime.JSType; 35 import jdk.nashorn.internal.runtime.PropertyMap; 36 import jdk.nashorn.internal.runtime.ScriptObject; 37 import jdk.nashorn.internal.runtime.ScriptRuntime; 38 39 @ScriptClass("ArrayBuffer") 40 final class NativeArrayBuffer extends ScriptObject { 41 private final byte[] buffer; 42 43 // initialized by nasgen 44 private static PropertyMap $nasgenmap$; 45 46 static PropertyMap getInitialMap() { 47 return $nasgenmap$; 48 } 49 50 @Constructor(arity = 1) 51 public static Object constructor(final boolean newObj, final Object self, final Object... args) { 52 if (args.length == 0) { 53 throw new RuntimeException("missing length argument"); 54 } 55 56 return new NativeArrayBuffer(JSType.toInt32(args[0])); 57 } 58 59 protected NativeArrayBuffer(final byte[] byteArray, final Global global) { 60 super(global.getArrayBufferPrototype(), global.getArrayBufferMap()); 61 this.buffer = byteArray; 62 } 63 64 protected NativeArrayBuffer(final byte[] byteArray) { 65 this(byteArray, Global.instance()); 66 } 67 68 protected NativeArrayBuffer(final int byteLength) { 69 this(new byte[byteLength]); 70 } 71 72 protected NativeArrayBuffer(final NativeArrayBuffer other, final int begin, final int end) { 73 this(Arrays.copyOfRange(other.buffer, begin, end)); 74 } 75 76 @Override 77 public String getClassName() { 78 return "ArrayBuffer"; 79 } 80 81 @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE) 82 public static Object byteLength(final Object self) { 83 return ((NativeArrayBuffer)self).buffer.length; 84 } 85 86 @Function(attributes = Attribute.NOT_ENUMERABLE) 87 public static Object slice(final Object self, final Object begin0, final Object end0) { 88 final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self; 89 int begin = JSType.toInt32(begin0); 90 int end = end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : arrayBuffer.getByteLength(); 91 begin = adjustIndex(begin, arrayBuffer.getByteLength()); 92 end = adjustIndex(end, arrayBuffer.getByteLength()); 93 return new NativeArrayBuffer((NativeArrayBuffer) self, begin, Math.max(end, begin)); 94 } 95 96 /** 97 * If index is negative, it refers to an index from the end of the array, as 98 * opposed to from the beginning. The index is clamped to the valid index 99 * range for the array. 100 * 101 * @param index The index. 102 * @param length The length of the array. 103 * @return valid index index in the range [0, length). 104 */ 105 static int adjustIndex(final int index, final int length) { 106 if (index < 0) { 107 return clamp(index + length, length); 108 } 109 return clamp(index, length); 110 } 111 112 /** 113 * Clamp index into the range [0, length). 114 */ 115 private static int clamp(final int index, final int length) { 116 if (index < 0) { 117 return 0; 118 } else if (index > length) { 119 return length; 120 } 121 return index; 122 } 123 124 public byte[] getByteArray() { 125 return buffer; 126 } 127 128 public int getByteLength() { 129 return buffer.length; 130 } 131 }