Package org.apache.xindice.core.data

Source Code of org.apache.xindice.core.data.Value

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id: Value.java 527706 2007-04-11 22:18:07Z vgritsenko $
*/

package org.apache.xindice.core.data;

import org.apache.xindice.util.XindiceRuntimeException;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

/**
* Value is the primary base class for all data storing objects.
* The content window of Value objects are immutable, but the
* underlying byte array is not.
*
* @version $Revision: 527706 $, $Date: 2007-04-11 18:18:07 -0400 (Wed, 11 Apr 2007) $
*/
public class Value implements Comparable {

    protected byte[] data;
    protected int pos;
    protected int len;
    private int hash;

    public Value(Value value) {
        this.data = value.data;
        this.pos = value.pos;
        this.len = value.len;
    }

    public Value(byte[] data) {
        this.data = data;
        this.pos = 0;
        this.len = data.length;
    }

    public Value(byte[] data, int pos, int len) {
        if (pos >= data.length || pos < 0 || pos + len > data.length) {
            throw new ArrayIndexOutOfBoundsException("Value cannot be created");
        }
        this.data = data;
        this.pos = pos;
        this.len = len;
    }

    public Value(String data) {
        try {
            this.data = data.getBytes("utf-8");
            this.pos = 0;
            this.len = this.data.length;
        } catch (UnsupportedEncodingException e) {
            throw new XindiceRuntimeException("Java doesn't support UTF-8 encoding", e);
        }
    }

    /**
     * getLength retrieves the length of the data being stored by the Value.
     *
     * @return The Value length
     */
    public final int getLength() {
        return len;
    }

    /**
     * getData retrieves the data being stored by the Value as a byte array.
     *
     * @return The Data
     */
    public final byte[] getData() {
        if (len != data.length) {
            byte[] b = new byte[len];
            System.arraycopy(data, pos, b, 0, len);
            return b;
        } else {
            return data;
        }
    }

    /**
     * Get a new Value that is part of this Value object.
     *
     * @param start beginning index
     * @param len length of the new Value
     * @return Value object
     * @throws ArrayIndexOutOfBoundsException if start index is either negative
     *         or isn't less then length of original Value
     */
    public final Value getSubvalue(int start, int len) {
        return new Value(data, start, len);
    }

    /**
     * Returns the byte at the specified index.
     *
     * @param index byte index
     * @return the byte at the specified index.
     * @throws ArrayIndexOutOfBoundsException if index is negative number or
     *         is not less that the length of Value data
     */
    public final byte byteAt(int index) {
        if (index < 0 || index >= len) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        return data[pos + index];
    }

    public final boolean startsWith(Value value) {
        if (len < value.len) {
            return false;
        }

        byte[] ddata = value.data;
        int dpos = value.pos;

        for (int i = 0; i < value.len; i++) {
            if (data[i + pos] != ddata[i + dpos]) {
                return false;
            }
        }

        return true;
    }

    /**
     * Return an InputStream for the value.
     *
     * @return An InputStream
     */
    public final InputStream getInputStream() {
        return new ByteArrayInputStream(data, pos, len);
    }

    /**
     * Stream the content of the value into an OutputStream.
     *
     * @param out the OutputStream
     */
    public final void streamTo(OutputStream out) throws IOException {
        out.write(data, pos, len);
    }

    /**
     * Copy contents of the value into supplied byte array.
     *
     * @param tdata byte array for the value
     * @param tpos starting position
     */
    public final void copyTo(byte[] tdata, int tpos) {
        System.arraycopy(data, pos, tdata, tpos, len);
    }

    /**
     * Copy <code>len</code> bytes of value's content into supplied
     * byte array.
     *
     * @param tdata byte array for the value
     * @param tpos starting position
     * @param len count of bytes to copy
     */
    public final void copyTo(byte[] tdata, int tpos, int len) {
        System.arraycopy(data, pos, tdata, tpos, len);
    }

    public final int compareTo(Value value) {
        byte[] ddata = value.data;
        int dpos = value.pos;
        int dlen = value.len;

        int stop = len > dlen ? dlen : len;

        for (int i = 0; i < stop; i++) {
            byte b1 = data[pos + i];
            byte b2 = ddata[dpos + i];

            if (b1 != b2) {
                // get unsigned value
                int s1 = ((int) b1) & 0xFF;
                int s2 = ((int) b2) & 0xFF;
                return s1 > s2 ? (i + 1) : -(i + 1);
            }
        }

        if (len == dlen) {
            return 0;
        } else {
            return len > dlen ? stop + 1 : -(stop + 1);
        }
    }

    public final int compareTo(Object obj) {
        if (obj instanceof Value) {
            return compareTo((Value) obj);
        }
        return compareTo(new Value(obj.toString()));
    }

    public boolean equals(Value value) {
        return len == value.len && compareTo(value) == 0;
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof Value) {
            return equals((Value) obj);
        }
        return obj != null && equals(new Value(obj.toString()));
    }

    public int hashCode() {
        // modeled after String.hashCode()
        if(hash == 0) {
            int tempHash = 0;
            for(int i = 0 ; i < len; i++) {
                tempHash = 31 * tempHash + data[pos + i];
            }
            this.hash = Math.abs(tempHash);
        }
        return hash;
    }

    public final String toString() {
        try {
            return new String(data, pos, len, "utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new XindiceRuntimeException("Java doesn't seem to support UTF-8!", e);
        }
    }
}
TOP

Related Classes of org.apache.xindice.core.data.Value

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.