View Javadoc
1   // NAME
2   //      $RCSfile: BitsHelper.java,v $
3   // DESCRIPTION
4   //      [given below in javadoc format]
5   // DELTA
6   //      $Revision: 3.1 $
7   // CREATED
8   //      $Date: 2006/03/23 15:09:48 $
9   // COPYRIGHT
10  //      Westhawk Ltd
11  // TO DO
12  //
13  
14  /*
15   * Copyright (C) 2006 by Westhawk Ltd
16   * <a href="www.westhawk.co.uk">www.westhawk.co.uk</a>
17   *
18   * Permission to use, copy, modify, and distribute this software
19   * for any purpose and without fee is hereby granted, provided
20   * that the above copyright notices appear in all copies and that
21   * both the copyright notice and this permission notice appear in
22   * supporting documentation.
23   * This software is provided "as is" without express or implied
24   * warranty.
25   * author <a href="mailto:snmp@westhawk.co.uk">Tim Panton</a>
26   */
27  
28  package uk.co.westhawk.snmp.stack;
29  
30  /*-
31   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
32   * SNMP Java Client
33   * ჻჻჻჻჻჻
34   * Copyright 2023 MetricsHub, Westhawk
35   * ჻჻჻჻჻჻
36   * This program is free software: you can redistribute it and/or modify
37   * it under the terms of the GNU Lesser General Public License as
38   * published by the Free Software Foundation, either version 3 of the
39   * License, or (at your option) any later version.
40   *
41   * This program is distributed in the hope that it will be useful,
42   * but WITHOUT ANY WARRANTY; without even the implied warranty of
43   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
44   * GNU General Lesser Public License for more details.
45   *
46   * You should have received a copy of the GNU General Lesser Public
47   * License along with this program.  If not, see
48   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
49   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
50   */
51  
52  import java.io.*;
53  
54  /**
55   * This class help with the BITS construct. The AsnOctets class is
56   * growing too big, because of all the different representations.
57   *
58   * Note that BITS is different from the ANS.1 BIT STRING. Apparently BIT
59   * STRING was in v1, but was depreceated in favour of BITS.
60   *
61   * <pre>
62   * An instance with bits 0, 3 and 10 set will have the value:
63   *
64   *      10010000 00100000
65   *      ^  ^       ^
66   * bit  0  3      10
67   *
68   * so will consist of the two bytes (octets) 0x90 &amp; 0x20.
69   * </pre>
70   *
71   * See also
72   * section 7.1.4. of
73   * <a href="http://www.ietf.org/rfc/rfc2578.txt">SNMPv2-SMI</a>
74   * and section 8. (3) of
75   * <a href="http://www.ietf.org/rfc/rfc3417.txt">SNMPv2-TM</a>.
76   *
77   * @author <a href="mailto:snmp@westhawk.co.uk">Birgit Arkesteijn</a>
78   * @version $Revision: 3.1 $ $Date: 2006/03/23 15:09:48 $
79   * @since 5_0
80   */
81  public class BitsHelper {
82      private static final String version_id = "@(#)$Id: BitsHelper.java,v 3.1 2006/03/23 15:09:48 birgit Exp $ Copyright Westhawk Ltd";
83  
84      /**
85       * Sets or unsets the flag (bit) on the specified index. The bit
86       * will be set to zero if toset is false, set to one if toset is
87       * true.
88       *
89       * Note, as a side effect the size of the asn octet might grow.
90       *
91       * @param oct   The AsnOctets that represents the BITS
92       * @param index The index (0 - X)
93       * @param toset Whether to set (true) or unset (false) the bit
94       */
95      public static void setFlagged(AsnOctets oct, int index, boolean toset)
96              throws IllegalArgumentException {
97          if (index < 0) {
98              throw new IllegalArgumentException("Illegal value index (" + index
99                      + "). Shoud be greater than 0.");
100         } else {
101             byte mask;
102             int byteNo = index / 8;
103             int bitNo = index % 8;
104 
105             // See if we've got enough bytes in our array.
106             // Reallocate if necessary.
107             int len = oct.value.length;
108             if (byteNo >= len) {
109                 int newLen = byteNo + 1;
110                 byte[] newValue = new byte[newLen];
111                 System.arraycopy(oct.value, 0, newValue, 0, len);
112                 oct.value = newValue;
113             }
114 
115             if (toset == true) {
116                 mask = (byte) (0x80 >>> bitNo);
117                 oct.value[byteNo] = (byte) (oct.value[byteNo] | mask);
118             } else {
119                 mask = (byte) (0x7F >>> bitNo);
120                 oct.value[byteNo] = (byte) (oct.value[byteNo] & mask);
121             }
122         }
123     }
124 
125     /**
126      * Returns if the flag (bit) on the specified index is set. The bit
127      * will be set to zero if toset is false, set to one if toset is
128      * true.
129      *
130      * @param oct   The AsnOctets that represents the BITS
131      * @param index The index (0 - X)
132      * @return Whether the bit is set (true) or unset (false)
133      */
134     public static boolean isFlagged(AsnOctets oct, int index)
135             throws IllegalArgumentException {
136         boolean isFlagged = false;
137         if (index < 0) {
138             throw new IllegalArgumentException("Illegal value index (" + index
139                     + "). Shoud be greater than 0.");
140         } else {
141             byte mask;
142             int byteNo = index / 8;
143             int bitNo = index % 8;
144 
145             int len = oct.value.length;
146             if (byteNo < len) {
147                 // Shift the bit we're interested in to the far left.
148                 // If the bit is one, the byte will be negative.
149                 byte res = (byte) (oct.value[byteNo] << bitNo);
150                 isFlagged = (res < 0);
151             }
152         }
153         return isFlagged;
154     }
155 
156 }