package org.gscript.terminal;
import java.nio.ByteBuffer;
import org.gscript.jni.JNIReference;
import android.os.Parcel;
import android.os.Parcelable;
public class ScreenBufferParcelable extends JNIReference implements Parcelable {
static final int COPY_RESULT_SUCCESS = 0;
static final int COPY_RESULT_WRONG_SIZE = 1;
/* TODO: Move ScreenLine flags to somewhere more general */
static final int FLAG_LINEWRAPPED = 0x2;
protected ScreenBufferParcelable(long refpointer)
throws JNIReferenceException {
super(refpointer);
}
public static final Parcelable.Creator<ScreenBufferParcelable> CREATOR = new Parcelable.Creator<ScreenBufferParcelable>() {
public ScreenBufferParcelable createFromParcel(Parcel in) {
try {
return new ScreenBufferParcelable(in);
} catch (JNIReferenceException e) {
return null;
}
}
public ScreenBufferParcelable[] newArray(int size) {
return null;
}
};
public ScreenBufferParcelable(Parcel source) throws JNIReferenceException {
super(cloneReferencePointer(source.readLong()));
/*
* NOTE: DO NOT USE THE SAME REFPOINTER create a new native reference to
* same native object the other reference was pointing to. else the
* reference count of the actual object will not get raised and the
* backing native JNIReference might get deleted before we are.
*/
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(getReferencePointer());
}
/*
* The ScreenBufferParcelable only contains the get methods but the
* definition of the native methods are defined in ScreenBuffer so that this
* is just an empty base class and we only have one JNI header to look after
*/
public int getTextColor() {
return ScreenBuffer.nativeGetTextColor(getReferencePointer());
}
public int getBackColor() {
return ScreenBuffer.nativeGetBackColor(getReferencePointer());
}
public int getScreenRows() {
return ScreenBuffer.nativeGetScreenRows(getReferencePointer());
}
public int getScreenCols() {
return ScreenBuffer.nativeGetScreenCols(getReferencePointer());
}
public int getScreenTop() {
return ScreenBuffer.nativeGetScreenTop(getReferencePointer());
}
public int getScreenFillTop() {
return ScreenBuffer.nativeGetScreenFillTop(getReferencePointer());
}
public int getCursorRow(boolean absolute) {
return ScreenBuffer.nativeGetCursorRow(getReferencePointer(), absolute);
}
public int getCursorCol() {
return ScreenBuffer.nativeGetCursorCol(getReferencePointer());
}
private ByteBuffer allocateRowBuffer() {
return ByteBuffer.allocateDirect(
/* int:rowflags */4 +
/* int:columns */4 * getScreenCols());
}
public ByteBuffer getRowData(ByteBuffer buffer, int row, boolean absolute) {
if (buffer == null || !buffer.isDirect()) {
buffer = allocateRowBuffer();
}
if (!ScreenBuffer.nativeGetRowData(getReferencePointer(), row,
absolute, buffer)) {
/*
* the size of the row buffer does not match. reallocate row buffer
* to match sizes and then try again
*/
buffer = allocateRowBuffer();
if (!ScreenBuffer.nativeGetRowData(getReferencePointer(), row,
absolute, buffer)) {
return null;
}
}
buffer.position(0);
return buffer;
}
public String getTranscript() {
ByteBuffer rowBuffer = null;
StringBuilder transcript = new StringBuilder(getScreenRows() * (getScreenCols()));
StringBuilder line = new StringBuilder(getScreenCols());
int rows = (this.getScreenTop() + this.getScreenRows());
for(int row=0; row < rows; ++row) {
if((rowBuffer=getRowData(rowBuffer, row, true))==null)
return "failed to build transcript";
int rowFlags = rowBuffer.getInt();
if(row != 0 && (rowFlags & FLAG_LINEWRAPPED) != FLAG_LINEWRAPPED) {
transcript.append(line.toString().trim());
transcript.append("\n");
line.setLength(0);
}
if(rowFlags != -1) {
int pos = rowBuffer.position();
int cols = (rowBuffer.capacity() - pos) / 4;
for(int col=0; col < cols; ++col) {
int encodedChar = rowBuffer.getInt();
byte bTextEffects = (byte) ((encodedChar >> 16) & 0xff);
if ((bTextEffects & TextEffects.IGNORE) != TextEffects.IGNORE) {
line.append( (char) ((encodedChar >> 24) & 0xff) );
} else {
line.append(" ");
}
}
}
}
if(line.length() > 0)
transcript.append(line.toString().trim());
return transcript.toString();
}
}