1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 * 19 */ 20 package org.apache.directory.api.asn1.ber.tlv; 21 22 23 import org.apache.directory.api.i18n.I18n; 24 25 26 /** 27 * Parse and decode a Long value. 28 * 29 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 30 */ 31 public final class LongDecoder 32 { 33 /** A mask used to get only the necessary bytes */ 34 private static final long[] MASK = new long[] 35 { 0x00000000000000FFL, 0x000000000000FFFFL, 0x0000000000FFFFFFL, 0x00000000FFFFFFFFL, 0x000000FFFFFFFFFFL, 36 0x0000FFFFFFFFFFFFL, 0x00FFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL }; 37 38 39 private LongDecoder() 40 { 41 } 42 43 44 /** 45 * Parse a byte buffer and send back an long, controlling that this number 46 * is in a specified interval. 47 * 48 * @param value The byte buffer to parse 49 * @param min Lowest value allowed, included 50 * @param max Highest value allowed, included 51 * @return An integer 52 * @throws LongDecoderException Thrown if the byte stream does not contains an integer 53 */ 54 public static long parse( BerValue value, long min, long max ) throws LongDecoderException 55 { 56 long result = parseLong( value ); 57 58 if ( ( result >= min ) && ( result <= max ) ) 59 { 60 return result; 61 } 62 else 63 { 64 throw new LongDecoderException( I18n.err( I18n.ERR_00038_VALUE_NOT_IN_RANGE, min, max ) ); 65 } 66 } 67 68 69 /** 70 * Parse a byte buffer and send back an integer 71 * 72 * @param value The byte buffer to parse 73 * @return An integer 74 * @throws LongDecoderException Thrown if the byte stream does not contains an integer 75 */ 76 public static long parse( BerValue value ) throws LongDecoderException 77 { 78 return parseLong( value ); 79 } 80 81 82 /** 83 * Helper method used to parse the long. We don't check any minimal or maximal 84 * bound. 85 * 86 * @param value The value to parse to a long 87 * @return The decoded long 88 * @throws LongDecoderException If we failed to decode a long 89 */ 90 public static long parseLong( BerValue value ) throws LongDecoderException 91 { 92 long result = 0; 93 94 byte[] bytes = value.getData(); 95 96 if ( ( bytes == null ) || ( bytes.length == 0 ) ) 97 { 98 throw new LongDecoderException( I18n.err( I18n.ERR_00039_0_BYTES_LONG_LONG ) ); 99 } 100 101 if ( bytes.length > 8 ) 102 { 103 throw new LongDecoderException( I18n.err( I18n.ERR_00039_0_BYTES_LONG_LONG ) ); 104 } 105 106 for ( int i = 0; ( i < bytes.length ) && ( i < 9 ); i++ ) 107 { 108 result = ( result << 8 ) | ( bytes[i] & 0x00FF ); 109 } 110 111 if ( ( bytes[0] & 0x80 ) == 0x80 ) 112 { 113 result = -( ( ( ~result ) + 1 ) & MASK[bytes.length - 1] ); 114 } 115 116 return result; 117 } 118 }