diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java | |
download | cbb-gcc-4.6.4-upstream.tar.bz2 cbb-gcc-4.6.4-upstream.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java')
-rw-r--r-- | libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java b/libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java new file mode 100644 index 000000000..1dc7f9282 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java @@ -0,0 +1,358 @@ +/* CdrEncapsCodecImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.CDR.AbstractCdrOutput; + +import org.omg.CORBA.Any; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.UserException; +import org.omg.IOP.Codec; +import org.omg.IOP.CodecPackage.FormatMismatch; +import org.omg.IOP.CodecPackage.InvalidTypeForEncoding; +import org.omg.IOP.CodecPackage.TypeMismatch; + +/** + * The local {@link Codec} implementation for ENCODING_CDR_ENCAPS + * encoding. This is a local implementation; the remote side should + * have its own Codec of this kind. + * + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class CdrEncapsCodecImpl + extends LocalObject + implements Codec +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * If set to true, no wide string or wide character is allowed (GIOP 1.0). + */ + private final boolean noWide; + + /** + * The version of this encoding. + */ + private final Version version; + + /** + * The associated ORB. + */ + protected final ORB orb; + + /** + * If true, this Codec writes the record length (as int) in the beginning + * of the record. This indicator is part of the formal OMG standard, but it is + * missing in Sun's implementation. Both Suns's and this Codec detects + * the indicator, if present, but can also decode data where this information + * is missing. If the length indicator is missing, the first four bytes in + * Suns encoding are equal to 0 (Big Endian marker). + */ + private boolean lengthIndicator = true; + + /** + * Create an instance of this Codec, encoding following the given version. + */ + public CdrEncapsCodecImpl(ORB _orb, Version _version) + { + orb = _orb; + version = _version; + noWide = version.until_inclusive(1, 0); + } + + /** + * Return the array of repository ids for this object. + * + * @return { "IDL:gnu/CORBA/cdrEnapsCodec:1.0" }, always. + */ + public String[] _ids() + { + return new String[] { "IDL:gnu/CORBA/cdrEnapsCodec:1.0" }; + } + + /** + * Decode the contents of the byte array into Any. + * The byte array may have the optional four byte length indicator + * in the beginning. If these four bytes are zero, it is assumed, + * that no length indicator is present. + */ + public Any decode(byte[] them) + throws FormatMismatch + { + BufferredCdrInput input = createInput(them); + BufferredCdrInput encapsulation = createEncapsulation(them, input); + + TypeCode type = encapsulation.read_TypeCode(); + + try + { + checkTypePossibility("", type); + } + catch (InvalidTypeForEncoding ex) + { + throw new FormatMismatch(ex.getMessage()); + } + + return readAny(type, encapsulation); + } + + private BufferredCdrInput createEncapsulation(byte[] them, BufferredCdrInput input) + { + BufferredCdrInput encapsulation; + + if ((them [ 0 ] | them [ 1 ] | them [ 2 ] | them [ 3 ]) == 0) + { + // Skip that appears to be the always present Big Endian marker. + encapsulation = input; + input.read_short(); + } + else + encapsulation = input.read_encapsulation(); + return encapsulation; + } + + /** {@inheritDoc} */ + public byte[] encode(Any that) + throws InvalidTypeForEncoding + { + checkTypePossibility("", that.type()); + + BufferedCdrOutput output = createOutput(that); + + // BufferedCdrOutput has internal support for this encoding. + AbstractCdrOutput encapsulation = output.createEncapsulation(); + + try + { + TypeCodeHelper.write(encapsulation, that.type()); + that.write_value(encapsulation); + + encapsulation.close(); + output.close(); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Encapsulation; + m.initCause(ex); + throw m; + } + return output.buffer.toByteArray(); + } + + /** + * Decode the value, stored in the byte array, into Any, assuming, + * that the byte array holds the data structure, defined by the + * given typecode. + * + * The byte array may have the optional four byte length indicator + * in the beginning. If these four bytes are zero, it is assumed, + * that no length indicator is present. + */ + public Any decode_value(byte[] them, TypeCode type) + throws FormatMismatch, TypeMismatch + { + try + { + checkTypePossibility("", type); + } + catch (InvalidTypeForEncoding ex) + { + throw new TypeMismatch(ex.getMessage()); + } + + BufferredCdrInput input = createInput(them); + BufferredCdrInput encapsulation = createEncapsulation(them, input); + return readAny(type, encapsulation); + } + + /** + * Read an Any from the given stream. + * + * @param type a type of the Any to read. + * @param input the encapsulation stream. + */ + private Any readAny(TypeCode type, BufferredCdrInput encapsulation) + throws MARSHAL + { + gnuAny a = new gnuAny(); + a.setOrb(orb); + + // BufferredCdrInput has internal support for this encoding. + a.read_value(encapsulation, type); + return a; + } + + /** {@inheritDoc} */ + public byte[] encode_value(Any that) + throws InvalidTypeForEncoding + { + checkTypePossibility("", that.type()); + + BufferedCdrOutput output = createOutput(that); + + AbstractCdrOutput encapsulation = output.createEncapsulation(); + + try + { + that.write_value(encapsulation); + + encapsulation.close(); + output.close(); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Encapsulation; + m.initCause(ex); + throw m; + } + return output.buffer.toByteArray(); + } + + /** + * Create the CDR output stream for writing the given Any. + * The BufferedCdrOutput has internal support for encapsulation encodings. + * + * @param that the Any that will be written. + * + * @return the stream. + * + * @throws InvalidTypeForEncoding if that Any cannot be written under the + * given version. + */ + private BufferedCdrOutput createOutput(Any that) + throws InvalidTypeForEncoding + { + BufferedCdrOutput output = new BufferedCdrOutput(); + output.setOrb(orb); + output.setVersion(version); + return output; + } + + /** + * Checks if the given type can be encoded. Currently only checks for wide + * strings and wide chars for GIOP 1.0. + * + * @param t a typecode to chek. + * + * @throws InvalidTypeForEncoding if the typecode is not valid for the given + * version. + */ + private void checkTypePossibility(String name, TypeCode t) + throws InvalidTypeForEncoding + { + if (noWide) + { + try + { + int kind = t.kind().value(); + + if (kind == TCKind._tk_wchar || kind == TCKind._tk_wstring) + throw new InvalidTypeForEncoding(name + " wide char in " + + version + ); + else if (kind == TCKind._tk_alias || kind == TCKind._tk_array || + kind == TCKind._tk_sequence + ) + checkTypePossibility("Array member", t.content_type()); + + else if (kind == TCKind._tk_struct || kind == TCKind._tk_union) + { + for (int i = 0; i < t.member_count(); i++) + { + checkTypePossibility(t.member_name(i), t.member_type(i)); + } + } + } + catch (UserException ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + } + + /** + * Create the CDR input stream for reading the given byte array. + * + * @param them a byte array to read. + * + * @return the stream. + */ + private BufferredCdrInput createInput(byte[] them) + { + BufferredCdrInput input = new BufferredCdrInput(them); + input.setOrb(orb); + input.setVersion(version); + return input; + } + + /** + * Check if the Codec writes the length indicator. + */ + public boolean hasLengthIndicator() + { + return lengthIndicator; + } + + /** + * Sets if the Codec must write the record length in the beginning of the + * array. Encodings both with and without that indicator are understood + * both by Suns and this codec, but the OMG specification seems requiring + * it. The default behavior is to use the length indicator. + * + * @param use_lengthIndicator + */ + public void setUseLengthIndicator(boolean use_lengthIndicator) + { + lengthIndicator = use_lengthIndicator; + } +} |