# nikiroo-utils
+## Version 4.5.0
+
+- Base64: allow access to streams
+- Deprecated: do not use our on deprecated functions
+- Serial: fix ZIP/noZIP error
+
## Version 4.4.5
- Base64: allow access to not-zipped Base64 utilities
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@Deprecated
public static String zip64(String data) {
try {
- return Base64.encodeBytes(data.getBytes(), Base64.GZIP);
+ return Base64.encodeBytes(data.getBytes("UTF-8"), Base64.GZIP);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
+ /**
+ * Convert the given data to Base64 format.
+ *
+ * @param data
+ * the data to convert
+ * @param zip
+ * TRUE to also compress the data in GZIP format; remember that
+ * compressed and not-compressed content are different; you need
+ * to know which is which when decoding
+ *
+ * @return the Base64 {@link String} representation of the data
+ *
+ * @throws IOException
+ * in case of I/O errors
+ */
+ public static String base64(String data, boolean zip) throws IOException {
+ return base64(data.getBytes("UTF-8"), zip);
+ }
+
/**
* Convert the given data to Base64 format.
*
}
/**
- * Unonvert the given data from Base64 format back to a raw array of bytes.
+ * Convert the given data to Base64 format.
+ *
+ * @param data
+ * the data to convert
+ * @param zip
+ * TRUE to also uncompress the data from a GZIP format; take care
+ * about this flag, as it could easily cause errors in the
+ * returned content or an {@link IOException}
+ * @param breakLines
+ * TRUE to break lines on every 76th character
+ *
+ * @return the Base64 {@link String} representation of the data
+ *
+ * @throws IOException
+ * in case of I/O errors
+ */
+ public static OutputStream base64(OutputStream data, boolean zip,
+ boolean breakLines) throws IOException {
+ OutputStream out = new Base64.OutputStream(data,
+ breakLines ? Base64.DO_BREAK_LINES & Base64.ENCODE
+ : Base64.ENCODE);
+
+ if (zip) {
+ out = new java.util.zip.GZIPOutputStream(out);
+ }
+
+ return out;
+ }
+
+ /**
+ * Convert the given data to Base64 format.
+ *
+ * @param data
+ * the data to convert
+ * @param zip
+ * TRUE to also uncompress the data from a GZIP format; take care
+ * about this flag, as it could easily cause errors in the
+ * returned content or an {@link IOException}
+ * @param breakLines
+ * TRUE to break lines on every 76th character
+ *
+ * @return the Base64 {@link String} representation of the data
+ *
+ * @throws IOException
+ * in case of I/O errors
+ */
+ public static InputStream base64(InputStream data, boolean zip,
+ boolean breakLines) throws IOException {
+ if (zip) {
+ data = new java.util.zip.GZIPInputStream(data);
+ }
+
+ return new Base64.InputStream(data, breakLines ? Base64.DO_BREAK_LINES
+ & Base64.ENCODE : Base64.ENCODE);
+ }
+
+ /**
+ * Unconvert the given data from Base64 format back to a raw array of bytes.
*
* @param data
* the data to unconvert
return Base64.decode(data, zip ? Base64.GZIP : Base64.NO_OPTIONS);
}
+ /**
+ * Unconvert the given data from Base64 format back to a raw array of bytes.
+ *
+ * @param data
+ * the data to unconvert
+ * @param zip
+ * TRUE to also uncompress the data from a GZIP format; take care
+ * about this flag, as it could easily cause errors in the
+ * returned content or an {@link IOException}
+ * @param breakLines
+ * TRUE to break lines on every 76th character
+ *
+ * @return the raw data represented by the given Base64 {@link String}
+ *
+ * @throws IOException
+ * in case of I/O errors
+ */
+ public static OutputStream unbase64(OutputStream data, boolean zip,
+ boolean breakLines) throws IOException {
+ OutputStream out = new Base64.OutputStream(data,
+ breakLines ? Base64.DO_BREAK_LINES & Base64.ENCODE
+ : Base64.ENCODE);
+
+ if (zip) {
+ out = new java.util.zip.GZIPOutputStream(out);
+ }
+
+ return out;
+ }
+
+ /**
+ * Unconvert the given data from Base64 format back to a raw array of bytes.
+ *
+ * @param data
+ * the data to unconvert
+ * @param zip
+ * TRUE to also uncompress the data from a GZIP format; take care
+ * about this flag, as it could easily cause errors in the
+ * returned content or an {@link IOException}
+ * @param breakLines
+ * TRUE to break lines on every 76th character
+ *
+ * @return the raw data represented by the given Base64 {@link String}
+ *
+ * @throws IOException
+ * in case of I/O errors
+ */
+ public static InputStream unbase64(InputStream data, boolean zip,
+ boolean breakLines) throws IOException {
+ if (zip) {
+ data = new java.util.zip.GZIPInputStream(data);
+ }
+
+ return new Base64.InputStream(data, breakLines ? Base64.DO_BREAK_LINES
+ & Base64.ENCODE : Base64.ENCODE);
+ }
+
/**
* Unonvert the given data from Base64 format back to a {@link String}.
*
public static String unbase64s(String data, boolean zip) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(unbase64(data, zip));
- Scanner scan = new Scanner(in);
+ Scanner scan = new Scanner(in, "UTF-8");
scan.useDelimiter("\\A");
try {
return scan.next();
package be.nikiroo.utils.serial;
+import java.io.IOException;
import java.io.NotSerializableException;
import java.util.HashMap;
import java.util.Map;
map.clear();
}
+ /**
+ * Append the exported items in a serialised form into the given
+ * {@link StringBuilder}.
+ *
+ * @param toBuilder
+ * the {@link StringBuilder}
+ * @param b64
+ * TRUE to have BASE64-coded content, FALSE to have raw content,
+ * NULL to let the system decide
+ * @param zip
+ * TRUE to zip the BASE64 output if the output is indeed in
+ * BASE64 format, FALSE not to
+ */
+ public void appendTo(StringBuilder toBuilder, Boolean b64, boolean zip) {
+ if (b64 == null && builder.length() < 128) {
+ b64 = false;
+ }
+
+ if (b64 != null || b64) {
+ try {
+ String zipped = StringUtils.base64(builder.toString(), zip);
+ if (b64 != null || zipped.length() < builder.length() - 4) {
+ toBuilder.append(zip ? "ZIP:" : "B64:");
+ toBuilder.append(zipped);
+ return;
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Base64 conversion of data failed, maybe not enough memory?",
+ e);
+ }
+ }
+
+ toBuilder.append(builder);
+ }
+
/**
* The exported items in a serialised form.
*
+ * @deprecated use {@link Exporter#toString(Boolean, boolean)} instead
+ *
* @param zip
* TRUE to have zipped (and BASE64-coded) content, FALSE to have
* raw content, NULL to let the system decide
*
* @return the items currently in this {@link Exporter}
*/
+ @Deprecated
public String toString(Boolean zip) {
- if (zip == null && builder.length() > 128) {
- zip = false;
- }
-
- if (zip == null || zip) {
- String zipped = "ZIP:" + StringUtils.zip64(builder.toString());
-
- if (zip != null || builder.length() < zipped.length())
- return zipped;
- }
+ return toString(zip, zip == null || zip);
+ }
- return builder.toString();
+ /**
+ * The exported items in a serialised form.
+ *
+ * @param b64
+ * TRUE to have BASE64-coded content, FALSE to have raw content,
+ * NULL to let the system decide
+ * @param zip
+ * TRUE to zip the BASE64 output if the output is indeed in
+ * BASE64 format, FALSE not to
+ *
+ * @return the items currently in this {@link Exporter}
+ */
+ public String toString(Boolean b64, boolean zip) {
+ StringBuilder toBuilder = new StringBuilder();
+ appendTo(toBuilder, b64, zip);
+ return toBuilder.toString();
}
/**
- * The exported items in a serialised form (possibly zipped).
+ * The exported items in a serialised form (possibly BASE64-coded, possibly
+ * zipped).
*
* @return the items currently in this {@link Exporter}
*/
@Override
public String toString() {
- return toString(null);
+ return toString(null, true);
}
}
\ No newline at end of file
if (line.startsWith("ZIP:")) {
try {
- line = StringUtils.unzip64(line.substring("ZIP:"
- .length()));
+ line = StringUtils.unbase64s(
+ line.substring("ZIP:".length()), true);
} catch (IOException e) {
throw new IOException(
"Internal error when decoding ZIP content: input may be corrupt");
}
read(line);
+ } else if (line.startsWith("B64:")) {
+ try {
+ line = StringUtils.unbase64s(
+ line.substring("B64:".length()), false);
+ } catch (IOException e) {
+ throw new IOException(
+ "Internal error when decoding B64 content: input may be corrupt");
+ }
+ read(line);
} else {
processLine(line);
}
if (!SerialUtils.encode(builder, item)) {
try {
// use ZIP: if not
- builder.append(new Exporter().append(item)
- .toString(true));
+ new Exporter().append(item).appendTo(builder,
+ true, false);
} catch (NotSerializableException e) {
throw new UnknownFormatConversionException(e
.getMessage());
protected Object sendObject(Object data) throws IOException,
NoSuchFieldException, NoSuchMethodException, ClassNotFoundException {
synchronized (lock) {
- String rep = sendString(new Exporter().append(data).toString(true));
+ String rep = sendString(new Exporter().append(data).toString(true,
+ true));
if (rep != null) {
return new Importer().read(rep).getValue();
}
if (getTraceHandler().getTraceLevel() >= 2) {
try {
- if (data.startsWith("ZIP:")) {
- data = StringUtils.unzip64(data.substring(4));
+ while (data.startsWith("ZIP:") || data.startsWith("B64:")) {
+ if (data.startsWith("ZIP:")) {
+ data = StringUtils.unbase64s(data.substring(4), true);
+ } else if (data.startsWith("B64:")) {
+ data = StringUtils.unbase64s(data.substring(4), false);
+ }
}
Object obj = new Importer().read(data).getValue();
@Override
public void test() throws Exception {
String orig = "test";
- String zipped = StringUtils.zip64(orig);
- String unzipped = StringUtils.unzip64(zipped);
+ String zipped = StringUtils.base64(orig, true);
+ String unzipped = StringUtils.unbase64s(zipped, true);
assertEquals(orig, unzipped);
}
});