Permalink
Browse files

Fix for supporting BSON user defined binary

The default BSON binary predicate, reader and writer classes defined in
Default{Predicate,Reader,Writer} respectively didn't support predicates,
readers and writers registered via BsonBinary.USER. Now it does.

I added a test case to demonstrate this to the DefaultBinaryReaderWriterTest.
  • Loading branch information...
1 parent c1b154f commit 1c923a3bf5efa014625cca09e56146f1509134bf @kohanyirobert committed Nov 14, 2012
@@ -54,8 +54,13 @@ public boolean apply(Class<?> input) {
BINARY {
@Override
- public boolean apply(Class<?> input) {
- return GENERIC.apply(input);
+ public boolean apply(final Class<?> input) {
+ for (BsonBinary binary : BsonBinary.values()) {
+ if (binary.predicate().apply(input)) {
+ return true;
+ }
+ }
+ return false;
}
},
@@ -94,7 +94,7 @@ public Object checkedReadFrom(ByteBuffer buffer) {
BsonBinary bsonBinary = BsonBinary.find(terminal);
int oldLimit = buffer.limit();
buffer.limit(buffer.position() + binaryLength);
- byte[] binary = (byte[]) bsonBinary.reader().readFrom(buffer);
+ Object binary = bsonBinary.reader().readFrom(buffer);
buffer.limit(oldLimit);
return binary;
}
@@ -90,11 +90,12 @@ public void writeTo(ByteBuffer buffer, Object reference) {
@Override
public void writeTo(ByteBuffer buffer, Object reference) {
- byte[] binary = (byte[]) reference;
- buffer.putInt(binary.length);
- BsonBinary bsonBinary = BsonBinary.find(binary.getClass());
+ int markedPosition = buffer.position();
+ buffer.position(markedPosition + Ints.BYTES);
+ BsonBinary bsonBinary = BsonBinary.find(reference.getClass());
buffer.put(bsonBinary.terminal());
- bsonBinary.writer().writeTo(buffer, binary);
+ bsonBinary.writer().writeTo(buffer, reference);
+ buffer.putInt(markedPosition, buffer.position() - markedPosition - Ints.BYTES - 1);
}
},
@@ -1,12 +1,21 @@
package com.github.kohanyirobert.ebson;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
import org.junit.Test;
+import java.nio.ByteBuffer;
+
+import javax.annotation.Nullable;
+
public final class DefaultBinaryReaderWriterTest extends AbstractReaderWriterTest {
private static final int BINARY_LENGTH = 1024;
+
private static final ThreadLocal<byte[]> RANDOM_BINARY = new ThreadLocal<byte[]>() {
@Override
@@ -22,7 +31,88 @@ public DefaultBinaryReaderWriterTest() {
}
@Test
- public void primitiveBytes() {
+ public void randomByteArray() {
assertArrayEquals((byte[]) writeTo(RANDOM_BINARY.get()), (byte[]) readFrom());
}
+
+ @Test
+ public void customUserObject() {
+ BsonBinary.USER.predicate(new UserPredicate());
+ BsonBinary.USER.reader(new UserReader());
+ BsonBinary.USER.writer(new UserWriter());
+
+ assertEquals(writeTo(new User("Ford", 42)), readFrom());
+ }
+
+ private static final class UserPredicate implements Predicate<Class<?>> {
+
+ public UserPredicate() {}
+
+ @Override
+ public boolean apply(@Nullable Class<?> input) {
+ return input == null
+ ? false
+ : User.class.isAssignableFrom(input);
+ }
+ }
+
+ private static final class UserReader implements BsonReader {
+
+ public UserReader() {}
+
+ @Override
+ @Nullable
+ public Object readFrom(ByteBuffer buffer) {
+ Object name = BsonObject.STRING.reader().readFrom(buffer);
+ Object age = BsonObject.INT32.reader().readFrom(buffer);
+ return new User((String) name, ((Integer) age).intValue());
+ }
+ }
+
+ private static final class UserWriter implements BsonWriter {
+
+ public UserWriter() {}
+
+ @Override
+ public void writeTo(ByteBuffer buffer, @Nullable Object reference) {
+ User user = (User) reference;
+ BsonObject.STRING.writer().writeTo(buffer, user.getName());
+ BsonObject.INT32.writer().writeTo(buffer, Integer.valueOf(user.getAge()));
+ }
+ }
+
+ private static final class User {
+
+ private final String name;
+ private final int age;
+
+ public User(String name, int age) {
+ this.name = Preconditions.checkNotNull(name);
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 17;
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object instanceof User) {
+ User other = (User) object;
+ return getName().equals(other.getName())
+ && getAge() == other.getAge();
+ }
+ return false;
+ }
+ }
}

0 comments on commit 1c923a3

Please sign in to comment.