1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @author Alexey V. Varlamov, Stepan M. Mishura 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @version $Revision$ 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/ 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.security.asn1; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Represents ASN.1 bit string value 27f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see <a href="http://asn1.elibel.tm.fr/en/standards/index.htm">ASN.1</a> 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class BitString { 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final byte[] SET_MASK = { (byte) 128, 64, 32, 16, 8, 4, 2, 1 }; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final byte[] RESET_MASK = { 0x7f, (byte) 0xbf, (byte) 0xdf, 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (byte) 0xef, (byte) 0xf7, (byte) 0xfb, (byte) 0xfd, (byte) 0xfe, }; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 375c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** Sequence of bits padded with unused bits. */ 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final byte[] bytes; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 405c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson /** Number of unused bits in the last byte. */ 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int unusedBits; 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 445c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson * @param bytes array of bytes that represents bit string, 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * including unused bits 465c27fb80ffd335aa45dc8829ba3ecbc18c01e4e8Jesse Wilson * @param unusedBits number of unused bits 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException - if parameters are invalid 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public BitString(byte[] bytes, int unusedBits) { 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // constraints are set according X.690 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (unusedBits < 0 || unusedBits > 7) { 52897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException("Number of unused bits MUST be in range 0-7"); 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bytes.length == 0 && unusedBits != 0) { 56897538a36c18f4db8f9f68ee566aec0bda842e9fElliott Hughes throw new IllegalArgumentException("For empty bit string unused bits MUST be 0"); 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.bytes = bytes; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.unusedBits = unusedBits; 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public BitString(boolean[] values) { 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unusedBits = values.length % 8; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int size = values.length / 8; 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (unusedBits != 0) { 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project size++; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytes = new byte[size]; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < values.length; i++) { 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project setBit(i, values[i]); 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getBit(int bit) { 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int offset = bit % 8; 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = bit / 8; 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (bytes[index] & SET_MASK[offset]) != 0; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setBit(int bit, boolean value) { 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int offset = bit % 8; 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = bit / 8; 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value) { 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytes[index] |= SET_MASK[offset]; 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project bytes[index] &= RESET_MASK[offset]; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean[] toBooleanArray() { 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean[] result = new boolean[bytes.length * 8 - unusedBits]; 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < result.length; i++) { 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result[i] = getBit(i); 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 99