/* * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TypedArrayAdaptors_h #define TypedArrayAdaptors_h #include "JSCJSValue.h" #include "MathCommon.h" #include "TypedArrayType.h" #include namespace JSC { template< typename TypeArg, typename ViewTypeArg, typename JSViewTypeArg, TypedArrayType typeValueArg> struct IntegralTypedArrayAdaptor { typedef TypeArg Type; typedef ViewTypeArg ViewType; typedef JSViewTypeArg JSViewType; static const TypedArrayType typeValue = typeValueArg; static JSValue toJSValue(Type value) { return jsNumber(value); } static double toDouble(Type value) { return static_cast(value); } static Type toNativeFromInt32(int32_t value) { return static_cast(value); } static Type toNativeFromUint32(uint32_t value) { return static_cast(value); } static Type toNativeFromDouble(double value) { int32_t result = static_cast(value); if (static_cast(result) != value) result = toInt32(value); return static_cast(result); } template static typename OtherAdaptor::Type convertTo(Type value) { if (typeValue == TypeUint32) return OtherAdaptor::toNativeFromUint32(value); return OtherAdaptor::toNativeFromInt32(value); } }; template< typename TypeArg, typename ViewTypeArg, typename JSViewTypeArg, TypedArrayType typeValueArg> struct FloatTypedArrayAdaptor { typedef TypeArg Type; typedef ViewTypeArg ViewType; typedef JSViewTypeArg JSViewType; static const TypedArrayType typeValue = typeValueArg; static JSValue toJSValue(Type value) { return jsDoubleNumber(purifyNaN(value)); } static double toDouble(Type value) { return static_cast(value); } static Type toNativeFromInt32(int32_t value) { return static_cast(value); } static Type toNativeFromUint32(uint32_t value) { return static_cast(value); } static Type toNativeFromDouble(double value) { return value; } template static typename OtherAdaptor::Type convertTo(Type value) { return OtherAdaptor::toNativeFromDouble(value); } }; struct Int8Adaptor; struct Int16Adaptor; struct Int32Adaptor; struct Uint8Adaptor; struct Uint8ClampedAdaptor; struct Uint16Adaptor; struct Uint32Adaptor; struct Float32Adaptor; struct Float64Adaptor; template class GenericTypedArrayView; typedef GenericTypedArrayView Int8Array; typedef GenericTypedArrayView Int16Array; typedef GenericTypedArrayView Int32Array; typedef GenericTypedArrayView Uint8Array; typedef GenericTypedArrayView Uint8ClampedArray; typedef GenericTypedArrayView Uint16Array; typedef GenericTypedArrayView Uint32Array; typedef GenericTypedArrayView Float32Array; typedef GenericTypedArrayView Float64Array; template class JSGenericTypedArrayView; typedef JSGenericTypedArrayView JSInt8Array; typedef JSGenericTypedArrayView JSInt16Array; typedef JSGenericTypedArrayView JSInt32Array; typedef JSGenericTypedArrayView JSUint8Array; typedef JSGenericTypedArrayView JSUint8ClampedArray; typedef JSGenericTypedArrayView JSUint16Array; typedef JSGenericTypedArrayView JSUint32Array; typedef JSGenericTypedArrayView JSFloat32Array; typedef JSGenericTypedArrayView JSFloat64Array; struct Int8Adaptor : IntegralTypedArrayAdaptor { }; struct Int16Adaptor : IntegralTypedArrayAdaptor { }; struct Int32Adaptor : IntegralTypedArrayAdaptor { }; struct Uint8Adaptor : IntegralTypedArrayAdaptor { }; struct Uint16Adaptor : IntegralTypedArrayAdaptor { }; struct Uint32Adaptor : IntegralTypedArrayAdaptor { }; struct Float32Adaptor : FloatTypedArrayAdaptor { }; struct Float64Adaptor : FloatTypedArrayAdaptor { }; struct Uint8ClampedAdaptor { typedef uint8_t Type; typedef Uint8ClampedArray ViewType; typedef JSUint8ClampedArray JSViewType; static const TypedArrayType typeValue = TypeUint8Clamped; static JSValue toJSValue(uint8_t value) { return jsNumber(value); } static double toDouble(uint8_t value) { return static_cast(value); } static Type toNativeFromInt32(int32_t value) { return clamp(value); } static Type toNativeFromUint32(uint32_t value) { return std::min(static_cast(255), value); } static Type toNativeFromDouble(double value) { if (std::isnan(value) || value < 0) return 0; if (value > 255) return 255; return static_cast(lrint(value)); } template static typename OtherAdaptor::Type convertTo(uint8_t value) { return OtherAdaptor::toNativeFromInt32(value); } private: static uint8_t clamp(int32_t value) { if (value < 0) return 0; if (value > 255) return 255; return static_cast(value); } }; } // namespace JSC #endif // TypedArrayAdaptors_h