/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"

#if ENABLE(DATABASE)

#include "JSSQLResultSetRowList.h"

#include "SQLResultSetRowList.h"
#include <runtime/Error.h>
#include <runtime/JSNumberCell.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSSQLResultSetRowList);

/* Hash table */

static const HashTableValue JSSQLResultSetRowListTableValues[2] =
{
    { "length", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsSQLResultSetRowListLength), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSQLResultSetRowListTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSSQLResultSetRowListTableValues, 0 };
#else
    { 2, 1, JSSQLResultSetRowListTableValues, 0 };
#endif

/* Hash table for prototype */

static const HashTableValue JSSQLResultSetRowListPrototypeTableValues[2] =
{
    { "item", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsSQLResultSetRowListPrototypeFunctionItem), (intptr_t)1 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSSQLResultSetRowListPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 0, JSSQLResultSetRowListPrototypeTableValues, 0 };
#else
    { 2, 1, JSSQLResultSetRowListPrototypeTableValues, 0 };
#endif

const ClassInfo JSSQLResultSetRowListPrototype::s_info = { "SQLResultSetRowListPrototype", 0, &JSSQLResultSetRowListPrototypeTable, 0 };

JSObject* JSSQLResultSetRowListPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSSQLResultSetRowList>(exec, globalObject);
}

bool JSSQLResultSetRowListPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSSQLResultSetRowListPrototypeTable, this, propertyName, slot);
}

bool JSSQLResultSetRowListPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSSQLResultSetRowListPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSSQLResultSetRowList::s_info = { "SQLResultSetRowList", 0, &JSSQLResultSetRowListTable, 0 };

JSSQLResultSetRowList::JSSQLResultSetRowList(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<SQLResultSetRowList> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSSQLResultSetRowList::~JSSQLResultSetRowList()
{
    forgetDOMObject(this, impl());
}

JSObject* JSSQLResultSetRowList::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSSQLResultSetRowListPrototype(JSSQLResultSetRowListPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSSQLResultSetRowList::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSSQLResultSetRowList, Base>(exec, &JSSQLResultSetRowListTable, this, propertyName, slot);
}

bool JSSQLResultSetRowList::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSSQLResultSetRowList, Base>(exec, &JSSQLResultSetRowListTable, this, propertyName, descriptor);
}

JSValue jsSQLResultSetRowListLength(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSSQLResultSetRowList* castedThis = static_cast<JSSQLResultSetRowList*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    SQLResultSetRowList* imp = static_cast<SQLResultSetRowList*>(castedThis->impl());
    JSValue result = jsNumber(exec, imp->length());
    return result;
}

JSValue JSC_HOST_CALL jsSQLResultSetRowListPrototypeFunctionItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSQLResultSetRowList::s_info))
        return throwError(exec, TypeError);
    JSSQLResultSetRowList* castedThisObj = static_cast<JSSQLResultSetRowList*>(asObject(thisValue));
    return castedThisObj->item(exec, args);
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, SQLResultSetRowList* object)
{
    return getDOMObjectWrapper<JSSQLResultSetRowList>(exec, globalObject, object);
}
SQLResultSetRowList* toSQLResultSetRowList(JSC::JSValue value)
{
    return value.inherits(&JSSQLResultSetRowList::s_info) ? static_cast<JSSQLResultSetRowList*>(asObject(value))->impl() : 0;
}

}

#endif // ENABLE(DATABASE)
