/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (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.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.yoko.orb.CORBA;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.yoko.orb.OCI.GiopVersion;
import org.omg.CORBA.portable.ValueOutputStream;

final public class OutputStream extends org.omg.CORBA_2_3.portable.OutputStream implements ValueOutputStream {
    static final Logger LOGGER = Logger.getLogger(OutputStream.class.getName());

    private org.apache.yoko.orb.OB.ORBInstance orbInstance_; // Java only

    public org.apache.yoko.orb.OCI.Buffer buf_;

    private GiopVersion giopVersion_ = org.apache.yoko.orb.OB.OB_Extras.DEFAULT_GIOP_VERSION;

    private org.apache.yoko.orb.OB.CodeConverters codeConverters_;

    private boolean charWriterRequired_;

    private boolean charConversionRequired_;

    private boolean wCharWriterRequired_;

    private boolean wCharConversionRequired_;

    //
    // Handles all OBV marshalling
    //
    private org.apache.yoko.orb.OB.ValueWriter valueWriter_;

    //
    // If alignNext_ > 0, the next write should be aligned on this
    // boundary
    //
    private int alignNext_;

    private java.lang.Object invocationContext_; // Java only

    private java.lang.Object delegateContext_; // Java only

    // ------------------------------------------------------------------
    // Private and protected functions
    // ------------------------------------------------------------------

    // Write a gap of four bytes (ulong aligned), avoids byte shifts
    private int writeGap() {
        LOGGER.finest("Writing a gap value");
        addCapacity(4, 4);
        int result = buf_.pos_;
        buf_.pos_ += 4;
        return result;
    }

    private void writeLength(int start) {
        int length = buf_.pos_ - (start + 4);
        LOGGER.finest("Writing a length value of " + length + " at offset " + start);

        buf_.data_[start++] = (byte) (length >>> 24);
        buf_.data_[start++] = (byte) (length >>> 16);
        buf_.data_[start++] = (byte) (length >>> 8);
        buf_.data_[start] = (byte) length;
    }

    public void writeTypeCodeImpl(org.omg.CORBA.TypeCode tc,
            java.util.Hashtable history) {
        //
        // Try casting the TypeCode to org.apache.yoko.orb.CORBA.TypeCode. This
        // could
        // fail if the TypeCode was created by a foreign singleton ORB.
        //
        TypeCode obTC = null;
        try {
            obTC = (TypeCode) tc;
        } catch (ClassCastException ex) {
        }

        if (obTC != null) {
            if (obTC.recId_ != null) {
                if (obTC.recType_ == null)
                    throw new org.omg.CORBA.BAD_TYPECODE(
                            org.apache.yoko.orb.OB.MinorCodes
                                    .describeBadTypecode(org.apache.yoko.orb.OB.MinorCodes.MinorIncompleteTypeCode),
                            org.apache.yoko.orb.OB.MinorCodes.MinorIncompleteTypeCode,
                            org.omg.CORBA.CompletionStatus.COMPLETED_NO);
                writeTypeCodeImpl(obTC.recType_, history);
                return;
            }
        }

        LOGGER.finest("Writing a type code of type " + tc.kind().value());

        //
        // For performance reasons, handle the primitive TypeCodes first
        //
        switch (tc.kind().value()) {
        case org.omg.CORBA.TCKind._tk_null:
        case org.omg.CORBA.TCKind._tk_void:
        case org.omg.CORBA.TCKind._tk_short:
        case org.omg.CORBA.TCKind._tk_long:
        case org.omg.CORBA.TCKind._tk_longlong:
        case org.omg.CORBA.TCKind._tk_ushort:
        case org.omg.CORBA.TCKind._tk_ulong:
        case org.omg.CORBA.TCKind._tk_ulonglong:
        case org.omg.CORBA.TCKind._tk_float:
        case org.omg.CORBA.TCKind._tk_double:
        case org.omg.CORBA.TCKind._tk_longdouble:
        case org.omg.CORBA.TCKind._tk_boolean:
        case org.omg.CORBA.TCKind._tk_char:
        case org.omg.CORBA.TCKind._tk_wchar:
        case org.omg.CORBA.TCKind._tk_octet:
        case org.omg.CORBA.TCKind._tk_any:
        case org.omg.CORBA.TCKind._tk_TypeCode:
        case org.omg.CORBA.TCKind._tk_Principal:
            write_ulong(tc.kind().value());
            return;

        default:
            break;
        }

        Integer indirectionPos = (Integer) history.get(tc);
        if (indirectionPos != null) {
            write_long(-1);
            int offs = indirectionPos.intValue() - buf_.pos_;
            LOGGER.finest("Writing an indirect type code for offset " + offs);
            write_long(offs);
        } else {
            write_ulong(tc.kind().value());
            Integer oldPos = new Integer(buf_.pos_ - 4);

            try {
                switch (tc.kind().value()) {
                case org.omg.CORBA.TCKind._tk_fixed: {
                    history.put(tc, oldPos);

                    write_ushort(tc.fixed_digits());
                    write_short(tc.fixed_scale());

                    break;
                }

                case org.omg.CORBA.TCKind._tk_objref: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_struct:
                case org.omg.CORBA.TCKind._tk_except: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    write_ulong(tc.member_count());
                    for (int i = 0; i < tc.member_count(); i++) {
                        write_string(tc.member_name(i));
                        writeTypeCodeImpl(tc.member_type(i), history);
                    }
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_union: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    org.omg.CORBA.TypeCode discType = tc.discriminator_type();
                    writeTypeCodeImpl(discType, history);
                    int defaultIndex = tc.default_index();
                    write_long(defaultIndex);
                    write_ulong(tc.member_count());
                    for (int i = 0; i < tc.member_count(); i++) {
                        //
                        // Check for default label value
                        //
                        if (i == defaultIndex) {
                            //
                            // Marshal a dummy value of the appropriate size
                            // for the discriminator type
                            //
                            org.omg.CORBA.TypeCode origDiscType = TypeCode
                                    ._OB_getOrigType(discType);
                            switch (origDiscType.kind().value()) {
                            case org.omg.CORBA.TCKind._tk_short:
                                write_short((short) 0);
                                break;
                            case org.omg.CORBA.TCKind._tk_ushort:
                                write_ushort((short) 0);
                                break;
                            case org.omg.CORBA.TCKind._tk_long:
                                write_long(0);
                                break;
                            case org.omg.CORBA.TCKind._tk_ulong:
                                write_ulong(0);
                                break;
                            case org.omg.CORBA.TCKind._tk_longlong:
                                write_longlong(0);
                                break;
                            case org.omg.CORBA.TCKind._tk_ulonglong:
                                write_ulonglong(0);
                                break;
                            case org.omg.CORBA.TCKind._tk_boolean:
                                write_boolean(false);
                                break;
                            case org.omg.CORBA.TCKind._tk_char:
                                write_char((char) 0);
                                break;
                            case org.omg.CORBA.TCKind._tk_enum:
                                write_ulong(0);
                                break;
                            default:
                                org.apache.yoko.orb.OB.Assert._OB_assert("Invalid sub-type in tk_union");
                            }
                        } else {
                            tc.member_label(i).write_value(this);
                        }

                        write_string(tc.member_name(i));
                        writeTypeCodeImpl(tc.member_type(i), history);
                    }
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_enum: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    write_ulong(tc.member_count());
                    for (int i = 0; i < tc.member_count(); i++)
                        write_string(tc.member_name(i));
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_string:
                case org.omg.CORBA.TCKind._tk_wstring:
                    write_ulong(tc.length());
                    break;

                case org.omg.CORBA.TCKind._tk_sequence:
                case org.omg.CORBA.TCKind._tk_array: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    writeTypeCodeImpl(tc.content_type(), history);
                    write_ulong(tc.length());
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_alias: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    writeTypeCodeImpl(tc.content_type(), history);
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_value: {
                    history.put(tc, oldPos);

                    org.omg.CORBA.TypeCode concreteBase = tc
                            .concrete_base_type();
                    if (concreteBase == null) {
                        concreteBase = org.apache.yoko.orb.OB.TypeCodeFactory
                                .createPrimitiveTC(org.omg.CORBA.TCKind.tk_null);
                    }

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    write_short(tc.type_modifier());
                    writeTypeCodeImpl(concreteBase, history);
                    write_ulong(tc.member_count());
                    for (int i = 0; i < tc.member_count(); i++) {
                        write_string(tc.member_name(i));
                        writeTypeCodeImpl(tc.member_type(i), history);
                        write_short(tc.member_visibility(i));
                    }
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_value_box: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    writeTypeCodeImpl(tc.content_type(), history);
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_abstract_interface: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA.TCKind._tk_native: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    writeLength(start);

                    break;
                }

                case org.omg.CORBA_2_4.TCKind._tk_local_interface: {
                    history.put(tc, oldPos);

                    int start = writeGap();
                    _OB_writeEndian();
                    write_string(tc.id());
                    write_string(tc.name());
                    writeLength(start);

                    break;
                }

                default:
                    org.apache.yoko.orb.OB.Assert._OB_assert("Invalid typecode");
                }
            } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) {
                org.apache.yoko.orb.OB.Assert._OB_assert(ex);
            } catch (org.omg.CORBA.TypeCodePackage.Bounds ex) {
                org.apache.yoko.orb.OB.Assert._OB_assert(ex);
            }
        }
    }

    //
    // Must be called prior to any writes
    //
    private void checkBeginChunk() {
        org.apache.yoko.orb.OB.Assert._OB_assert(valueWriter_ != null);
        valueWriter_.checkBeginChunk();
    }

    private org.apache.yoko.orb.OB.ValueWriter valueWriter() {
        if (valueWriter_ == null)
            valueWriter_ = new org.apache.yoko.orb.OB.ValueWriter(this);
        return valueWriter_;
    }

    private void addCapacity(int size) {
        //
        // Expand buffer to hold requested size
        //
        // Note: OutputStreams are not always written to in a linear
        // fashion, i.e., sometimes the position is reset to
        // an earlier point and data is patched in. Therefore,
        // do NOT do this:
        //
        // buf_.realloc(buf_.len_ + size);
        //
        //
        if (alignNext_ > 0) {
            int align = alignNext_;
            alignNext_ = 0;
            addCapacity(size, align);
        } else {
            //
            // If we're at the end of the current buffer, then we are about
            // to write new data. We must first check if we need to start a
            // chunk, which may result in a recursive call to addCapacity().
            //
            if (buf_.pos_ == buf_.len_ && valueWriter_ != null) {
                checkBeginChunk();
            }

            //
            // If there isn't enough room, then reallocate the buffer
            //
            final int len = buf_.pos_ + size;
            if (len > buf_.len_) {
                buf_.realloc(len);
            }
        }
    }

    private int roundUp(final int i, final int align) {
        switch (align) {
            case 0x00: return i;
            case 0x01: return i;
            case 0x02: return ((i + 0b0001) & ~(0b0001));
            case 0x04: return ((i + 0b0011) & ~(0b0011));
            case 0x08: return ((i + 0b0111) & ~(0b0111));
            case 0x10: return ((i + 0b1111) & ~(0b1111));
            default:
                if (LOGGER.isLoggable(Level.WARNING))
                    LOGGER.warning(String.format("Aligning on a strange number 0x%x", align));
                final int j = (i + align - 1);
                return (j - (j % align));
        }
    }

    private static final byte PAD_BYTE = (byte)0xbd;

    private void addCapacity(int size, int align) {
        // use addCapacity(int) if align == 0
        org.apache.yoko.orb.OB.Assert._OB_assert(align > 0);

        //
        // If we're at the end of the current buffer, then we are about
        // to write new data. We must first check if we need to start a
        // chunk, which may result in a recursive call to addCapacity().
        //
        if (buf_.pos_ == buf_.len_ && valueWriter_ != null) {
            checkBeginChunk();
        }

        //
        // If alignNext_ is set, then use the larger of alignNext_ and align
        //
        if (alignNext_ > 0) {
            align = (alignNext_ > align ? alignNext_ : align);
            alignNext_ = 0;
        }

        final int newPos = roundUp(buf_.pos_, align);

        //
        // If there isn't enough room, then reallocate the buffer
        //
        final int len = newPos + size;
        if (len > buf_.len_) {
            buf_.realloc(len);
        }

        //
        // Pad to the requested boundary
        //
        for (; buf_.pos_ < newPos; buf_.pos_++) {
            buf_.data_[buf_.pos_] = PAD_BYTE;
        }
    }

    //
    // write wchar using old non-compliant method
    //
    private void _OB_write_wchar_old(char value) {
        if (wCharConversionRequired_) {
            final org.apache.yoko.orb.OB.CodeConverterBase converter = codeConverters_.outputWcharConverter;

            value = converter.convert(value);

            //
            // For GIOP 1.1 non byte-oriented wide characters are written
            // as ushort or ulong, depending on their maximum length
            // listed in the code set registry.
            //
            switch (giopVersion_) {
            case GIOP1_1: {
                if (converter.getTo().max_bytes <= 2)
                    write_ushort((short) value);
                else
                    write_ulong((int) value);
            }
                break;

            default: {
                final int length = converter.write_count_wchar(value);
                write_octet((byte) length);
                addCapacity(length);
                converter.write_wchar(this, value);
            }
                break;
            }
        }
        //
        // UTF-16
        //
        else {
            switch (giopVersion_) {
            case GIOP1_0:
            case GIOP1_1:
                write_ushort((short) value);
                break;

            default:
                addCapacity(3);
                buf_.data_[buf_.pos_++] = 2;
                buf_.data_[buf_.pos_++] = (byte) (value >> 8);
                buf_.data_[buf_.pos_++] = (byte) value;
                break;
            }
        }
    }

    //
    // write wchar using new compilant method
    //
    private void _OB_write_wchar_new(char value, boolean partOfString) {
        final org.apache.yoko.orb.OB.CodeConverterBase converter = codeConverters_.outputWcharConverter;

        //
        // pre-convert the character if necessary
        //
        if (wCharConversionRequired_)
            value = converter.convert(value);

        if (wCharWriterRequired_) {
            if (partOfString == false)
                converter
                        .set_writer_flags(org.apache.yoko.orb.OB.CodeSetWriter.FIRST_CHAR);

            //
            // For GIOP 1.1 non byte-oriented wide characters are written
            // as ushort or ulong, depending on their maximum length
            // listed in the code set registry.
            //
            switch (giopVersion_) {
            case GIOP1_0: {
                //
                // we don't support special writers for GIOP 1.0 if
                // conversion is required or if a writer is required
                //
                org.apache.yoko.orb.OB.Assert._OB_assert(false);
            }
                break;

            case GIOP1_1: {
                //
                // get the length of the character
                //
                int len = converter.write_count_wchar(value);

                //
                // For GIOP 1.1 we are limited to 2-byte wchars
                // so make sure to check for that
                //
                org.apache.yoko.orb.OB.Assert._OB_assert(len == 2);

                //
                // allocate aligned space
                //
                addCapacity(2, 2);

                //
                // write using the writer
                //
                converter.write_wchar(this, value);
            }
                break;

            default: {
                //
                // get the length of the character
                //
                int len = converter.write_count_wchar(value);

                //
                // write the octet length at the beginning
                //
                write_octet((byte) len);

                //
                // add unaligned capacity
                //
                addCapacity(len);

                //
                // write the actual character
                //
                converter.write_wchar(this, value);
            }
                break;
            }
        } else {
            switch (giopVersion_) {
            case GIOP1_0: {
                //
                // Orbix2000/Orbacus/E compatible 1.0 marshal
                //

                //
                // add aligned capacity
                //
                addCapacity(2, 2);

                //
                // write 2-byte character in big endian
                //
                buf_.data_[buf_.pos_++] = (byte) (value >>> 8);
                buf_.data_[buf_.pos_++] = (byte) (value & 0xff);
            }
                break;

            case GIOP1_1: {
                write_ushort((short) value);
            }
                break;

            default: {
                //
                // add unaligned space for character
                //
                addCapacity(3);

                //
                // write the octet length at the start
                //
                buf_.data_[buf_.pos_++] = 2;

                //
                // write the character in big endian format
                //
                buf_.data_[buf_.pos_++] = (byte) (value >>> 8);
                buf_.data_[buf_.pos_++] = (byte) (value & 0xff);
            }
                break;
            }
        }
    }

    //
    // write wstring using old non-compliant method
    //
    private void _OB_write_wstring_old(String value) {
        final char[] arr = value.toCharArray();
        final int len = arr.length;

        //
        // 15.3.2.7: For GIOP version 1.1, a wide string is encoded as an
        // unsigned long indicating the length of the string in octets or
        // unsigned integers (determined by the transfer syntax for wchar)
        // followed by the individual wide characters. Both the string length
        // and contents include a terminating null. The terminating null
        // character for a wstring is also a wide character.
        //
        switch (giopVersion_) {
        case GIOP1_0:
        case GIOP1_1: {
            write_ulong(len + 1);
            write_wchar_array(arr, 0, len);
            write_wchar((char) 0);
        }
            break;

        default: {
            //
            // For octet count
            //
            int start = writeGap();

            if (wCharConversionRequired_) {
                final org.apache.yoko.orb.OB.CodeConverterBase converter = codeConverters_.outputWcharConverter;

                for (int i = 0; i < len; i++) {
                    char v = converter.convert(arr[i]);

                    if (v == 0)
                        throw new org.omg.CORBA.DATA_CONVERSION(
                                "illegal wchar value for wstring: " + (int) v);

                    addCapacity(converter.write_count_wchar(v));
                    converter.write_wchar(this, v);
                }
            }
            //
            // UTF-16
            //
            else {
                addCapacity(2 * len);

                for (int i = 0; i < len; i++) {
                    char v = arr[i];

                    if (v == 0)
                        throw new org.omg.CORBA.DATA_CONVERSION(
                                "illegal wchar value for wstring: " + (int) v);

                    buf_.data_[buf_.pos_++] = (byte) (v >> 8);
                    buf_.data_[buf_.pos_++] = (byte) v;
                }
            }

            //
            // Write octet count
            //
            writeLength(start);
        }
            break;
        }
    }

    //
    // write wstring using new compliant method
    //
    private void _OB_write_wstring_new(String value) {
        final char[] arr = value.toCharArray();
        final int len = arr.length;

        LOGGER.finest("Writing wstring value " + value);
        //
        // get converter/writer instance
        //
        final org.apache.yoko.orb.OB.CodeConverterBase converter = codeConverters_.outputWcharConverter;

        //
        // some writers (specially UTF-16) requires the possible BOM
        // only found at the beginning of a string... this will
        // indicate that we are at the start of the first character
        // of the string to the writer
        if (wCharWriterRequired_)
            converter
                    .set_writer_flags(org.apache.yoko.orb.OB.CodeSetWriter.FIRST_CHAR);

        //
        // for GIOP 1.0/1.1 we don't need to differentiate between
        // strings requiring a writer/converter (or not) since they can
        // be handled by the write_wchar() method
        //
        switch (giopVersion_) {
            case GIOP1_0:
            case GIOP1_1:
                //
                // write the length of the string
                //
                write_ulong(len + 1);

                //
                // now write all the characters
                //
                for (int i = 0; i < len; i++)
                    write_wchar(arr[i], true);

                //
                // and the null terminator
                //
                write_wchar((char) 0, true);
                return;
            default:
        }

        //
        // save the starting position and write the gap to place the
        // length of the string later
        //
        int start = writeGap();

        //
        // we've handled GIOP 1.0/1.1 above so this must be GIOP 1.2+
        //
        if (wCharWriterRequired_) {
            for (int i = 0; i < len; i++) {
                char v = arr[i];

                //
                // check if the character requires conversion
                //
                if (wCharConversionRequired_)
                    v = converter.convert(v);

                //
                // illegal for the string to contain nulls
                //
                if (v == 0)
                    throw new org.omg.CORBA.DATA_CONVERSION(
                            "illegal wchar value for wstring: " + (int) v);

                //
                // add capacity for the character
                //
                addCapacity(converter.write_count_wchar(v));

                //
                // write the character
                //
                converter.write_wchar(this, v);
            }
        } else {
            //
            // since we don't require a special writer, each character
            // MUST be 2-bytes in size
            //
            addCapacity(len << 1);

            for (int i = 0; i < len; i++) {
                char v = arr[i];

                //
                // check for conversion
                //
                if (wCharConversionRequired_)
                    v = converter.convert(v);

                //
                // write character in big endian format
                //
                buf_.data_[buf_.pos_++] = (byte) (v >>> 8);
                buf_.data_[buf_.pos_++] = (byte) (v & 0xff);
            }
        }

        //
        // write the octet length
        //
        writeLength(start);
    }

    // ------------------------------------------------------------------
    // Standard IDL to Java Mapping
    // ------------------------------------------------------------------

    public void write(int b) throws java.io.IOException {
        //
        // this matches the behaviour of this function in the Java ORB
        // and not what is outlined in the java.io.OutputStream
        //
        write_long(b);
    }

    public org.omg.CORBA.ORB orb() {
        if (orbInstance_ != null)
            return orbInstance_.getORB();
        return null;
    }

    public org.omg.CORBA.portable.InputStream create_input_stream() {
        org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                buf_.len_);
        if (buf_.len_ > 0)
            System.arraycopy(buf_.data_, 0, buf.data_, 0, buf_.len_);

// this is a useful tracepoint, but produces a lot of data, so turn on only
// if really needed.
//      if (logger.isLoggable(Level.FINEST)) {
//          logger.fine("new input stream created:\n" + buf.dumpData());
//      }

        InputStream in = new InputStream(buf, 0, false, codeConverters_,
                giopVersion_);
        in._OB_ORBInstance(orbInstance_);
        return in;
    }

    public void write_boolean(boolean value) {
        addCapacity(1);

        buf_.data_[buf_.pos_++] = value ? (byte) 1 : (byte) 0;
    }

    public void write_char(char value) {
        if (value > 255)
            throw new org.omg.CORBA.DATA_CONVERSION("char value exceeds 255: "
                    + (int) value);

        addCapacity(1);

        final org.apache.yoko.orb.OB.CodeConverterBase converter = codeConverters_.outputCharConverter;

        if (charConversionRequired_)
            value = converter.convert(value);

        if (charWriterRequired_)
            converter.write_char(this, value);
        else
            buf_.data_[buf_.pos_++] = (byte) value;
    }

    public void write_wchar(char value) {
        write_wchar(value, false);
    }

    public void write_wchar(char value, boolean partOfString) {
        if (org.apache.yoko.orb.OB.OB_Extras.COMPAT_WIDE_MARSHAL == false)
            _OB_write_wchar_new(value, partOfString);
        else
            _OB_write_wchar_old(value);
    }

    public void write_octet(byte value) {
        addCapacity(1);
        buf_.data_[buf_.pos_++] = value;
    }

    public void write_short(short value) {
        addCapacity(2, 2);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 8);
        buf_.data_[buf_.pos_++] = (byte) value;
    }

    public void write_ushort(short value) {
        write_short(value);
    }

    public void write_long(int value) {
        addCapacity(4, 4);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 24);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 16);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 8);
        buf_.data_[buf_.pos_++] = (byte) value;
    }

    public void write_ulong(int value) {
        write_long(value);
    }

    public void write_longlong(long value) {
        addCapacity(8, 8);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 56);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 48);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 40);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 32);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 24);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 16);
        buf_.data_[buf_.pos_++] = (byte) (value >>> 8);
        buf_.data_[buf_.pos_++] = (byte) value;
    }

    public void write_ulonglong(long value) {
        write_longlong(value);
    }

    public void write_float(float value) {
        write_long(Float.floatToIntBits(value));
    }

    public void write_double(double value) {
        write_longlong(Double.doubleToLongBits(value));
    }

    public void write_string(String value) {
        LOGGER.finest("Writing string value " + value);
        final char[] arr = value.toCharArray();
        int len = arr.length;
        int capacity = len + 1;

        if (!(charWriterRequired_ || charConversionRequired_)) {
            write_ulong(capacity);
            addCapacity(capacity);

            for (int i = 0; i < len; i++) {
                char c = arr[i];

                if (c == 0 || c > 255)
                    throw new org.omg.CORBA.DATA_CONVERSION(
                            "illegal char value for string: " + (int) c);

                buf_.data_[buf_.pos_++] = (byte) c;
            }
        } else {
            final org.apache.yoko.orb.OB.CodeConverterBase converter = codeConverters_.outputCharConverter;

            //
            // Intermediate variable used for efficiency
            //
            boolean bothRequired = charWriterRequired_
                    && charConversionRequired_;

            //
            // Temporary OCI buffer required
            //
            org.apache.yoko.orb.OCI.Buffer buffer = new org.apache.yoko.orb.OCI.Buffer(
                    64);
            OutputStream tmpStream = new OutputStream(buffer);

            for (int i = 0; i < len; i++) {
                char c = arr[i];

                if (c == 0 || c > 255)
                    throw new org.omg.CORBA.DATA_CONVERSION(
                            "illegal char value for string: " + (int) c);

                //
                // Expand the temporary buffer, if necessary
                //
                if (buffer.length() - buffer.pos() <= 4)
                    buffer.realloc(buffer.length() * 2);

                if (bothRequired)
                    converter.write_char(tmpStream, converter.convert(c));
                else if (charWriterRequired_)
                    converter.write_char(tmpStream, c);
                else
                    buffer.data_[buffer.pos_++] = (byte) converter.convert(c);
            }

            //
            // Copy the contents from the temporary buffer
            //
            int bufSize = buffer.pos_;

            write_ulong(bufSize + 1);
            addCapacity(bufSize + 1);

            for (int i = 0; i < bufSize; i++) {
                buf_.data_[buf_.pos_++] = buffer.data_[i];
            }
        }

        buf_.data_[buf_.pos_++] = (byte) 0;
    }

    public void write_wstring(String value) {
        if (org.apache.yoko.orb.OB.OB_Extras.COMPAT_WIDE_MARSHAL == false)
            _OB_write_wstring_new(value);
        else
            _OB_write_wstring_old(value);
    }

    public void write_boolean_array(boolean[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length);

            for (int i = offset; i < offset + length; i++)
                buf_.data_[buf_.pos_++] = value[i] ? (byte) 1 : (byte) 0;
        }
    }

    public void write_char_array(char[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length);

            if (!(charWriterRequired_ || charConversionRequired_)) {
                for (int i = offset; i < offset + length; i++) {
                    if (value[i] > 255)
                        throw new org.omg.CORBA.DATA_CONVERSION(
                                "char value exceeds 255: " + (int) value[i]);

                    buf_.data_[buf_.pos_++] = (byte) value[i];
                }
            } else {
                final org.apache.yoko.orb.OB.CodeConverterBase converter = codeConverters_.outputCharConverter;

                //
                // Intermediate variable used for efficiency
                //
                boolean bothRequired = charWriterRequired_
                        && charConversionRequired_;

                for (int i = offset; i < offset + length; i++) {
                    if (value[i] > 255)
                        throw new org.omg.CORBA.DATA_CONVERSION(
                                "char value exceeds 255: " + (int) value[i]);

                    if (bothRequired)
                        converter.write_char(this, converter.convert(value[i]));
                    else if (charWriterRequired_)
                        converter.write_char(this, value[i]);
                    else
                        buf_.data_[buf_.pos_++] = (byte) converter
                                .convert(value[i]);
                }
            }
        }
    }

    public void write_wchar_array(char[] value, int offset, int length) {
        for (int i = offset; i < offset + length; i++)
            write_wchar(value[i], false);
    }

    public void write_octet_array(byte[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length);

            System.arraycopy(value, offset, buf_.data_, buf_.pos_, length);

            buf_.pos_ += length;
        }
    }

    public void write_short_array(short[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length * 2, 2);

            for (int i = offset; i < offset + length; i++) {
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 8);
                buf_.data_[buf_.pos_++] = (byte) value[i];
            }
        }
    }

    public void write_ushort_array(short[] value, int offset, int length) {
        write_short_array(value, offset, length);
    }

    public void write_long_array(int[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length * 4, 4);

            for (int i = offset; i < offset + length; i++) {
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 24);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 16);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 8);
                buf_.data_[buf_.pos_++] = (byte) value[i];
            }
        }
    }

    public void write_ulong_array(int[] value, int offset, int length) {
        write_long_array(value, offset, length);
    }

    public void write_longlong_array(long[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length * 8, 8);

            for (int i = offset; i < offset + length; i++) {
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 56);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 48);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 40);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 32);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 24);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 16);
                buf_.data_[buf_.pos_++] = (byte) (value[i] >>> 8);
                buf_.data_[buf_.pos_++] = (byte) value[i];
            }
        }
    }

    public void write_ulonglong_array(long[] value, int offset, int length) {
        write_longlong_array(value, offset, length);
    }

    public void write_float_array(float[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length * 4, 4);

            for (int i = offset; i < offset + length; i++) {
                int v = Float.floatToIntBits(value[i]);

                buf_.data_[buf_.pos_++] = (byte) (v >>> 24);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 16);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 8);
                buf_.data_[buf_.pos_++] = (byte) v;
            }
        }
    }

    public void write_double_array(double[] value, int offset, int length) {
        if (length > 0) {
            addCapacity(length * 8, 8);

            for (int i = offset; i < offset + length; i++) {
                long v = Double.doubleToLongBits(value[i]);

                buf_.data_[buf_.pos_++] = (byte) (v >>> 56);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 48);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 40);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 32);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 24);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 16);
                buf_.data_[buf_.pos_++] = (byte) (v >>> 8);
                buf_.data_[buf_.pos_++] = (byte) v;
            }
        }
    }

    public void write_Object(org.omg.CORBA.Object value) {
        if (value == null) {
            LOGGER.finest("Writing a null CORBA object value");
            org.omg.IOP.IOR ior = new org.omg.IOP.IOR();
            ior.type_id = "";
            ior.profiles = new org.omg.IOP.TaggedProfile[0];
            org.omg.IOP.IORHelper.write(this, ior);
        } else {
            if (value instanceof org.omg.CORBA.LocalObject)
                throw new org.omg.CORBA.MARSHAL(
                        org.apache.yoko.orb.OB.MinorCodes
                                .describeMarshal(org.apache.yoko.orb.OB.MinorCodes.MinorLocalObject),
                        org.apache.yoko.orb.OB.MinorCodes.MinorLocalObject,
                        org.omg.CORBA.CompletionStatus.COMPLETED_NO);

            Delegate p = (Delegate) ((org.omg.CORBA.portable.ObjectImpl) value)
                    ._get_delegate();

            p._OB_marshalOrigIOR(this);
        }
    }

    public void write_TypeCode(org.omg.CORBA.TypeCode t) {
        //
        // NOTE:
        //
        // No data with natural alignment of greater than four octets
        // is needed for TypeCode. Therefore it is not necessary to do
        // encapsulation in a separate buffer.
        //

        if (t == null)
            throw new org.omg.CORBA.BAD_TYPECODE("TypeCode is nil");

        java.util.Hashtable history = new java.util.Hashtable(11);
        writeTypeCodeImpl(t, history);
    }

    public void write_any(org.omg.CORBA.Any value) {
        LOGGER.finest("Writing an ANY value of type " + value.type().kind());
        write_TypeCode(value.type());
        value.write_value(this);
    }

    public void write_Context(org.omg.CORBA.Context ctx,
            org.omg.CORBA.ContextList contexts) {
        int count = contexts.count();
        java.util.Vector v = new java.util.Vector();
        org.apache.yoko.orb.CORBA.Context ctxImpl = (org.apache.yoko.orb.CORBA.Context) ctx;
        for (int i = 0; i < count; i++) {
            try {
                String pattern = contexts.item(i);
                ctxImpl._OB_getValues("", 0, pattern, v);
            } catch (org.omg.CORBA.Bounds ex) {
                org.apache.yoko.orb.OB.Assert._OB_assert(ex);
            }
        }

        write_ulong(v.size());

        java.util.Enumeration e = v.elements();
        while (e.hasMoreElements())
            write_string((String) e.nextElement());
    }

    public void write_Principal(org.omg.CORBA.Principal value) {
        // Deprecated by CORBA 2.2
        throw new org.omg.CORBA.NO_IMPLEMENT();
    }

    public void write_fixed(java.math.BigDecimal value) {
        String v = value.abs().toString();

        //
        // Append coded sign to value string
        //
        if (value.signum() == -1)
            v += (char) ('0' + 0x0d);
        else
            v += (char) ('0' + 0x0c);

        String s = "";
        if ((v.length() & 1) != 0)
            s = "0";

        s += v;
        final int len = s.length();

        for (int i = 0; i < len - 1; i += 2) {
            char c1 = s.charAt(i);
            char c2 = s.charAt(i + 1);
            write_octet((byte) ((c1 - '0') << 4 | (c2 - '0')));
        }
    }

    public void write_value(java.io.Serializable value) {
        valueWriter().writeValue(value, null);
    }

    public void write_value(java.io.Serializable value, java.lang.String rep_id) {
        valueWriter().writeValue(value, rep_id);
    }

    public void write_value(java.io.Serializable value, Class clz) {
        valueWriter().writeValue(value, null);
    }

    public void write_value(java.io.Serializable value,
            org.omg.CORBA.portable.BoxedValueHelper helper) {
        valueWriter().writeValueBox(value, null, helper);
    }

    public void write_abstract_interface(java.lang.Object obj) {
        valueWriter().writeAbstractInterface(obj);
    }

    // ------------------------------------------------------------------
    // Additional Yoko specific functions
    // ------------------------------------------------------------------

    public void write_value(java.io.Serializable value,
            org.omg.CORBA.TypeCode tc,
            org.omg.CORBA.portable.BoxedValueHelper helper) {
        valueWriter().writeValueBox(value, tc, helper);
    }

    public void write_InputStream(org.omg.CORBA.portable.InputStream in,
            org.omg.CORBA.TypeCode tc) {
        InputStream obin = null;
        try {
            obin = (InputStream) in;
        } catch (ClassCastException ex) {
            // InputStream may have been created by a different ORB
        }

        try {
            LOGGER.fine("writing a value of type " + tc.kind().value());

            switch (tc.kind().value()) {
            case org.omg.CORBA.TCKind._tk_null:
            case org.omg.CORBA.TCKind._tk_void:
                break;

            case org.omg.CORBA.TCKind._tk_short:
            case org.omg.CORBA.TCKind._tk_ushort:
                write_short(in.read_short());
                break;

            case org.omg.CORBA.TCKind._tk_long:
            case org.omg.CORBA.TCKind._tk_ulong:
            case org.omg.CORBA.TCKind._tk_float:
            case org.omg.CORBA.TCKind._tk_enum:
                write_long(in.read_long());
                break;

            case org.omg.CORBA.TCKind._tk_double:
            case org.omg.CORBA.TCKind._tk_longlong:
            case org.omg.CORBA.TCKind._tk_ulonglong:
                write_longlong(in.read_longlong());
                break;

            case org.omg.CORBA.TCKind._tk_boolean:
            case org.omg.CORBA.TCKind._tk_octet:
                write_octet(in.read_octet());
                break;

            case org.omg.CORBA.TCKind._tk_char:
                write_char(in.read_char());
                break;

            case org.omg.CORBA.TCKind._tk_wchar:
                write_wchar(in.read_wchar());
                break;

            case org.omg.CORBA.TCKind._tk_fixed:
                write_fixed(in.read_fixed());
                break;

            case org.omg.CORBA.TCKind._tk_any: {
                // Don't do this: write_any(in.read_any())
                // This is faster:
                org.omg.CORBA.TypeCode p = in.read_TypeCode();
                write_TypeCode(p);
                write_InputStream(in, p);
                break;
            }

            case org.omg.CORBA.TCKind._tk_TypeCode: {
                // Don't do this: write_TypeCode(in.read_TypeCode())
                // This is faster:

                int kind = in.read_ulong();

                //
                // An indirection is not permitted at this level
                //
                if (kind == -1) {
                    throw new org.omg.CORBA.MARSHAL(
                            org.apache.yoko.orb.OB.MinorCodes
                                    .describeMarshal(org.apache.yoko.orb.OB.MinorCodes.MinorReadInvTypeCodeIndirection),
                            org.apache.yoko.orb.OB.MinorCodes.MinorReadInvTypeCodeIndirection,
                            org.omg.CORBA.CompletionStatus.COMPLETED_NO);
                }

                write_ulong(kind);

                switch (kind) {
                case org.omg.CORBA.TCKind._tk_null:
                case org.omg.CORBA.TCKind._tk_void:
                case org.omg.CORBA.TCKind._tk_short:
                case org.omg.CORBA.TCKind._tk_long:
                case org.omg.CORBA.TCKind._tk_ushort:
                case org.omg.CORBA.TCKind._tk_ulong:
                case org.omg.CORBA.TCKind._tk_float:
                case org.omg.CORBA.TCKind._tk_double:
                case org.omg.CORBA.TCKind._tk_boolean:
                case org.omg.CORBA.TCKind._tk_char:
                case org.omg.CORBA.TCKind._tk_octet:
                case org.omg.CORBA.TCKind._tk_any:
                case org.omg.CORBA.TCKind._tk_TypeCode:
                case org.omg.CORBA.TCKind._tk_Principal:
                case org.omg.CORBA.TCKind._tk_longlong:
                case org.omg.CORBA.TCKind._tk_ulonglong:
                case org.omg.CORBA.TCKind._tk_longdouble:
                case org.omg.CORBA.TCKind._tk_wchar:
                    break;

                case org.omg.CORBA.TCKind._tk_fixed:
                    write_ushort(in.read_ushort());
                    write_short(in.read_short());
                    break;

                case org.omg.CORBA.TCKind._tk_objref:
                case org.omg.CORBA.TCKind._tk_struct:
                case org.omg.CORBA.TCKind._tk_union:
                case org.omg.CORBA.TCKind._tk_enum:
                case org.omg.CORBA.TCKind._tk_sequence:
                case org.omg.CORBA.TCKind._tk_array:
                case org.omg.CORBA.TCKind._tk_alias:
                case org.omg.CORBA.TCKind._tk_except:
                case org.omg.CORBA.TCKind._tk_value:
                case org.omg.CORBA.TCKind._tk_value_box:
                case org.omg.CORBA.TCKind._tk_abstract_interface:
                case org.omg.CORBA.TCKind._tk_native:
                case org.omg.CORBA_2_4.TCKind._tk_local_interface: {
                    final int len = in.read_ulong();
                    write_ulong(len);
                    addCapacity(len);
                    in.read_octet_array(buf_.data_, buf_.pos_, len);
                    buf_.pos_ += len;
                    break;
                }

                case org.omg.CORBA.TCKind._tk_string:
                case org.omg.CORBA.TCKind._tk_wstring: {
                    int bound = in.read_ulong();
                    write_ulong(bound);
                    break;
                }

                default:
                    throw new InternalError();
                }

                break;
            }

            case org.omg.CORBA.TCKind._tk_Principal:
                write_Principal(in.read_Principal());
                break;

            case org.omg.CORBA.TCKind._tk_objref: {
                // Don't do this: write_Object(in.read_Object())
                // This is faster:
                org.omg.IOP.IOR ior = org.omg.IOP.IORHelper.read(in);
                org.omg.IOP.IORHelper.write(this, ior);
                break;
            }

            case org.omg.CORBA.TCKind._tk_struct:
                for (int i = 0; i < tc.member_count(); i++)
                    write_InputStream(in, tc.member_type(i));
                break;

            case org.omg.CORBA.TCKind._tk_except:
                write_string(in.read_string());
                for (int i = 0; i < tc.member_count(); i++)
                    write_InputStream(in, tc.member_type(i));
                break;

            case org.omg.CORBA.TCKind._tk_union: {
                int defaultIndex = tc.default_index();
                int memberIndex = -1;

                org.omg.CORBA.TypeCode origDiscType = TypeCode
                        ._OB_getOrigType(tc.discriminator_type());

                switch (origDiscType.kind().value()) {
                case org.omg.CORBA.TCKind._tk_short: {
                    short val = in.read_short();
                    write_short(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_short()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_ushort: {
                    short val = in.read_ushort();
                    write_ushort(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_ushort()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_long: {
                    int val = in.read_long();
                    write_long(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_long()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_ulong: {
                    int val = in.read_ulong();
                    write_ulong(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_ulong()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_longlong: {
                    long val = in.read_longlong();
                    write_longlong(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_longlong()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_ulonglong: {
                    long val = in.read_ulonglong();
                    write_ulonglong(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_ulonglong()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_char: {
                    char val = in.read_char();
                    write_char(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_char()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_boolean: {
                    boolean val = in.read_boolean();
                    write_boolean(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).extract_boolean()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                case org.omg.CORBA.TCKind._tk_enum: {
                    int val = in.read_long();
                    write_long(val);

                    for (int i = 0; i < tc.member_count(); i++)
                        if (i != defaultIndex) {
                            if (val == tc.member_label(i).create_input_stream()
                                    .read_long()) {
                                memberIndex = i;
                                break;
                            }
                        }

                    break;
                }

                default:
                    org.apache.yoko.orb.OB.Assert._OB_assert("Invalid typecode in tk_union");
                }

                if (memberIndex >= 0)
                    write_InputStream(in, tc.member_type(memberIndex));
                else if (defaultIndex >= 0)
                    write_InputStream(in, tc.member_type(defaultIndex));

                break;
            }

            case org.omg.CORBA.TCKind._tk_string:
                write_string(in.read_string());
                break;

            case org.omg.CORBA.TCKind._tk_wstring:
                write_wstring(in.read_wstring());
                break;

            case org.omg.CORBA.TCKind._tk_sequence:
            case org.omg.CORBA.TCKind._tk_array: {
                int len;

                if (tc.kind().value() == org.omg.CORBA.TCKind._tk_sequence) {
                    len = in.read_ulong();
                    write_ulong(len);
                } else
                    len = tc.length();

                if (len > 0) {
                    org.omg.CORBA.TypeCode origContentType = TypeCode
                            ._OB_getOrigType(tc.content_type());

                    switch (origContentType.kind().value()) {
                    case org.omg.CORBA.TCKind._tk_null:
                    case org.omg.CORBA.TCKind._tk_void:
                        break;

                    case org.omg.CORBA.TCKind._tk_short:
                    case org.omg.CORBA.TCKind._tk_ushort: {
                        if (obin == null || obin.swap_) {
                            short[] s = new short[len];
                            in.read_short_array(s, 0, len);
                            write_short_array(s, 0, len);
                        } else {
                            // Read one value for the alignment
                            write_short(obin.read_short());
                            final int n = 2 * (len - 1);

                            if (n > 0) {
                                // Copy the rest
                                addCapacity(n);
                                org.apache.yoko.orb.OCI.Buffer buf = obin
                                        ._OB_buffer();
                                System.arraycopy(buf.data_, buf.pos_,
                                        buf_.data_, buf_.pos_, n);
                                buf.pos_ += n;
                                buf_.pos_ += n;
                            }
                        }
                        break;
                    }

                    case org.omg.CORBA.TCKind._tk_long:
                    case org.omg.CORBA.TCKind._tk_ulong:
                    case org.omg.CORBA.TCKind._tk_float: {
                        if (obin == null || obin.swap_) {
                            int[] i = new int[len];
                            in.read_long_array(i, 0, len);
                            write_long_array(i, 0, len);
                        } else {
                            // Read one value for the alignment
                            write_long(obin.read_long());
                            final int n = 4 * (len - 1);

                            if (n > 0) {
                                // Copy the rest
                                addCapacity(n);
                                org.apache.yoko.orb.OCI.Buffer buf = obin
                                        ._OB_buffer();
                                System.arraycopy(buf.data_, buf.pos_,
                                        buf_.data_, buf_.pos_, n);
                                buf.pos_ += n;
                                buf_.pos_ += n;
                            }
                        }
                        break;
                    }

                    case org.omg.CORBA.TCKind._tk_double:
                    case org.omg.CORBA.TCKind._tk_longlong:
                    case org.omg.CORBA.TCKind._tk_ulonglong: {
                        if (obin == null || obin.swap_) {
                            long[] l = new long[len];
                            in.read_longlong_array(l, 0, len);
                            write_longlong_array(l, 0, len);
                        } else {
                            // Read one value for the alignment
                            write_longlong(obin.read_longlong());
                            final int n = 8 * (len - 1);
                            if (n > 0) {
                                // Copy the rest
                                addCapacity(n);
                                org.apache.yoko.orb.OCI.Buffer buf = obin
                                        ._OB_buffer();
                                System.arraycopy(buf.data_, buf.pos_,
                                        buf_.data_, buf_.pos_, n);
                                buf.pos_ += n;
                                buf_.pos_ += n;
                            }
                        }
                        break;
                    }

                    case org.omg.CORBA.TCKind._tk_boolean:
                    case org.omg.CORBA.TCKind._tk_octet:
                        if (obin == null) {
                            addCapacity(len);
                            in.read_octet_array(buf_.data_, buf_.pos_, len);
                            buf_.pos_ += len;
                        } else {
                            addCapacity(len);
                            org.apache.yoko.orb.OCI.Buffer buf = obin
                                    ._OB_buffer();
                            System.arraycopy(buf.data_, buf.pos_, buf_.data_,
                                    buf_.pos_, len);
                            buf.pos_ += len;
                            buf_.pos_ += len;
                        }
                        break;

                    case org.omg.CORBA.TCKind._tk_char:
                        if (charWriterRequired_ || charConversionRequired_) {
                            char[] ch = new char[len];
                            in.read_char_array(ch, 0, len);
                            write_char_array(ch, 0, len);
                        } else {
                            addCapacity(len);
                            in.read_octet_array(buf_.data_, buf_.pos_, len);
                            buf_.pos_ += len;
                        }
                        break;

                    case org.omg.CORBA.TCKind._tk_wchar: {
                        char[] wch = new char[len];
                        in.read_wchar_array(wch, 0, len);
                        write_wchar_array(wch, 0, len);
                        break;
                    }

                    case org.omg.CORBA.TCKind._tk_alias:
                        org.apache.yoko.orb.OB.Assert._OB_assert("tk_alias not supported in tk_array or tk_sequence");
                        break;

                    default:
                        for (int i = 0; i < len; i++)
                            write_InputStream(in, tc.content_type());
                        break;
                    }
                }

                break;
            }

            case org.omg.CORBA.TCKind._tk_alias:
                write_InputStream(in, tc.content_type());
                break;

            case org.omg.CORBA.TCKind._tk_value:
            case org.omg.CORBA.TCKind._tk_value_box:
                if (obin == null) {
                    org.omg.CORBA_2_3.portable.InputStream i = (org.omg.CORBA_2_3.portable.InputStream) in;
                    write_value(i.read_value());
                } else
                    obin._OB_remarshalValue(tc, this);
                break;

            case org.omg.CORBA.TCKind._tk_abstract_interface: {
                boolean b = in.read_boolean();
                write_boolean(b);
                if (b) {
                    write_Object(in.read_Object());
                } else {
                    if (obin == null) {
                        org.omg.CORBA_2_3.portable.InputStream i = (org.omg.CORBA_2_3.portable.InputStream) in;
                        write_value(i.read_value());
                    } else {
                        //
                        // We have no TypeCode information about the
                        // valuetype, so we must use _tc_ValueBase and
                        // rely on the type information sent on the wire
                        //
                        obin._OB_remarshalValue(org.omg.CORBA.ValueBaseHelper
                                .type(), this);
                    }
                }
                break;
            }

            case org.omg.CORBA_2_4.TCKind._tk_local_interface:
            case org.omg.CORBA.TCKind._tk_native:
            default:
                org.apache.yoko.orb.OB.Assert._OB_assert("unsupported types");
            }
        } catch (org.omg.CORBA.TypeCodePackage.BadKind ex) {
            org.apache.yoko.orb.OB.Assert._OB_assert(ex);
        } catch (org.omg.CORBA.TypeCodePackage.Bounds ex) {
            org.apache.yoko.orb.OB.Assert._OB_assert(ex);
        }
    }

    // ------------------------------------------------------------------
    // Yoko internal functions
    // Application programs must not use these functions directly
    // ------------------------------------------------------------------

    public OutputStream(org.apache.yoko.orb.OCI.Buffer buf) {
        this(buf, null, null);
    }

    public OutputStream(org.apache.yoko.orb.OCI.Buffer buf,
            org.apache.yoko.orb.OB.CodeConverters converters, GiopVersion giopVersion) {
        buf_ = buf;

        if (giopVersion != null)
            giopVersion_ = giopVersion;

        charWriterRequired_ = false;
        charConversionRequired_ = false;
        wCharWriterRequired_ = false;
        wCharConversionRequired_ = false;

        codeConverters_ = new org.apache.yoko.orb.OB.CodeConverters(converters);

        if (converters != null) {
            if (codeConverters_.outputCharConverter != null) {
                charWriterRequired_ = codeConverters_.outputCharConverter
                        .writerRequired();
                charConversionRequired_ = codeConverters_.outputCharConverter
                        .conversionRequired();
            }

            if (codeConverters_.outputWcharConverter != null) {
                wCharWriterRequired_ = codeConverters_.outputWcharConverter
                        .writerRequired();
                wCharConversionRequired_ = codeConverters_.outputWcharConverter
                        .conversionRequired();
            }
        }
    }

    public org.apache.yoko.orb.OCI.Buffer _OB_buffer() {
        return buf_;
    }

    public int _OB_pos() {
        return buf_.pos_;
    }

    public void _OB_pos(int pos) {
        buf_.pos_ = pos;
    }

    public void _OB_align(int n) {
        if (buf_.pos_ % n != 0)
            addCapacity(0, n);
    }

    public void _OB_alignNext(int n) {
        alignNext_ = n;
    }

    public void _OB_writeEndian() {
        write_boolean(false); // false means big endian
    }

    public void _OB_beginValue(int tag, String[] ids, boolean chunked) {
        valueWriter().beginValue(tag, ids, null, chunked);
    }

    public void _OB_endValue() {
        valueWriter().endValue();
    }

    // Java only
    public void _OB_ORBInstance(org.apache.yoko.orb.OB.ORBInstance orbInstance) {
        orbInstance_ = orbInstance;
    }

    // Java only
    public org.apache.yoko.orb.OB.ORBInstance _OB_ORBInstance() {
        return orbInstance_;
    }

    // Java only
    public void _OB_invocationContext(java.lang.Object invocationContext) {
        invocationContext_ = invocationContext;
    }

    // Java only
    public java.lang.Object _OB_invocationContext() {
        return invocationContext_;
    }

    // Java only
    public void _OB_delegateContext(java.lang.Object delegateContext) {
        delegateContext_ = delegateContext;
    }

    // Java only
    public java.lang.Object _OB_delegateContext() {
        return delegateContext_;
    }

    @Override
    public void end_value() {
        _OB_endValue();
    }

    @Override
    public void start_value(String rep_id) {
        final int tag = 0x7fffff02;
        final String[] ids = { rep_id };
        _OB_beginValue(tag, ids, true);
    }
}
