/*
 * Copyright (C) 2010 Google 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
 */

module html {

    interface [
        CustomConstructor,
        ConstructorParameters=3,
        CustomToJSObject,
        JSNoStaticTables
    ] DataView : ArrayBufferView {
        // All these methods raise an exception if they would read or write beyond the end of the view.

        // We have to use custom code because our code generator does not support int8_t type.
        // int8_t getInt8(in unsigned long byteOffset);
        // uint8_t getUint8(in unsigned long byteOffset);
        [Custom] DOMObject getInt8()
            raises (DOMException);
        [Custom] DOMObject getUint8()
            raises (DOMException);

        [StrictTypeChecking] short getInt16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] unsigned short getUint16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] long getInt32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] unsigned long getUint32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
            raises (DOMException);

        // Use custom code to handle NaN case for JSC.
        [JSCustom, StrictTypeChecking] float getFloat32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
            raises (DOMException);
        [JSCustom, StrictTypeChecking] double getFloat64(in unsigned long byteOffset, in [Optional] boolean littleEndian)
            raises (DOMException);

        // We have to use custom code because our code generator does not support uint8_t type.
        // void setInt8(in unsigned long byteOffset, in int8_t value);
        // void setUint8(in unsigned long byteOffset, in uint8_t value);
        [Custom] void setInt8()
            raises (DOMException);
        [Custom] void setUint8()
            raises (DOMException);

        [StrictTypeChecking] void setInt16(in unsigned long byteOffset, in short value, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] void setUint16(in unsigned long byteOffset, in unsigned short value, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] void setInt32(in unsigned long byteOffset, in long value, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] void setUint32(in unsigned long byteOffset, in unsigned long value, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] void setFloat32(in unsigned long byteOffset, in float value, in [Optional] boolean littleEndian)
            raises (DOMException);
        [StrictTypeChecking] void setFloat64(in unsigned long byteOffset, in double value, in [Optional] boolean littleEndian)
            raises (DOMException);
    };

}
