Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,31 @@ import io.kaitai.struct.KaitaiStruct

/**
* Serialize a Kaitai struct to a byte array.
*
* Kaitai's [ByteBufferKaitaiStream] is fixed-capacity, so the underlying
* `ByteBuffer.put` throws [java.nio.BufferOverflowException] if the
* pre-allocated buffer is too small. We don't have a cheap way to know
* the encoded size up front, so start at 16 KiB and double on overflow
* until the message fits or we cross [MAX_BUFFER]. Most SSH messages
* encode in well under 16 KiB; this only matters for [SshMsgChannelData]
* carrying near-`maxPacketSize` (32 KiB) of data — e.g. SFTP transfers.
*/
fun KaitaiStruct.ReadWrite.toByteArray(): ByteArray {
_check()
val io = ByteBufferKaitaiStream(1024 * 16)
_write(io)
val size = io.pos()
io.seek(0)
return io.readBytes(size.toLong())
var capacity = INITIAL_BUFFER
while (true) {
try {
val io = ByteBufferKaitaiStream(capacity)
_write(io)
val size = io.pos()
io.seek(0)
return io.readBytes(size.toLong())
} catch (_: java.nio.BufferOverflowException) {
if (capacity >= MAX_BUFFER) throw IllegalStateException("Kaitai message exceeds $MAX_BUFFER byte serialization limit")
capacity = minOf(capacity * 2, MAX_BUFFER)
}
}
}

private const val INITIAL_BUFFER = 1024L * 16
private const val MAX_BUFFER = 1024L * 1024
176 changes: 176 additions & 0 deletions sshlib/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,180 @@ package org.connectbot.sshlib {
property public String type;
}

public final class SftpAttributes {
ctor public SftpAttributes();
ctor public SftpAttributes(optional java.lang.Long? size, optional java.lang.Integer? uid, optional java.lang.Integer? gid, optional java.lang.Integer? permissions, optional java.lang.Integer? atime, optional java.lang.Integer? mtime);
method public java.lang.Long? component1();
method public java.lang.Integer? component2();
method public java.lang.Integer? component3();
method public java.lang.Integer? component4();
method public java.lang.Integer? component5();
method public java.lang.Integer? component6();
method public org.connectbot.sshlib.SftpAttributes copy(optional java.lang.Long? size, optional java.lang.Integer? uid, optional java.lang.Integer? gid, optional java.lang.Integer? permissions, optional java.lang.Integer? atime, optional java.lang.Integer? mtime);
method public boolean equals(java.lang.Object? other);
method @InaccessibleFromKotlin public java.lang.Integer? getAtime();
method @InaccessibleFromKotlin public java.lang.Integer? getGid();
method @InaccessibleFromKotlin public java.lang.Integer? getMtime();
method @InaccessibleFromKotlin public java.lang.Integer? getPermissions();
method @InaccessibleFromKotlin public java.lang.Long? getSize();
method @InaccessibleFromKotlin public java.lang.Integer? getUid();
method public int hashCode();
method public java.lang.String toString();
property public Integer? atime;
property public Integer? gid;
property public Integer? mtime;
property public Integer? permissions;
property public Long? size;
property public Integer? uid;
field public static final org.connectbot.sshlib.SftpAttributes.Companion Companion;
}

public static final class SftpAttributes.Companion {
method @InaccessibleFromKotlin public org.connectbot.sshlib.SftpAttributes getEMPTY();
property public org.connectbot.sshlib.SftpAttributes EMPTY;
}

