All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.contextpropagation.wireadapters.PositionAwareObjectOutputStream Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2006-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package org.glassfish.contextpropagation.wireadapters;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;

/**
 * A stream that keeps track of the position
 */
public class PositionAwareObjectOutputStream extends ObjectOutputStream {
  short pos; // initialized by the super constructor
  ObjectOutputStream underlying;

  public PositionAwareObjectOutputStream(OutputStream os) throws IOException {
    super();
    underlying = new ObjectOutputStream(os);
  }

  public short position() throws IOException {
    return pos;
  }

  @Override
  protected void writeObjectOverride(Object obj) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(obj);
    oos.flush();
    byte[] bytes = baos.toByteArray();
    pos += bytes.length - 1;
    underlying.writeObject(obj);
  }

  @Override
  public void writeUnshared(Object obj) throws IOException {
    throw new UnsupportedOperationException("We do not need this for the WireAdapter");
  }

  @Override
  public void writeFields() throws IOException {
    throw new UnsupportedOperationException("We do not need this for the WireAdapter");
  }

  @Override
  protected void writeStreamHeader() throws IOException {
    pos += 4;
    throw new UnsupportedOperationException("We do not need this for the WireAdapter");
  }

  @Override
  public void useProtocolVersion(int version) throws IOException {
    underlying.useProtocolVersion(version);
  }

  @Override
  public void defaultWriteObject() throws IOException {
    underlying.defaultWriteObject();
  }

  @Override
  public PutField putFields() throws IOException {
    return underlying.putFields();
  }

  @Override
  public void reset() throws IOException {
    underlying.reset();
  }

  @Override
  public void flush() throws IOException {
    underlying.flush();
  }

  @Override
  public void close() throws IOException {
    underlying.close();
  }

  @Override
  protected void writeClassDescriptor(ObjectStreamClass desc)
      throws IOException {
    throw new UnsupportedOperationException("We should never use this directly");
  }

  @Override
  public void write(int val) throws IOException {
    pos += Byte.SIZE / Byte.SIZE;
    underlying.write(val);
  }

  @Override
  public void write(byte[] buf) throws IOException {
    pos += buf.length;
    underlying.write(buf);
  }

  @Override
  public void write(byte[] buf, int off, int len) throws IOException {
    pos += len - off;
    underlying.write(buf, off, len);
  }

  @Override
  public void writeBoolean(boolean val) throws IOException {
    pos += Byte.SIZE / Byte.SIZE;
    underlying.writeBoolean(val);
  }

  @Override
  public void writeByte(int val) throws IOException {
    pos += Byte.SIZE / Byte.SIZE;
    underlying.writeByte(val);
  }

  @Override
  public void writeShort(int val) throws IOException {
    pos += Short.SIZE / Byte.SIZE;
    underlying.writeShort(val);
  }

  @Override
  public void writeChar(int val) throws IOException {
    pos += Character.SIZE / Byte.SIZE;
    underlying.writeChar(val);
  }

  @Override
  public void writeInt(int val) throws IOException {
    pos += Integer.SIZE / Byte.SIZE;
    underlying.writeInt(val);
  }

  @Override
  public void writeLong(long val) throws IOException {
    pos += Long.SIZE / Byte.SIZE;
    underlying.writeLong(val);
  }

  @Override
  public void writeFloat(float val) throws IOException {
    pos += Float.SIZE / Byte.SIZE;
    underlying.writeFloat(val);
  }

  @Override
  public void writeDouble(double val) throws IOException {
    pos += Double.SIZE / Byte.SIZE;
    underlying.writeDouble(val);
  }

  @Override
  public void writeBytes(String str) throws IOException {
    pos += str.length(); // may not be correct
    underlying.writeBytes(str);
  }

  @Override
  public void writeChars(String str) throws IOException {
    pos += str.length() * Character.SIZE / Byte.SIZE;
    underlying.writeChars(str);
  }

  @Override
  public void writeUTF(String str) throws IOException {
    pos += Short.SIZE / Byte.SIZE + getUTFLength(str);
    underlying.writeUTF(str);
  }

  /* From java.io.ObjectOutputStream */
  private static final int CHAR_BUF_SIZE = 2048;
  private char[] cbuf = new char[CHAR_BUF_SIZE];
  synchronized long getUTFLength(String s) {
    int len = s.length();
    long utflen = 0;
    for (int off = 0; off < len; ) {
      int csize = Math.min(len - off, CHAR_BUF_SIZE);
      s.getChars(off, off + csize, cbuf, 0);
      for (int cpos = 0; cpos < csize; cpos++) {
        char c = cbuf[cpos];
        if (c >= 0x0001 && c <= 0x007F) {
          utflen++;
        } else if (c > 0x07FF) {
          utflen += 3;
        } else {
          utflen += 2;
        }
      }
      off += csize;
    }
    return utflen;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy