blob: 9f163a229252ffc7cc0f9c3ec8dd55c40b3e77ed [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.impl.google.rpc;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import io.v.impl.google.ListenableFutureCallback;
import io.v.v23.VFutures;
import io.v.v23.context.VContext;
import io.v.v23.rpc.Callback;
import io.v.v23.rpc.ClientCall;
import io.v.v23.rpc.Stream;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;
import java.lang.reflect.Type;
public class ClientCallImpl implements ClientCall {
private final VContext ctx;
private final long nativeRef;
private final Stream stream;
private native void nativeCloseSend(long nativeRef, Callback<Void> callback);
private native void nativeFinish(long nativeRef, int numResults, Callback<byte[][]> callback);
private native void nativeFinalize(long nativeRef);
private ClientCallImpl(VContext ctx, long nativeRef, Stream stream) {
this.ctx = ctx;
this.nativeRef = nativeRef;
this.stream = stream;
}
@Override
public ListenableFuture<Void> send(Object item, Type type) {
return stream.send(item, type);
}
@Override
public ListenableFuture<Object> recv(Type type) {
return stream.recv(type);
}
@Override
public ListenableFuture<Void> closeSend() {
ListenableFutureCallback<Void> callback = new ListenableFutureCallback<>();
nativeCloseSend(nativeRef, callback);
return callback.getFuture(ctx);
}
@Override
public ListenableFuture<Object[]> finish(final Type[] types) {
ListenableFutureCallback<byte[][]> callback = new ListenableFutureCallback<>();
nativeFinish(nativeRef, types.length, callback);
return VFutures.withUserLandChecks(ctx,
Futures.transform(callback.getVanillaFuture(),
new AsyncFunction<byte[][], Object[]>() {
@Override
public ListenableFuture<Object[]> apply(byte[][] vomResults) throws Exception {
if (vomResults.length != types.length) {
throw new VException(String.format(
"Mismatch in number of results, want %s, have %s",
types.length, vomResults.length));
}
// VOM-decode results.
Object[] ret = new Object[types.length];
for (int i = 0; i < types.length; i++) {
ret[i] = VomUtil.decode(vomResults[i], types[i]);
}
return Futures.immediateFuture(ret);
}
}));
}
@Override
protected void finalize() {
nativeFinalize(nativeRef);
}
}