All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.wimpi.modbus.util.BitVector Maven / Gradle / Ivy

Go to download

jamod is an object oriented implementation of the Modbus protocol, realized 100% in Java. It allows to quickly realize master and slave applications in various transport flavors (IP and serial).

The newest version!
/***
 * Copyright 2002-2010 jamod development team
 *
 * Licensed 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.
 ***/

package net.wimpi.modbus.util;


/**
 * Class that implements a collection for
 * bits, storing them packed into bytes.
 * Per default the access operations will index from
 * the LSB (rightmost) bit.
 *
 * @author Dieter Wimberger
 * @version 1.2 (@date@)
 */
public final class BitVector {

  //instance attributes
  private int m_Size;
  private byte[] m_Data;
  private boolean m_MSBAccess = false;

  /**
   * Constructs a new BitVector instance
   * with a given size.
   * 

* @param size the number of bits the BitVector * should be able to hold. */ public BitVector(int size) { //store bits m_Size = size; //calculate size in bytes if ((size % 8) > 0) { size = (size / 8) + 1; } else { size = (size / 8); } m_Data = new byte[size]; }//constructor /** * Toggles the flag deciding whether the LSB * or the MSB of the byte corresponds to the * first bit (index=0). */ public void toggleAccess() { m_MSBAccess = !m_MSBAccess; }//toggleAccess /** * Toggles the flag deciding whether the LSB * or the MSB of the byte corresponds to the * first bit (index=0). * * @param b true if LSB=0 up to MSB=7, false otherwise. */ public void toggleAccess(boolean b) { m_MSBAccess = b; }//toggleAccess /** * Tests if this BitVector has * the LSB (rightmost) as the first bit * (i.e. at index 0). * * @return true if LSB=0 up to MSB=7, false otherwise. */ public boolean isLSBAccess() { return !m_MSBAccess; }//isLSBAccess /** * Tests if this BitVector has * the MSB (leftmost) as the first bit * (i.e. at index 0). * * @return true if LSB=0 up to MSB=7, false otherwise. */ public boolean isMSBAccess() { return m_MSBAccess; }//isMSBAccess /** * Returns the byte[] which is used to store * the bits of this BitVector. *

* @return the byte[] used to store the bits. */ public final byte[] getBytes() { return m_Data; }//getBytes /** * Sets the byte[] which stores * the bits of this BitVector. *

* @param data a byte[]. */ public final void setBytes(byte[] data) { System.arraycopy(data, 0, m_Data, 0, data.length); }//setBytes /** * Sets the byte[] which stores * the bits of this BitVector. *

* @param data a byte[]. */ public final void setBytes(byte[] data, int size) { System.arraycopy(data, 0, m_Data, 0, data.length); m_Size = size; }//setBytes /** * Returns the state of the bit at the given index of this * BitVector. *

* @param index the index of the bit to be returned. * * @return true if the bit at the specified index is set, * false otherwise. * * @throws IndexOutOfBoundsException if the index is out of bounds. */ public final boolean getBit(int index) throws IndexOutOfBoundsException { index = translateIndex(index); //System.out.println("Get bit #" + index); return ( (m_Data[byteIndex(index)] & (0x01 << bitIndex(index))) != 0 ) ? true : false; }//getBit /** * Sets the state of the bit at the given index of * this BitVector. *

* @param index the index of the bit to be set. * @param b true if the bit should be set, false if it should be reset. * * @throws IndexOutOfBoundsException if the index is out of bounds. */ public final void setBit(int index, boolean b) throws IndexOutOfBoundsException { index = translateIndex(index); //System.out.println("Set bit #"+index); int value = ((b) ? 1 : 0); int byteNum = byteIndex(index); int bitNum = bitIndex(index); m_Data[byteNum] = (byte) ( (m_Data[byteNum] & ~(0x01 << bitNum)) | ((value & 0x01) << bitNum) ); }//setBit /** * Returns the number of bits in this BitVector * as int. *

* @return the number of bits in this BitVector. */ public final int size() { return m_Size; }//size /** * Forces the number of bits in this BitVector. * * @param size * @throws IllegalArgumentException if the size exceeds * the byte[] store size multiplied by 8. */ public final void forceSize(int size) { if(size > m_Data.length * 8) { throw new IllegalArgumentException("Size exceeds byte[] store."); } else { m_Size = size; } }//forceSize /** * Returns the number of bytes used to store the * collection of bits as int. *

* @return the number of bits in this BitVector. */ public final int byteSize() { return m_Data.length; }//byteSize /** * Returns a String representing the * contents of the bit collection in a way that * can be printed to a screen or log. *

* Note that this representation will ALLWAYS * show the MSB to the left and the LSB to the right * in each byte. * * @return a String representing this BitVector. */ public String toString() { StringBuffer sbuf = new StringBuffer(); for (int i = 0; i < size(); i++) { sbuf.append( ((((m_Data[byteIndex(i)] & (0x01 << bitIndex(i))) != 0 ) ? true : false) ? '1' : '0') ); if (((i + 1) % 8) == 0) { sbuf.append(" "); } } return sbuf.toString(); }//toString /** * Returns the index of the byte in the the byte array * that contains the given bit. *

* @param index the index of the bit. * * @return the index of the byte where the given bit is stored. * * @throws IndexOutOfBoundsException if index is * out of bounds. */ private final int byteIndex(int index) throws IndexOutOfBoundsException { if (index < 0 || index >= m_Data.length * 8) { throw new IndexOutOfBoundsException(); } else { return index / 8; } }//byteIndex /** * Returns the index of the given bit in the byte * where it it stored. *

* @param index the index of the bit. * * @return the bit index relative to the position in the byte * that stores the specified bit. * * @throws IndexOutOfBoundsException if index is * out of bounds. */ private final int bitIndex(int index) throws IndexOutOfBoundsException { if (index < 0 || index >= m_Data.length * 8) { throw new IndexOutOfBoundsException(); } else { return index % 8; } }//bitIndex private final int translateIndex(int idx) { if (m_MSBAccess) { int mod4 = idx % 4; int div4 = idx / 4; if ((div4 % 2) != 0) { //odd return (idx + ODD_OFFSETS[mod4]); } else { //straight return (idx + STRAIGHT_OFFSETS[mod4]); } } else { return idx; } }//translateIndex /** * Factory method for creating a BitVector instance * wrapping the given byte data. * * @param data a byte[] containing packed bits. * @return the newly created BitVector instance. */ public static BitVector createBitVector(byte[] data, int size) { BitVector bv = new BitVector(data.length * 8); bv.setBytes(data); bv.m_Size = size; return bv; }//createBitVector /** * Factory method for creating a BitVector instance * wrapping the given byte data. * * @param data a byte[] containing packed bits. * @return the newly created BitVector instance. */ public static BitVector createBitVector(byte[] data) { BitVector bv = new BitVector(data.length * 8); bv.setBytes(data); return bv; }//createBitVector public static void main(String[] args) { BitVector test = new BitVector(24); System.out.println(test.isLSBAccess()); test.setBit(7, true); System.out.println(test.getBit(7)); test.toggleAccess(true); System.out.println(test.getBit(7)); test.toggleAccess(true); test.setBit(6, true); test.setBit(3, true); test.setBit(2, true); test.setBit(0, true); test.setBit(8,true); test.setBit(10,true); System.out.println(test); test.toggleAccess(true); System.out.println(test); test.toggleAccess(true); System.out.println(test); System.out.println(ModbusUtil.toHex(test.getBytes())); } private static final int[] ODD_OFFSETS = {-1, -3, -5, -7}; private static final int[] STRAIGHT_OFFSETS = {7, 5, 3, 1}; }//class BitVector





© 2015 - 2024 Weber Informatics LLC | Privacy Policy