Skip to content

Commit

Permalink
Add methods to serialize cursors
Browse files Browse the repository at this point in the history
  • Loading branch information
alexjg committed Jan 17, 2024
1 parent c70bdd6 commit ef13fbb
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 5 deletions.
6 changes: 6 additions & 0 deletions lib/src/main/java/org/automerge/AutomergeSys.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,12 @@ public static native long lookupCursorIndexInDoc(DocPointer doc, ObjectId obj, C
public static native long lookupCursorIndexInTx(TransactionPointer tx, ObjectId obj, Cursor cursor,
Optional<ChangeHash[]> heads);

public static native String cursorToString(Cursor cursor);

public static native Cursor cursorFromString(String encoded);

public static native Cursor cursorFromBytes(byte[] encoded);

public static native Optional<ObjectType> getObjectTypeInDoc(DocPointer doc, ObjectId obj);

public static native Optional<ObjectType> getObjectTypeInTx(TransactionPointer tx, ObjectId obj);
Expand Down
17 changes: 17 additions & 0 deletions lib/src/main/java/org/automerge/Cursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,21 @@

public class Cursor {
private byte[] raw;

public static Cursor fromBytes(byte[] encoded) {
return AutomergeSys.cursorFromBytes(encoded);
}

public static Cursor fromString(String encoded) {
return AutomergeSys.cursorFromString(encoded);
}

@Override
public String toString() {
return AutomergeSys.cursorToString(this);
}

public byte[] toBytes() {
return raw.clone();
}
}
24 changes: 24 additions & 0 deletions lib/src/test/java/org/automerge/TestCursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,28 @@ public void testCursorInTx() {
tx.commit();
}
}

@Test
public void testToFromString() {
Cursor cursor = doc.makeCursor(text, 3);
String encoded = cursor.toString();
Cursor decoded = Cursor.fromString(encoded);
Assertions.assertEquals(doc.lookupCursorIndex(text, decoded), 3);

Assertions.assertThrows(IllegalArgumentException.class, () -> {
Cursor.fromString("invalid");
});
}

@Test
public void testToFromBytes() {
Cursor cursor = doc.makeCursor(text, 3);
byte[] encoded = cursor.toBytes();
Cursor decoded = Cursor.fromBytes(encoded);
Assertions.assertEquals(doc.lookupCursorIndex(text, decoded), 3);

Assertions.assertThrows(IllegalArgumentException.class, () -> {
Cursor.fromBytes(new byte[] { 0x01, 0x01 });
});
}
}
35 changes: 30 additions & 5 deletions rust/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use jni::{
JNIEnv,
};

use crate::AUTOMERGE_EXCEPTION;

#[derive(Debug)]
pub struct Cursor(automerge::Cursor);

Expand Down Expand Up @@ -85,12 +83,39 @@ pub unsafe extern "C" fn cursorFromString(
) -> jobject {
let s = env.get_string(JString::from_raw(s)).unwrap();
let Ok(s) = s.to_str() else {
env.throw_new(AUTOMERGE_EXCEPTION, "invalid cursor string")
.unwrap();
env.throw_new(
"java/lang/IllegalArgumentException",
"invalid cursor string",
)
.unwrap();
return JObject::null().into_raw();
};
let Ok(cursor) = automerge::Cursor::try_from(s) else {
env.throw_new(AUTOMERGE_EXCEPTION, "invalid cursor string")
env.throw_new(
"java/lang/IllegalArgumentException",
"invalid cursor string",
)
.unwrap();
return JObject::null().into_raw();
};
Cursor::from(cursor).into_raw(&env).unwrap()
}

#[no_mangle]
#[jni_fn]
pub unsafe extern "C" fn cursorFromBytes(
env: jni::JNIEnv,
_class: jni::objects::JClass,
bytes: jni::sys::jbyteArray,
) -> jobject {
let bytes = env
.get_byte_array_elements(bytes, jni::objects::ReleaseMode::NoCopyBack)
.unwrap();
let bytes =
std::slice::from_raw_parts(bytes.as_ptr() as *const u8, bytes.size().unwrap() as usize);
let Ok(cursor) = automerge::Cursor::try_from(bytes) else {
// throw IllegalArgumentException
env.throw_new("java/lang/IllegalArgumentException", "invalid cursor bytes")
.unwrap();
return JObject::null().into_raw();
};
Expand Down

0 comments on commit ef13fbb

Please sign in to comment.