Commit 65091187 authored by Andre Freyssinet's avatar Andre Freyssinet
Browse files

Use UTF-8 default to serialize String objects, allows to fix a specific

charset.
parent 82f91a1c
/*
* JORAM: Java(TM) Open Reliable Asynchronous Messaging
* Copyright (C) 2006 - 2020 ScalAgent Distributed Technologies
* Copyright (C) 2006 - 2022 ScalAgent Distributed Technologies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -27,24 +27,53 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import fr.dyade.aaa.common.Configuration;
import fr.dyade.aaa.common.Debug;
import fr.dyade.aaa.common.encoding.Decoder;
import fr.dyade.aaa.common.encoding.Encodable;
import fr.dyade.aaa.common.encoding.EncodableHelper;
import fr.dyade.aaa.common.encoding.Encoder;
public final class StreamUtil {
static Logger logger = Debug.getLogger(StreamUtil.class.getName());
// ############################################################
// Fix charset used to encode/decode String objects.
public final static String STREAM_CHARSET_PROPERTY = "fr.dyade.aaa.common.stream.charset";
public final static String STREAM_USE_JVM_CHARSET_PROPERTY = "fr.dyade.aaa.common.stream.useJVMcharset";
public final static String STREAM_CHARSET_DFLT = "UTF-8";
private final static Charset charset;
static {
if (Configuration.getBoolean(STREAM_USE_JVM_CHARSET_PROPERTY)) {
charset = Charset.defaultCharset();
} else {
charset = Charset.forName(Configuration.getProperty(STREAM_CHARSET_PROPERTY, STREAM_CHARSET_DFLT));
}
logger.log(BasicLevel.INFO, "Stream configuration: " + charset.displayName());
}
//############################################################
// Per-thread buffer for conversion
private static ThreadLocal perThreadBuffer = new ThreadLocal() {
protected synchronized Object initialValue() {
return new byte[8];
}
};
// Be careful, the buffer will be reused..
private static byte[] readFully(int length, InputStream is) throws IOException {
int count = 0;
......@@ -75,7 +104,7 @@ public final class StreamUtil {
public static final int FALSE = 1;
/**
* This method allows to write a boolean to the output stream.
* This method allows to write a boolean to the output stream.
*
* @param b the boolean to write
* @param os the stream to write the object to
......@@ -282,6 +311,7 @@ public final class StreamUtil {
/**
* This method allows to write a String to the output stream.
* /!\ Be careful, since Joram 5.19 by default String objects are encoded using UTF-8 charset.
*
* @param str the String to write
* @param os the stream to write the object to
......@@ -293,7 +323,7 @@ public final class StreamUtil {
} else if (str.length() == 0) {
writeTo(0, os);
} else {
byte[] buf = str.getBytes();
byte[] buf = str.getBytes(charset);
writeTo(buf.length, os);
os.write(buf);
}
......@@ -303,6 +333,7 @@ public final class StreamUtil {
/**
* This method allows to restore a String from the input stream.
* /!\ Be careful, since Joram 5.19 by default String objects are encoded using UTF-8 charset.
*
* @param is the stream to read data from in order to restore the object
* @return the String object or null
......@@ -316,15 +347,16 @@ public final class StreamUtil {
return EMPTY_STRING;
} else if (length > 0) {
byte[] tab = readFully(length, is);
return new String(tab, 0, length);
return new String(tab, 0, length, charset);
} else {
throw new IOException("bad string length");
}
}
/**
* This method allows to restore a short String from the input stream. The
* maximum length for a short String is 255 characters.
* This method allows to restore a short String from the input stream.
* The maximum length for a short String is 255 characters (Used only one time in AMQP).
* /!\ Be careful, these String objects are encoded using UTF-8 charset.
*
* @param is
* the stream to read data from in order to restore the object
......@@ -339,7 +371,7 @@ public final class StreamUtil {
return EMPTY_STRING;
} else if (length > 0) {
byte[] tab = readFully(length, is);
return new String(tab, 0, length);
return new String(tab, 0, length, "UTF-8");
} else {
throw new IOException("bad short string length");
}
......@@ -503,19 +535,19 @@ public final class StreamUtil {
case NULL:
return null;
case BOOLEAN:
return new Boolean(readBooleanFrom(is));
return Boolean.valueOf(readBooleanFrom(is));
case BYTE:
return new Byte(readByteFrom(is));
return Byte.valueOf(readByteFrom(is));
case SHORT:
return new Short(readShortFrom(is));
return Short.valueOf(readShortFrom(is));
case INT:
return new Integer(readIntFrom(is));
return Integer.valueOf(readIntFrom(is));
case LONG:
return new Long(readLongFrom(is));
return Long.valueOf(readLongFrom(is));
case FLOAT:
return new Float(readFloatFrom(is));
return Float.valueOf(readFloatFrom(is));
case DOUBLE:
return new Double(readDoubleFrom(is));
return Double.valueOf(readDoubleFrom(is));
case STRING:
return readStringFrom(is);
case BYTEARRAY:
......@@ -552,8 +584,7 @@ public final class StreamUtil {
}
/**
* This method allows to write a generic list of String objects to the
* output stream.
* This method allows to write a generic list of String objects to the output stream.
*
* @param v the List object to write
* @param os the stream to write the object to
......@@ -572,18 +603,17 @@ public final class StreamUtil {
}
/**
* This method allows to restore a vector of String objects from the
* input stream.
* This method allows to restore a vector of String objects from the input stream.
*
* @param is the stream to read data from in order to restore the object
* @return the Vector object or null
* @throws IOException an error occurs during IO operation.
*/
public static Vector readVectorOfStringFrom(InputStream is) throws IOException {
public static Vector<String> readVectorOfStringFrom(InputStream is) throws IOException {
int size = readIntFrom(is);
if (size == -1) return null;
Vector v = new Vector(size);
Vector<String> v = new Vector<String>(size);
for (int i=0; i<size; i++) {
v.addElement(readStringFrom(is));
}
......@@ -591,19 +621,18 @@ public final class StreamUtil {
}
/**
* This method allows to restore a list of String objects from the
* input stream.
* This method allows to restore a list of String objects from the input stream.
*
* @param is the stream to read data from in order to restore the object
* @return the ArrayList object or null
* @throws IOException an error occurs during IO operation.
*/
public static ArrayList readArrayListOfStringFrom(InputStream is) throws IOException {
public static ArrayList<String> readArrayListOfStringFrom(InputStream is) throws IOException {
int size = readIntFrom(is);
if (size == -1)
return null;
ArrayList v = new ArrayList(size);
ArrayList<String> v = new ArrayList<String>(size);
for (int i = 0; i < size; i++) {
v.add(readStringFrom(is));
}
......@@ -768,6 +797,11 @@ public final class StreamUtil {
return prop;
}
// ############################################################
// Code allowing to implements Encodable interface for Properties
// TODO (AF): Should be in Properties.
// ############################################################
public static int getEncodedSize(Object obj) throws IOException {
int size = 0;
if (obj == null) {
......@@ -837,19 +871,19 @@ public final class StreamUtil {
case NULL:
return null;
case BOOLEAN:
return new Boolean(decoder.decodeBoolean());
return Boolean.valueOf(decoder.decodeBoolean());
case BYTE:
return new Byte(decoder.decodeByte());
return Byte.valueOf(decoder.decodeByte());
case SHORT:
return new Short(decoder.decodeSignedShort());
return Short.valueOf(decoder.decodeSignedShort());
case INT:
return new Integer(decoder.decodeSignedInt());
return Integer.valueOf(decoder.decodeSignedInt());
case LONG:
return new Long(decoder.decodeSignedLong());
return Long.valueOf(decoder.decodeSignedLong());
case FLOAT:
return new Float(decoder.decodeFloat());
return Float.valueOf(decoder.decodeFloat());
case DOUBLE:
return new Double(decoder.decodeDouble());
return Double.valueOf(decoder.decodeDouble());
case STRING:
return decoder.decodeString();
case BYTEARRAY:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment