/**
 * END USER LICENSE AGREEMENT (“EULA”)
 *
 * READ THIS AGREEMENT CAREFULLY (date: 9/13/2011):
 * http://www.akiban.com/licensing/20110913
 *
 * BY INSTALLING OR USING ALL OR ANY PORTION OF THE SOFTWARE, YOU ARE ACCEPTING
 * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU AGREE THAT THIS
 * AGREEMENT IS ENFORCEABLE LIKE ANY WRITTEN AGREEMENT SIGNED BY YOU.
 *
 * IF YOU HAVE PAID A LICENSE FEE FOR USE OF THE SOFTWARE AND DO NOT AGREE TO
 * THESE TERMS, YOU MAY RETURN THE SOFTWARE FOR A FULL REFUND PROVIDED YOU (A) DO
 * NOT USE THE SOFTWARE AND (B) RETURN THE SOFTWARE WITHIN THIRTY (30) DAYS OF
 * YOUR INITIAL PURCHASE.
 *
 * IF YOU WISH TO USE THE SOFTWARE AS AN EMPLOYEE, CONTRACTOR, OR AGENT OF A
 * CORPORATION, PARTNERSHIP OR SIMILAR ENTITY, THEN YOU MUST BE AUTHORIZED TO SIGN
 * FOR AND BIND THE ENTITY IN ORDER TO ACCEPT THE TERMS OF THIS AGREEMENT. THE
 * LICENSES GRANTED UNDER THIS AGREEMENT ARE EXPRESSLY CONDITIONED UPON ACCEPTANCE
 * BY SUCH AUTHORIZED PERSONNEL.
 *
 * IF YOU HAVE ENTERED INTO A SEPARATE WRITTEN LICENSE AGREEMENT WITH AKIBAN FOR
 * USE OF THE SOFTWARE, THE TERMS AND CONDITIONS OF SUCH OTHER AGREEMENT SHALL
 * PREVAIL OVER ANY CONFLICTING TERMS OR CONDITIONS IN THIS AGREEMENT.
 */

package com.akiban.server.rowdata;

import com.akiban.server.AkServerUtil;
import com.akiban.server.Quote;
import com.akiban.server.encoding.EncodingException;
import com.akiban.server.types.*;
import com.akiban.server.types3.pvalue.PUnderlying;
import com.akiban.server.types3.pvalue.PValueSource;
import com.akiban.util.AkibanAppender;
import com.akiban.util.WrappingByteSource;

import java.nio.ByteBuffer;

abstract class AbstractRowDataPValueSource implements PValueSource {

    // ValueSource interface

    @Override
    public PUnderlying getUnderlyingType() {
        return fieldDef().getType().pUnderlying();
    }

    @Override
    public boolean hasAnyValue() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean hasRawValue() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean hasCacheValue() {
        throw new UnsupportedOperationException();
    }


    @Override
    public abstract boolean isNull();

    @Override
    public boolean getBoolean() {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean getBoolean(boolean defaultValue) {
        throw new UnsupportedOperationException();
    }

    @Override
    public byte getInt8() {
        throw new UnsupportedOperationException();
    }

    @Override
    public short getInt16() {
        throw new UnsupportedOperationException();
    }

    @Override
    public char getUInt16() {
        throw new UnsupportedOperationException();
    }

    @Override
    public int getInt32() {
        return (int) extractLong(Signage.SIGNED);
    }

    @Override
    public long getInt64() {
        return extractLong(Signage.SIGNED);
    }

    @Override
    public float getFloat() {
        return doGetFloat();
    }

    @Override
    public double getDouble() {
        return doGetDouble();
    }

    @Override
    public byte[] getBytes() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Object getObject() {
        throw new UnsupportedOperationException();
    }


    // for subclasses
    protected abstract long getRawOffsetAndWidth();
    protected abstract byte[] bytes();
    protected abstract FieldDef fieldDef();

    // for use within this class
    private double doGetDouble() {
        long asLong = extractLong(Signage.SIGNED);
        return Double.longBitsToDouble(asLong);
    }

    private float doGetFloat() {
        long asLong = extractLong(Signage.SIGNED);
        int asInt = (int) asLong;
        return Float.intBitsToFloat(asInt);
    }

    private String doGetString() {
        final long location = getRawOffsetAndWidth();
        return location == 0
                ? null
                : AkServerUtil.decodeMySQLString(bytes(), (int) location, (int) (location >>> 32), fieldDef());
    }

    private long extractLong(Signage signage) {
        long offsetAndWidth = getCheckedOffsetAndWidth();
        final int offset = (int)offsetAndWidth;
        final int width = (int)(offsetAndWidth >>> 32);
        if (signage == Signage.SIGNED) {
            return AkServerUtil.getSignedIntegerByWidth(bytes(), offset, width);
        } else {
            assert signage == Signage.UNSIGNED;
            return AkServerUtil.getUnsignedIntegerByWidth(bytes(), offset, width);
        }
    }

    private long getCheckedOffsetAndWidth() {
        long offsetAndWidth = getRawOffsetAndWidth();
        if (offsetAndWidth == 0) {
            throw new ValueSourceIsNullException();
        }
        return offsetAndWidth;
    }

    // object state
    private final WrappingByteSource byteSource = new WrappingByteSource();

    private enum Signage {
        SIGNED, UNSIGNED
    }
}

@@ -1306,93 +1306,8 @@
 il;%0A
-import com.akiban.server.Quote;%0Aimport com.akiban.server.encoding.EncodingException;%0A
 impo
@@ -1336,16 +1336,16 @@
 ypes.*;%0A
+
 import c
@@ -1445,47 +1445,8 @@
 ce;%0A
-import com.akiban.util.AkibanAppender;%0A
 impo
@@ -1489,36 +1489,8 @@
 e;%0A%0A
-import java.nio.ByteBuffer;%0A
 %0Aabs
@@ -2140,49 +2140,47 @@
     
-throw new UnsupportedOperationException()
+return extractLong(Signage.SIGNED) != 0
 ;%0A  
@@ -2264,46 +2264,50 @@
     
-throw new UnsupportedOperationExceptio
+return isNull() ? defaultValue : getBoolea
 n();

update getBoolean to return appropriate values