Created
February 7, 2014 23:57
-
-
Save searler/8874433 to your computer and use it in GitHub Desktop.
Baudot conversion using RxJava Observable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package baudot; | |
import java.util.Arrays; | |
import rx.Observable; | |
import rx.Observable.OnSubscribeFunc; | |
import rx.Observer; | |
import rx.Subscription; | |
import rx.util.functions.Func1; | |
public class BaudotObservable { | |
public static Observable<String> decode(final Observable<byte[]> src) { | |
return Observable.create(new OnSubscribeFunc<String>() { | |
@Override | |
public Subscription onSubscribe( | |
final Observer<? super String> observer) { | |
return src.subscribe(new Observer<byte[]>() { | |
private char[] current = LETTERS; | |
@Override | |
public void onCompleted() { | |
observer.onCompleted(); | |
} | |
@Override | |
public void onError(Throwable e) { | |
observer.onError(e); | |
} | |
@Override | |
public void onNext(byte[] bytes) { | |
if (bytes.length == 0) | |
return; | |
final StringBuilder builder = new StringBuilder( | |
bytes.length); | |
for (byte raw : bytes) { | |
final int b = raw & 0x1F; | |
if (b == FIGURES_MODE) | |
current = FIGURES; | |
else if (b == LETTERS_MODE) | |
current = LETTERS; | |
else | |
builder.append(current[b]); | |
} | |
if (builder.length() > 0) | |
observer.onNext(builder.toString()); | |
} | |
}); | |
} | |
}); | |
} | |
public static Observable<byte[]> encode(Observable<String> src) { | |
return src.map(new Func1<String, byte[]>() { | |
private byte mode = UNDEFINED; | |
@Override | |
public byte[] call(String string) { | |
final Buffer buffer = new Buffer(string.length()); | |
for (byte raw : string.getBytes()) { | |
final int sb = raw & 0x7F; | |
final byte lb = LETTER_BYTES[sb]; | |
final byte fb = FIGURE_BYTES[sb]; | |
byte m = (mode == UNDEFINED) ? LETTERS_MODE : mode; | |
if (fb != lb) | |
m = (fb == UNDEFINED) ? LETTERS_MODE : FIGURES_MODE; | |
if (mode != m) { | |
mode = m; | |
buffer.append(mode); | |
} | |
if (lb != UNDEFINED) | |
buffer.append(lb); | |
else if (fb != UNDEFINED) | |
buffer.append(fb); | |
else | |
buffer.append(BLANK); | |
} | |
return buffer.asArray(); | |
} | |
}); | |
} | |
private final static String FIGURES_STRING = "\u00003\n- \u000787\r$4',!:(5\")2#6019?&\u007F./;"; | |
private final static String LETTERS_STRING = "\u0000E\nA SIU\rDRJNFCKTZLWHYPQOBG\u007FMXV"; | |
private final static byte FIGURES_MODE = 27; | |
private final static byte LETTERS_MODE = 31; | |
private final static char[] FIGURES = FIGURES_STRING.toCharArray(); | |
private final static char[] LETTERS = LETTERS_STRING.toCharArray(); | |
private final static byte[] LETTER_BYTES = invert(LETTERS_STRING); | |
private final static byte[] FIGURE_BYTES = invert(FIGURES_STRING); | |
private static final byte BLANK = 0; | |
private static final int UNDEFINED = -1; | |
private final static byte[] invert(String string) { | |
byte[] strBytes = string.getBytes(); | |
byte[] baudot = new byte[128]; | |
Arrays.fill(baudot, (byte) UNDEFINED); | |
for (byte b = 0; b < LETTERS_MODE; b++) | |
if (b != FIGURES_MODE) | |
baudot[strBytes[b]] = b; | |
return baudot; | |
} | |
private static class Buffer { | |
private final byte[] buffer; | |
private int length; | |
public Buffer(int strLen) { | |
buffer = new byte[strLen * 2]; | |
} | |
public void append(byte b) { | |
buffer[length++] = b; | |
} | |
public byte[] asArray() { | |
byte[] result = new byte[length]; | |
System.arraycopy(buffer, 0, result, 0, length); | |
return result; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment