Avi-Levi / kryo

Automatically exported from code.google.com/p/kryo
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Make input.java not compact if no stream is available (with patch) #89

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create an Input over a fixed array.
2. Read from it until it's exhausted.
3. Recreate the input over the same array and read again.

What is the expected output? What do you see instead?

I expect to be able to read it again.

What happens is that the optional() or require() calls as the buffer becomes 
exhausted, so the last byte(s) of the buffer are copied to the start. However, 
there's no point compacting if there's no stream, as there will never be any 
more data.

The only workaround is to memdup the array before handing it to kryo, but this 
can cost an extra 20Mb for really no reason.

What version of the Kryo are you using?

svn rev 341

Please provide any additional information below.

--- src/com/esotericsoftware/kryo/io/Input.java (revision 341)
+++ src/com/esotericsoftware/kryo/io/Input.java (working copy)
@@ -149,7 +149,7 @@
                int remaining = limit - position;
                if (remaining >= required) return remaining;
                if (required > capacity) throw new KryoException("Buffer too small: capacity: " + capacity + ", required: " + required);
-
+               if (inputStream == null) throw new KryoException("Buffer 
underflow, with no InputStream");
                // Compact.
                System.arraycopy(buffer, position, buffer, 0, remaining);
                total += position;
@@ -174,6 +174,7 @@
                int remaining = limit - position;
                if (remaining >= optional) return optional;
                optional = Math.min(optional, capacity);
+               if (inputStream != null) {

                // Compact.
                System.arraycopy(buffer, position, buffer, 0, remaining);
@@ -187,6 +188,7 @@
                        if (remaining >= optional) break; // Enough has been read.
                }
                limit = remaining;
+               }
                return remaining == 0 ? -1 : Math.min(remaining, optional);
        }

Original issue reported on code.google.com by shevek.h...@googlemail.com on 10 Sep 2012 at 4:17

GoogleCodeExporter commented 9 years ago
The proposed patch doesn't quite work in the case where fill() is being 
overridden to provide more bytes. I've changed Input to attempt to fill the 
buffer first, if not enough was read and not EOS, only then does it compact. 
This should fix your issue and also avoid compacting in other cases.

Original comment by nathan.s...@gmail.com on 4 Dec 2012 at 12:22