001/*
002 * Copyright 2013 Alex Kasko (alexkasko.com)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.alexkasko.unsafe.bytearray;
018
019import static java.lang.System.arraycopy;
020
021/**
022 * Implementation of {@link ByteArrayTool} using bits shifting and standard
023 * byte array operations.
024 *
025 * @author alexkasko
026 * Date: 12/11/12
027 */
028class BitShiftLittleEndianByteArrayTool extends ByteArrayTool {
029    /**
030     * {@inheritDoc}
031     */
032    @Override
033    public boolean isUnsafe() {
034        return false;
035    }
036
037    /**
038     * {@inheritDoc}
039     */
040    @Override
041    public byte getByte(byte[] data, int offset) {
042        return data[offset];
043    }
044
045    /**
046     * {@inheritDoc}
047     */
048    @Override
049    public void putByte(byte[] data, int offset, byte value) {
050        data[offset] = value;
051    }
052
053    /**
054     * {@inheritDoc}
055     */
056    @Override
057    public short getUnsignedByte(byte[] data, int offset) {
058        return (short) (data[offset] & 0xff);
059    }
060
061    /**
062     * {@inheritDoc}
063     */
064    @Override
065    public void putUnsignedByte(byte[] data, int offset, short value) {
066        if(value < 0 || value >= 1<<8) throw new IllegalArgumentException(Short.toString(value));
067        data[offset] = (byte) value;
068    }
069
070    /**
071     * {@inheritDoc}
072     */
073    @Override
074    public short getShort(byte[] data, int offset) {
075        return (short) ((data[offset + 0] & 0xff) << 0 |
076                        (data[offset + 1] & 0xff) << 8);
077    }
078
079    /**
080     * {@inheritDoc}
081     */
082    @Override
083    public void putShort(byte[] data, int offset, short value) {
084        data[offset + 0] = (byte) (value >>> 0);
085        data[offset + 1] = (byte) (value >>> 8);
086    }
087
088    /**
089     * {@inheritDoc}
090     */
091    @Override
092    public int getUnsignedShort(byte[] data, int offset) {
093        return ((data[offset + 0] & 0xff) << 0 |
094                (data[offset + 1] & 0xff) << 8) & 0xffff;
095    }
096
097    /**
098     * {@inheritDoc}
099     */
100    @Override
101    public void putUnsignedShort(byte[] data, int offset, int value) {
102        if(value < 0 || value >= 1<<16) throw new IllegalArgumentException(Integer.toString(value));
103        data[offset + 0] = (byte) (value >>> 0);
104        data[offset + 1] = (byte) (value >>> 8);
105    }
106
107    /**
108     * {@inheritDoc}
109     */
110    @Override
111    public int getInt(byte[] data, int offset) {
112        return (data[offset + 0] & 0xff) << 0 |
113               (data[offset + 1] & 0xff) << 8 |
114               (data[offset + 2] & 0xff) << 16 |
115               (data[offset + 3] & 0xff) << 24;
116    }
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public void putInt(byte[] data, int offset, int value) {
123        data[offset + 0] = (byte) (value >>> 0);
124        data[offset + 1] = (byte) (value >>> 8);
125        data[offset + 2] = (byte) (value >>> 16);
126        data[offset + 3] = (byte) (value >>> 24);
127    }
128
129    /**
130     * {@inheritDoc}
131     */
132    @Override
133    public long getUnsignedInt(byte[] data, int offset) {
134        return ((data[offset + 0] & 0xff) << 0 |
135                (data[offset + 1] & 0xff) << 8 |
136                (data[offset + 2] & 0xff) << 16 |
137                (data[offset + 3] & 0xff) << 24) & 0xffffffffL;
138    }
139
140    /**
141     * {@inheritDoc}
142     */
143    @Override
144    public void putUnsignedInt(byte[] data, int offset, long value) {
145        if(value < 0 || value >= 1L<<32) throw new IllegalArgumentException(Long.toString(value));
146        data[offset + 0] = (byte) (value >>> 0);
147        data[offset + 1] = (byte) (value >>> 8);
148        data[offset + 2] = (byte) (value >>> 16);
149        data[offset + 3] = (byte) (value >>> 24);
150    }
151
152    /**
153     * {@inheritDoc}
154     */
155    @Override
156    public long getLong(byte[] data, int offset) {
157        return (data[offset + 0] & 0xffL) << 0 |
158               (data[offset + 1] & 0xffL) << 8 |
159               (data[offset + 2] & 0xffL) << 16 |
160               (data[offset + 3] & 0xffL) << 24 |
161               (data[offset + 4] & 0xffL) << 32 |
162               (data[offset + 5] & 0xffL) << 40 |
163               (data[offset + 6] & 0xffL) << 48 |
164               (data[offset + 7] & 0xffL) << 56;
165    }
166
167    /**
168     * {@inheritDoc}
169     */
170    @Override
171    public void putLong(byte[] data, int offset, long value) {
172        data[offset + 0] = (byte) (value >>> 0);
173        data[offset + 1] = (byte) (value >>> 8);
174        data[offset + 2] = (byte) (value >>> 16);
175        data[offset + 3] = (byte) (value >>> 24);
176        data[offset + 4] = (byte) (value >>> 32);
177        data[offset + 5] = (byte) (value >>> 40);
178        data[offset + 6] = (byte) (value >>> 48);
179        data[offset + 7] = (byte) (value >>> 56);
180    }
181
182    /**
183     * {@inheritDoc}
184     */
185    @Override
186    public void copy(byte[] input, int inputIndex, byte[] output, int outputIndex, int length) {
187        arraycopy(input, inputIndex, output, outputIndex, length);
188    }
189}