This is an automated email from the git hooks/post-receive script.
sparks pushed a commit to branch master
in repository defensive-coding-guide.
commit 8512082515dfdd71a3a45627d4dd3b61fa84290b
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Fri Jul 5 11:07:13 2013 +0200
Java: Add note on reading arrays
---
defensive-coding/en-US/Java/Language.xml | 33 +++++++++++++
.../en-US/Java/snippets/Language-ReadArray.xml | 39 +++++++++++++++
defensive-coding/src/JavaReadArray.java | 55 ++++++++++++++++++++++
defensive-coding/src/src.mk | 1 +
4 files changed, 128 insertions(+)
diff --git a/defensive-coding/en-US/Java/Language.xml
b/defensive-coding/en-US/Java/Language.xml
index edea9a4..e47df99 100644
--- a/defensive-coding/en-US/Java/Language.xml
+++ b/defensive-coding/en-US/Java/Language.xml
@@ -11,6 +11,34 @@
<xref linkend="sect-Defensive_Coding-Java-LowLevel"/>.
</para>
+ <section id="sect-Defensive_Coding-Java-Language-ReadArray">
+ <title>Inceasing robustness when reading arrays</title>
+ <para>
+ External data formats often include arrays, and the data is
+ stored as an integer indicating the number of array elements,
+ followed by this number of elements in the file or protocol data
+ unit. This length specified can be much larger than what is
+ actually available in the data source.
+ </para>
+ <para>
+ To avoid allocating extremely large amounts of data, you can
+ allocate a small array initially and grow it as you read more
+ data, implementing an exponential growth policy. See the
+ <function>readBytes(InputStream, int)</function> function in
+ <xref linkend="ex-Defensive_Coding-Java-Language-ReadArray"/>.
+ </para>
+ <example id="ex-Defensive_Coding-Java-Language-ReadArray">
+ <title>Incrementally reading a byte array</title>
+ <xi:include href="snippets/Language-ReadArray.xml"
+
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ </example>
+ <para>
+ When reading data into arrays, hash maps or hash sets, use the
+ default constructor and do not specify a size hint. You can
+ simply add the elements to the collection as you read them.
+ </para>
+ </section>
+
<section id="sect-Defensive_Coding-Java-Language-Resources">
<title>Resource management</title>
<para>
@@ -234,6 +262,11 @@
greater problems.
</para>
<para>
+ Code should be written in a way that avoids triggering errors.
+ See <xref linkend="sect-Defensive_Coding-Java-Language-ReadArray"/>
+ for an example.
+ </para>
+ <para>
It is usually necessary to log errors. Otherwise, no trace of
the problem might be left anywhere, making it very difficult
to diagnose realted failures. Consequently, if you catch
diff --git a/defensive-coding/en-US/Java/snippets/Language-ReadArray.xml
b/defensive-coding/en-US/Java/snippets/Language-ReadArray.xml
new file mode 100644
index 0000000..1470795
--- /dev/null
+++ b/defensive-coding/en-US/Java/snippets/Language-ReadArray.xml
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE programlisting PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+]>
+<!-- Automatically generated file. Do not edit. -->
+<programlisting language="Java">
+static byte[] readBytes(InputStream in, int length) throws IOException {
+ final int startSize = 65536;
+ byte[] b = new byte[Math.min(length, startSize)];
+ int filled = 0;
+ while (true) {
+ int remaining = b.length - filled;
+ readFully(in, b, filled, remaining);
+ if (b.length == length) {
+ break;
+ }
+ filled = b.length;
+ if (length - b.length <= b.length) {
+ // Allocate final length. Condition avoids overflow.
+ b = Arrays.copyOf(b, length);
+ } else {
+ b = Arrays.copyOf(b, b.length * 2);
+ }
+ }
+ return b;
+}
+
+static void readFully(InputStream in,byte[] b, int off, int len)
+ throws IOException {
+ int startlen = len;
+ while (len > 0) {
+ int count = in.read(b, off, len);
+ if (count < 0) {
+ throw new EOFException();
+ }
+ off += count;
+ len -= count;
+ }
+}
+</programlisting>
diff --git a/defensive-coding/src/JavaReadArray.java
b/defensive-coding/src/JavaReadArray.java
new file mode 100644
index 0000000..06cba15
--- /dev/null
+++ b/defensive-coding/src/JavaReadArray.java
@@ -0,0 +1,55 @@
+import java.io.EOFException;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.util.Arrays;
+
+public class JavaReadArray {
+ public static void main(String[] args) throws IOException {
+ String path = args[0];
+ int length = Integer.parseInt(args[1]);
+
+ byte[] data;
+ try (InputStream in = new FileInputStream(path)) {
+ data = readBytes(in, length);
+ }
+ System.out.write(data);
+ }
+
+ //+ Java Language-ReadArray
+ static byte[] readBytes(InputStream in, int length) throws IOException {
+ final int startSize = 65536;
+ byte[] b = new byte[Math.min(length, startSize)];
+ int filled = 0;
+ while (true) {
+ int remaining = b.length - filled;
+ readFully(in, b, filled, remaining);
+ if (b.length == length) {
+ break;
+ }
+ filled = b.length;
+ if (length - b.length <= b.length) {
+ // Allocate final length. Condition avoids overflow.
+ b = Arrays.copyOf(b, length);
+ } else {
+ b = Arrays.copyOf(b, b.length * 2);
+ }
+ }
+ return b;
+ }
+
+ static void readFully(InputStream in,byte[] b, int off, int len)
+ throws IOException {
+ int startlen = len;
+ while (len > 0) {
+ int count = in.read(b, off, len);
+ if (count < 0) {
+ throw new EOFException();
+ }
+ off += count;
+ len -= count;
+ }
+ }
+ //-
+}
diff --git a/defensive-coding/src/src.mk b/defensive-coding/src/src.mk
index c916d01..219e70b 100644
--- a/defensive-coding/src/src.mk
+++ b/defensive-coding/src/src.mk
@@ -19,6 +19,7 @@ CFLAGS_Java-JNI-Pointers = \
# List Java files which sould be compiled
compile_java += JavaFinally
+compile_java += JavaReadArray
compile_java += JavaSecurityManagerUnprivileged
compile_java += JavaSecurityManagerPrivileged
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.