001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Alexey V. Varlamov, Stepan M. Mishura
020: * @version $Revision$
021: */package org.apache.harmony.security.asn1;
022:
023: import org.apache.harmony.security.internal.nls.Messages;
024:
025: /**
026: * Represents ASN.1 bit string value
027: *
028: * @see http://asn1.elibel.tm.fr/en/standards/index.htm
029: */
030:
031: public final class BitString {
032:
033: private static final byte[] SET_MASK = { (byte) 128, 64, 32, 16, 8,
034: 4, 2, 1 };
035:
036: private static final byte[] RESET_MASK = { 0x7f, (byte) 0xbf,
037: (byte) 0xdf, (byte) 0xef, (byte) 0xf7, (byte) 0xfb,
038: (byte) 0xfd, (byte) 0xfe, };
039:
040: /**
041: * Sequence of bits padded with unused bits.
042: * @see #unusedBits
043: */
044: public final byte[] bytes;
045:
046: /**
047: * Number of unused bits in the last byte.
048: */
049: public final int unusedBits;
050:
051: /**
052: * Constructs bit string
053: *
054: * @param bytes - array of bytes that represents bit string,
055: * including unused bits
056: * @param unusedBits - number of unused bits
057: * @throws IllegalArgumentException - if parameters are invalid
058: */
059: public BitString(byte[] bytes, int unusedBits) {
060:
061: // constraints are set according X.690
062: if (unusedBits < 0 || unusedBits > 7) {
063: throw new IllegalArgumentException(Messages
064: .getString("security.13D")); //$NON-NLS-1$
065: }
066:
067: if (bytes.length == 0 && unusedBits != 0) {
068: throw new IllegalArgumentException(Messages
069: .getString("security.13E")); //$NON-NLS-1$
070: }
071:
072: this .bytes = bytes;
073: this .unusedBits = unusedBits;
074: }
075:
076: /**
077: * Constructs bit string from array of booleans
078: *
079: * @param values - array of booleans
080: */
081: public BitString(boolean[] values) {
082: unusedBits = values.length % 8;
083: int size = values.length / 8;
084: if (unusedBits != 0) {
085: size++;
086: }
087: bytes = new byte[size];
088: for (int i = 0; i < values.length; i++) {
089: setBit(i, values[i]);
090: }
091: }
092:
093: public boolean getBit(int bit) {
094: int offset = bit % 8;
095: int index = bit / 8;
096: return (bytes[index] & SET_MASK[offset]) != 0;
097: }
098:
099: public void setBit(int bit, boolean value) {
100: int offset = bit % 8;
101: int index = bit / 8;
102: if (value) {
103: bytes[index] |= SET_MASK[offset];
104: } else {
105: bytes[index] &= RESET_MASK[offset];
106: }
107: }
108:
109: public boolean[] toBooleanArray() {
110: boolean[] result = new boolean[bytes.length * 8 - unusedBits];
111: for (int i = 0; i < result.length; i++) {
112: result[i] = getBit(i);
113: }
114: return result;
115: }
116: }
|