public interface SftpClient {
method public void close();
method public suspend java.lang.Object? close(org.connectbot.sshlib.SftpFileHandle handle, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? fsetstat(org.connectbot.sshlib.SftpFileHandle handle, org.connectbot.sshlib.SftpAttributes attrs, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? fstat(org.connectbot.sshlib.SftpFileHandle handle, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<org.connectbot.sshlib.SftpAttributes>>);
method @InaccessibleFromKotlin public int getProtocolVersion();
method @InaccessibleFromKotlin public boolean isOpen();
method public default suspend java.lang.Object? listdir(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<? extends java.util.List<org.connectbot.sshlib.SftpDirectoryEntry>>>);
method public suspend java.lang.Object? lstat(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<org.connectbot.sshlib.SftpAttributes>>);
method public suspend java.lang.Object? mkdir(java.lang.String path, optional org.connectbot.sshlib.SftpAttributes attrs, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? open(java.lang.String path, java.util.Set<? extends org.connectbot.sshlib.SftpOpenFlag> flags, optional org.connectbot.sshlib.SftpAttributes attrs, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<org.connectbot.sshlib.SftpFileHandle>>);
method public suspend java.lang.Object? opendir(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<org.connectbot.sshlib.SftpFileHandle>>);
method public suspend java.lang.Object? read(org.connectbot.sshlib.SftpFileHandle handle, long offset, int length, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<byte[]?>>);
method public suspend java.lang.Object? readdir(org.connectbot.sshlib.SftpFileHandle handle, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<? extends java.util.List<org.connectbot.sshlib.SftpDirectoryEntry>?>>);
method public suspend java.lang.Object? readlink(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<java.lang.String>>);
method public suspend java.lang.Object? realpath(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<java.lang.String>>);
method public suspend java.lang.Object? remove(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? rename(java.lang.String oldPath, java.lang.String newPath, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? rmdir(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? setstat(java.lang.String path, org.connectbot.sshlib.SftpAttributes attrs, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? stat(java.lang.String path, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<org.connectbot.sshlib.SftpAttributes>>);
method public suspend java.lang.Object? symlink(java.lang.String targetPath, java.lang.String linkPath, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
method public suspend java.lang.Object? write(org.connectbot.sshlib.SftpFileHandle handle, long offset, byte[] data, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<kotlin.Unit>>);
property public abstract boolean isOpen;
property public abstract int protocolVersion;
}

public final class SftpDirectoryEntry {
ctor public SftpDirectoryEntry(java.lang.String filename, java.lang.String longname, org.connectbot.sshlib.SftpAttributes attrs);
method public java.lang.String component1();
method public java.lang.String component2();
method public org.connectbot.sshlib.SftpAttributes component3();
method public org.connectbot.sshlib.SftpDirectoryEntry copy(optional java.lang.String filename, optional java.lang.String longname, optional org.connectbot.sshlib.SftpAttributes attrs);
method public boolean equals(java.lang.Object? other);
method @InaccessibleFromKotlin public org.connectbot.sshlib.SftpAttributes getAttrs();
method @InaccessibleFromKotlin public java.lang.String getFilename();
method @InaccessibleFromKotlin public java.lang.String getLongname();
method public int hashCode();
method public java.lang.String toString();
property public org.connectbot.sshlib.SftpAttributes attrs;
property public String filename;
property public String longname;
}

public final class SftpException extends org.connectbot.sshlib.SshException {
ctor public SftpException(org.connectbot.sshlib.SftpStatusCode statusCode, java.lang.String message, optional java.lang.Throwable? cause);
method @InaccessibleFromKotlin public org.connectbot.sshlib.SftpStatusCode getStatusCode();
method public java.lang.String toString();
property public org.connectbot.sshlib.SftpStatusCode statusCode;
}

public final class SftpFileHandle {
method public boolean equals(java.lang.Object? other);
method public int hashCode();
}

public enum SftpOpenFlag {
method @InaccessibleFromKotlin public int getValue();
property public int value;
enum_constant public static final org.connectbot.sshlib.SftpOpenFlag APPEND;
enum_constant public static final org.connectbot.sshlib.SftpOpenFlag CREATE;
enum_constant public static final org.connectbot.sshlib.SftpOpenFlag EXCLUDE;
enum_constant public static final org.connectbot.sshlib.SftpOpenFlag READ;
enum_constant public static final org.connectbot.sshlib.SftpOpenFlag TRUNCATE;
enum_constant public static final org.connectbot.sshlib.SftpOpenFlag WRITE;
}

public sealed exhaustive interface SftpResult<T> {
}

public static final class SftpResult.IoError implements org.connectbot.sshlib.SftpResult {
ctor public SftpResult.IoError(java.lang.Throwable cause);
method public java.lang.Throwable component1();
method public org.connectbot.sshlib.SftpResult.IoError copy(optional java.lang.Throwable cause);
method public boolean equals(java.lang.Object? other);
method @InaccessibleFromKotlin public java.lang.Throwable getCause();
method public int hashCode();
method public java.lang.String toString();
property public Throwable cause;
}

public static final class SftpResult.ProtocolError implements org.connectbot.sshlib.SftpResult {
ctor public SftpResult.ProtocolError(java.lang.String message);
method public java.lang.String component1();
method public org.connectbot.sshlib.SftpResult.ProtocolError copy(optional java.lang.String message);
method public boolean equals(java.lang.Object? other);
method @InaccessibleFromKotlin public java.lang.String getMessage();
method public int hashCode();
method public java.lang.String toString();
property public String message;
}

public static final class SftpResult.ServerError implements org.connectbot.sshlib.SftpResult {
ctor public SftpResult.ServerError(org.connectbot.sshlib.SftpStatusCode statusCode, java.lang.String message);
method public org.connectbot.sshlib.SftpStatusCode component1();
method public java.lang.String component2();
method public org.connectbot.sshlib.SftpResult.ServerError copy(optional org.connectbot.sshlib.SftpStatusCode statusCode, optional java.lang.String message);
method public boolean equals(java.lang.Object? other);
method @InaccessibleFromKotlin public java.lang.String getMessage();
method @InaccessibleFromKotlin public org.connectbot.sshlib.SftpStatusCode getStatusCode();
method public int hashCode();
method public java.lang.String toString();
property public String message;
property public org.connectbot.sshlib.SftpStatusCode statusCode;
}

public static final class SftpResult.Success<T> implements org.connectbot.sshlib.SftpResult<T> {
ctor public SftpResult.Success(T value);
method public T component1();
method public org.connectbot.sshlib.SftpResult.Success<T> copy(optional T value);
method public boolean equals(java.lang.Object? other);
method @InaccessibleFromKotlin public T getValue();
method public int hashCode();
method public java.lang.String toString();
property public T value;
}

public final class SftpResultKt {
method public static <T> T? getOrNull(org.connectbot.sshlib.SftpResult<? extends T>);
method public static <T> T getOrThrow(org.connectbot.sshlib.SftpResult<? extends T>);
}

public enum SftpStatusCode {
method @InaccessibleFromKotlin public int getCode();
property public int code;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode BAD_MESSAGE;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode CONNECTION_LOST;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode EOF;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode FAILURE;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode NO_CONNECTION;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode NO_SUCH_FILE;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode OK;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode OP_UNSUPPORTED;
enum_constant public static final org.connectbot.sshlib.SftpStatusCode PERMISSION_DENIED;
field public static final org.connectbot.sshlib.SftpStatusCode.Companion Companion;
}

public static final class SftpStatusCode.Companion {
method public org.connectbot.sshlib.SftpStatusCode fromCode(int code);
}

public interface Socks5Authenticator {
method public boolean authenticate(java.lang.String username, java.lang.String password);
}
Expand All @@ -254,6 +428,7 @@ package org.connectbot.sshlib {
method public suspend java.lang.Object? localPortForward(int bindPort, java.lang.String remoteHost, int remotePort, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.PortForwarder?>);
method public org.connectbot.sshlib.transport.TransportFactory? openDirectTcpipTransport(java.lang.String remoteHost, int remotePort, optional java.lang.String originAddr, optional int originPort);
method public suspend java.lang.Object? openSession(kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SshSession?>);
method public suspend java.lang.Object? openSftp(kotlin.coroutines.Continuation<? super org.connectbot.sshlib.SftpResult<? extends org.connectbot.sshlib.SftpClient>>);
method public suspend java.lang.Object? remotePortForward(java.lang.String remoteBindAddress, int remoteBindPort, java.lang.String localHost, int localPort, kotlin.coroutines.Continuation<? super org.connectbot.sshlib.PortForwarder?>);
property public kotlinx.coroutines.flow.SharedFlow<java.lang.Throwable?> disconnectedFlow;
property public boolean isAuthenticated;
Expand Down Expand Up @@ -419,6 +594,7 @@ package org.connectbot.sshlib.blocking {
method public org.connectbot.sshlib.transport.TransportFactory? openDirectTcpipTransport(java.lang.String remoteHost, int remotePort, optional java.lang.String originAddr);
method public org.connectbot.sshlib.transport.TransportFactory? openDirectTcpipTransport(java.lang.String remoteHost, int remotePort, optional java.lang.String originAddr, optional int originPort);
method public org.connectbot.sshlib.SshSession? openSession();
method @kotlin.jvm.Throws(exceptionClasses=SftpException::class) public org.connectbot.sshlib.SftpClient openSftp() throws org.connectbot.sshlib.SftpException;
method public org.connectbot.sshlib.PortForwarder? remotePortForward(java.lang.String remoteBindAddress, int remoteBindPort, java.lang.String localHost, int localPort);
property public kotlinx.coroutines.flow.SharedFlow<java.lang.Throwable?> disconnectedFlow;
property public boolean isAuthenticated;
Expand Down
Loading
Loading