gecko-dev/directory/java-sdk/ldapjdk/netscape/ldap/ber/stream/BERReal.java

214 строки
7.0 KiB
Java
Исходник Обычный вид История

1998-07-28 04:58:49 +04:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
1999-11-02 04:46:24 +03:00
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (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.mozilla.org/NPL/
1998-07-28 04:58:49 +04:00
*
1999-11-02 04:46:24 +03:00
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
1998-07-28 04:58:49 +04:00
*
1999-11-02 04:46:24 +03:00
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
1998-07-28 04:58:49 +04:00
* Communications Corporation. Portions created by Netscape are
1999-11-02 04:46:24 +03:00
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
1998-07-28 04:58:49 +04:00
*/
package netscape.ldap.ber.stream;
import java.util.*;
import java.io.*;
/**
* This class is for the Real object.
*
* <pre>
* ENCODING RULE:
* tag = 0x09
* </pre>
*
* @version 1.0
* @seeAlso CCITT X.209
*/
public class BERReal extends BERElement {
/**
1998-07-28 04:58:49 +04:00
* Constants: special ASN.1 real values
*/
public final static float PLUS_INFINITY = 1.0f/0.0f;
public final static float MINUS_INFINITY = -1.0f/0.0f;
/**
* Value of element
1998-07-28 04:58:49 +04:00
*/
private float m_value = 0;
/**
* Constructs a real element with a value
1998-07-28 04:58:49 +04:00
* @param value float value
*/
public BERReal(float value) {
m_value = value;
}
/**
* Constructs a real element from an input stream.
* @param stream source
1998-07-28 04:58:49 +04:00
* @param bytes_read array of 1 int; value incremented by
* number of bytes read from stream.
* @exception IOException failed to construct
*/
public BERReal(InputStream stream, int[] bytes_read) throws IOException {
int length = super.readLengthOctets(stream, bytes_read);
if (length == 0)
/* zero length indicates value is zero */
m_value = 0;
else {
int octet = stream.read(); /* first content octet */
bytes_read[0]++;
if (octet == 0x40) /* bit 8 = 1 */
m_value = PLUS_INFINITY;
else if (octet == 0x41) /* bit 8 = 1 and bit 1 = 1 */
m_value = MINUS_INFINITY;
else if ((octet & 0x80) > 0) {
/* bit 8 = 1 */
/* Binary encoding */
/* M = S*N*2F where S = -1 or 1, 0<= F <= 3. */
int sign;
int base;
int number;
int f; /* binary scaling factor */
int exponent;
int mantissa;
int num_exponent_octets;
int contents_length_left;
if ((octet & 0x40) > 0) sign = -1;
else sign = 1;
if ((octet & 0x20) > 0) {
if ((octet & 0x10) > 0) {
/* bits 6+5 = 11 */
/* reserved for future use */
base = 0;
} else {
/* bits 6+5 = 10 */
base = 16;
}
} else if ((octet & 0x10) > 0) {
/* bits 6+5 = 01 */
base = 8;
} else {
/* bits 6+5 = 00 */
base = 2;
}
if ((octet & 0x08) > 0) {
if ((octet & 0x04) > 0) {
/* bits 4+3 = 11 */
f = 3;
} else {
/* bits 4+3 = 10 */
f = 2;
}
} else if ((octet & 0x04) > 0) {
/* bits 4+3 = 01 */
f = 1;
} else {
/* bits 4+3 = 00 */
f = 0;
}
if ((octet & 0x02) > 0) {
if ((octet & 0x01) > 0) {
/* bits 2+1 = 11 */
/* Following octet encodes the number of octets used to
* encode the exponent.
*/
num_exponent_octets = stream.read();
bytes_read[0]++;
exponent = readTwosComplement(stream,bytes_read,num_exponent_octets);
} else {
/* bits 2+1 = 10 */
num_exponent_octets = 3;
exponent = readTwosComplement(stream,bytes_read,num_exponent_octets);
}
} else if ((octet & 0x01) > 0) {
/* bits 2+1 = 01 */
num_exponent_octets = 2;
exponent = readTwosComplement(stream,bytes_read,num_exponent_octets);
} else {
/* bits 2+1 = 00 */
num_exponent_octets = 1;
exponent = readTwosComplement(stream,bytes_read,num_exponent_octets);
}
contents_length_left = length - 1 - num_exponent_octets;
number = readUnsignedBinary(stream, bytes_read, contents_length_left);
1999-09-15 22:32:21 +04:00
mantissa = (int)(sign * number * Math.pow(2, f));
1998-07-28 04:58:49 +04:00
m_value = mantissa * (float)Math.pow((double)base,(double)exponent);
} else {
/* bits 8 + 7 = 00 */
/* ISO 6093 field */
/*** NOTE: It has been agreed that this feature will
* not be provided right now.
*/
throw new IOException("real ISO6093 not supported. ");
}
}
}
/**
* Sends the BER encoding directly to a stream.
1998-07-28 04:58:49 +04:00
* @param stream output stream
* @exception IOException failed to write
1998-07-28 04:58:49 +04:00
*/
public void write(OutputStream stream) throws IOException {
if (m_value == 0) {
stream.write(BERElement.REAL);
stream.write(0x00); /* length */
} else if (m_value == PLUS_INFINITY) {
stream.write(BERElement.REAL);
stream.write(0x01); /* length */
stream.write(0x40); /* contents */
} else if (m_value == MINUS_INFINITY) {
stream.write(BERElement.REAL);
stream.write(0x01); /* length */
stream.write(0x41); /* contents */
} else {
/* Non-special real value */
/* NOTE: currently always sends as a base 2 binary encoding
* (see X.2 09 section 10.5.)
*
* M = S * N * 2F
*
* Simple encoding always uses F = 1.
*/
// bcm - incomplete.
}
}
/**
* Gets the element type.
* @return element type
1998-07-28 04:58:49 +04:00
*/
public int getType() {
return BERElement.REAL;
}
/**
* Gets the string representation.
* @return string representation of tag
*/
public String toString() {
return "Real {" + m_value + "}";
}
}