소스 검색

Merge pull request #102 from fizbin/bytestring_serializable

Make ByteStrings serializable with java serialization.
Feng Xiao 11 년 전
부모
커밋
7f2a9fb1af

+ 17 - 0
java/src/main/java/com/google/protobuf/BoundedByteString.java

@@ -30,6 +30,9 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import java.io.InvalidObjectException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.util.NoSuchElementException;
 import java.util.NoSuchElementException;
 
 
 /**
 /**
@@ -122,6 +125,20 @@ class BoundedByteString extends LiteralByteString {
         targetOffset, numberToCopy);
         targetOffset, numberToCopy);
   }
   }
 
 
+  // =================================================================
+  // Serializable
+
+  private static final long serialVersionUID = 1L;
+
+  Object writeReplace() {
+    return new LiteralByteString(toByteArray());
+  }
+
+  private void readObject(ObjectInputStream in) throws IOException {
+    throw new InvalidObjectException(
+        "BoundedByteStream instances are not to be serialized directly");
+  }
+
   // =================================================================
   // =================================================================
   // ByteIterator
   // ByteIterator
 
 

+ 2 - 1
java/src/main/java/com/google/protobuf/ByteString.java

@@ -34,6 +34,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStream;
+import java.io.Serializable;
 import java.io.UnsupportedEncodingException;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -57,7 +58,7 @@ import java.util.NoSuchElementException;
  * @author carlanton@google.com Carl Haverl
  * @author carlanton@google.com Carl Haverl
  * @author martinrb@google.com Martin Buchholz
  * @author martinrb@google.com Martin Buchholz
  */
  */
-public abstract class ByteString implements Iterable<Byte> {
+public abstract class ByteString implements Iterable<Byte>, Serializable {
 
 
   /**
   /**
    * When two strings to be concatenated have a combined length shorter than
    * When two strings to be concatenated have a combined length shorter than

+ 2 - 0
java/src/main/java/com/google/protobuf/LiteralByteString.java

@@ -51,6 +51,8 @@ import java.util.NoSuchElementException;
  */
  */
 class LiteralByteString extends ByteString {
 class LiteralByteString extends ByteString {
 
 
+  private static final long serialVersionUID = 1L;
+
   protected final byte[] bytes;
   protected final byte[] bytes;
 
 
   /**
   /**

+ 16 - 0
java/src/main/java/com/google/protobuf/RopeByteString.java

@@ -30,8 +30,10 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import java.io.InvalidObjectException;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
+import java.io.ObjectInputStream;
 import java.io.OutputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.io.UnsupportedEncodingException;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayInputStream;
@@ -771,6 +773,20 @@ class RopeByteString extends ByteString {
     }
     }
   }
   }
 
 
+  // =================================================================
+  // Serializable
+
+  private static final long serialVersionUID = 1L;
+
+  Object writeReplace() {
+    return new LiteralByteString(toByteArray());
+  }
+
+  private void readObject(ObjectInputStream in) throws IOException {
+    throw new InvalidObjectException(
+        "RopeByteStream instances are not to be serialized directly");
+  }
+
   // =================================================================
   // =================================================================
   // ByteIterator
   // ByteIterator
 
 

+ 19 - 0
java/src/test/java/com/google/protobuf/BoundedByteStringTest.java

@@ -30,8 +30,14 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.io.UnsupportedEncodingException;
 
 
+
 /**
 /**
  * This class tests {@link BoundedByteString}, which extends {@link LiteralByteString},
  * This class tests {@link BoundedByteString}, which extends {@link LiteralByteString},
  * by inheriting the tests from {@link LiteralByteStringTest}.  The only method which
  * by inheriting the tests from {@link LiteralByteStringTest}.  The only method which
@@ -65,4 +71,17 @@ public class BoundedByteStringTest extends LiteralByteStringTest {
     assertEquals(classUnderTest + " unicode bytes must match",
     assertEquals(classUnderTest + " unicode bytes must match",
         testString.substring(2, testString.length() - 6), roundTripString);
         testString.substring(2, testString.length() - 6), roundTripString);
   }
   }
+
+  public void testJavaSerialization() throws Exception {
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    ObjectOutputStream oos = new ObjectOutputStream(out);
+    oos.writeObject(stringUnderTest);
+    oos.close();
+    byte[] pickled = out.toByteArray();
+    InputStream in = new ByteArrayInputStream(pickled);
+    ObjectInputStream ois = new ObjectInputStream(in);
+    Object o = ois.readObject();
+    assertTrue("Didn't get a ByteString back", o instanceof ByteString);
+    assertEquals("Should get an equal ByteString back", stringUnderTest, o);
+  }
 }
 }

+ 16 - 0
java/src/test/java/com/google/protobuf/LiteralByteStringTest.java

@@ -32,9 +32,12 @@ package com.google.protobuf;
 
 
 import junit.framework.TestCase;
 import junit.framework.TestCase;
 
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
@@ -393,4 +396,17 @@ public class LiteralByteStringTest extends TestCase {
     assertSame("empty concatenated with " + classUnderTest + " must give " + classUnderTest,
     assertSame("empty concatenated with " + classUnderTest + " must give " + classUnderTest,
         ByteString.EMPTY.concat(stringUnderTest), stringUnderTest);
         ByteString.EMPTY.concat(stringUnderTest), stringUnderTest);
   }
   }
+
+  public void testJavaSerialization() throws Exception {
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    ObjectOutputStream oos = new ObjectOutputStream(out);
+    oos.writeObject(stringUnderTest);
+    oos.close();
+    byte[] pickled = out.toByteArray();
+    InputStream in = new ByteArrayInputStream(pickled);
+    ObjectInputStream ois = new ObjectInputStream(in);
+    Object o = ois.readObject();
+    assertTrue("Didn't get a ByteString back", o instanceof ByteString);
+    assertEquals("Should get an equal ByteString back", stringUnderTest, o);
+  }
 }
 }

+ 18 - 0
java/src/test/java/com/google/protobuf/RopeByteStringTest.java

@@ -30,6 +30,11 @@
 
 
 package com.google.protobuf;
 package com.google.protobuf;
 
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.io.UnsupportedEncodingException;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.Iterator;
@@ -112,4 +117,17 @@ public class RopeByteStringTest extends LiteralByteStringTest {
     assertEquals(classUnderTest + " string must must have same hashCode as the flat string",
     assertEquals(classUnderTest + " string must must have same hashCode as the flat string",
         flatString.hashCode(), unicode.hashCode());
         flatString.hashCode(), unicode.hashCode());
   }
   }
+
+  public void testJavaSerialization() throws Exception {
+    ByteArrayOutputStream out = new ByteArrayOutputStream();
+    ObjectOutputStream oos = new ObjectOutputStream(out);
+    oos.writeObject(stringUnderTest);
+    oos.close();
+    byte[] pickled = out.toByteArray();
+    InputStream in = new ByteArrayInputStream(pickled);
+    ObjectInputStream ois = new ObjectInputStream(in);
+    Object o = ois.readObject();
+    assertTrue("Didn't get a ByteString back", o instanceof ByteString);
+    assertEquals("Should get an equal ByteString back", stringUnderTest, o);
+  }
 }
 }