Skip to content

Commit

Permalink
- Added streaming protobufs using COBS
Browse files Browse the repository at this point in the history
- Updated to Android Studio 2.0
  • Loading branch information
sureshjoshi committed Apr 12, 2016
1 parent 4eed052 commit 3ca815a
Show file tree
Hide file tree
Showing 10 changed files with 695 additions and 372 deletions.
6 changes: 6 additions & 0 deletions .idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

906 changes: 550 additions & 356 deletions .idea/workspace.xml

Large diffs are not rendered by default.

27 changes: 23 additions & 4 deletions app/app.iml
Expand Up @@ -12,10 +12,7 @@
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
<afterSyncTasks>
<task>generateDebugAndroidTestSources</task>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
Expand All @@ -28,7 +25,7 @@
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/retrolambda/debug" />
<output-test url="file://$MODULE_DIR$/build/retrolambda/debugAndroidTest" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
Expand All @@ -50,6 +47,13 @@
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
Expand All @@ -64,17 +68,32 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.1.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.1.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
Expand Down
Expand Up @@ -28,7 +28,8 @@
public class MainActivity extends Activity {

int mRunningX = 0;
static final String FILE_NAME = "samples.pbin";
static final String FILE_NAME = "samples.pbld";
static final String FILE_NAME_COBS = "samples.pbcobs1";

@Bind(R.id.chart)
LineChart mChart;
Expand All @@ -37,14 +38,18 @@ public class MainActivity extends Activity {
void addOneSample() {
// Create one random entry
try {
OutputStream outputStream = new BufferedOutputStream(openFileOutput(FILE_NAME, MODE_APPEND));
Sample sample = new Sample.Builder()
.x(++mRunningX)
.y((int) (Math.random() * 1000))
.build();

OutputStream outputStream = new BufferedOutputStream(openFileOutput(FILE_NAME, MODE_APPEND));
WireUtils.writeDelimitedTo(outputStream, sample);
outputStream.close();

OutputStream outputStreamCobs = new BufferedOutputStream(openFileOutput(FILE_NAME_COBS, MODE_APPEND));
WireUtils.writeCobsEncodedTo(outputStreamCobs, sample);
outputStreamCobs.close();
} catch (IOException e) {
e.printStackTrace();
}
Expand All @@ -67,6 +72,10 @@ void addTenSamples() {
OutputStream outputStream = new BufferedOutputStream(openFileOutput(FILE_NAME, MODE_APPEND));
WireUtils.writeDelimitedTo(outputStream, samples);
outputStream.close();

// OutputStream outputStreamCobs = new BufferedOutputStream(openFileOutput(FILE_NAME_COBS, MODE_APPEND));
// WireUtils.writeCobsEncodedTo(outputStreamCobs, samples);
// outputStreamCobs.close();
} catch (IOException e) {
e.printStackTrace();
}
Expand All @@ -83,6 +92,10 @@ void refreshChart() {
InputStream inputStream = new BufferedInputStream(openFileInput(FILE_NAME));
samples = WireUtils.readDelimitedFrom(inputStream, Sample.ADAPTER);
inputStream.close();

// InputStream inputStreamCobs = new BufferedInputStream(openFileInput(FILE_NAME_COBS));
// samples = WireUtils.readCobsEncodedFrom(inputStreamCobs, Sample.ADAPTER);
// inputStreamCobs.close();
} catch (IOException e) {
e.printStackTrace();
}
Expand Down Expand Up @@ -123,5 +136,6 @@ protected void onCreate(Bundle savedInstanceState) {

// Delete the file, if any, between onCreate calls.
deleteFile(FILE_NAME);
deleteFile(FILE_NAME_COBS);
}
}
@@ -0,0 +1,65 @@
package com.sureshjoshi.android.streamingprotobufexample.utils;

public class CobsUtils {

// Expected to be the entire packet to encode
public static byte[] encode(byte[] packet) {
if (packet == null
|| packet.length == 0) {
return new byte[]{};
}

byte[] output = new byte[packet.length + 2];
byte blockStartValue = 1;
int lastZeroIndex = 0;
int srcIndex = 0;
int destIndex = 1;

while (srcIndex < packet.length) {
if (packet[srcIndex] == 0) {
output[lastZeroIndex] = blockStartValue;
lastZeroIndex = destIndex++;
blockStartValue = 1;
} else {
output[destIndex++] = packet[srcIndex];
if (++blockStartValue == 255) {
output[lastZeroIndex] = blockStartValue;
lastZeroIndex = destIndex++;
blockStartValue = 1;
}
}

++srcIndex;
}

output[lastZeroIndex] = blockStartValue;
return output;
}

// Expected to be the entire packet to decode (must end with a 0)
public static byte[] decode(byte[] packet) {
if (packet == null
|| packet.length == 0
|| packet[packet.length - 1] != 0) {
return new byte[]{};
}

byte[] output = new byte[packet.length - 2];
int srcPacketLength = packet.length - 1;
int srcIndex = 0;
int destIndex = 0;

while (srcIndex < srcPacketLength) {
int code = packet[srcIndex++] & 0xff;
for (int i = 1; srcIndex < srcPacketLength && i < code; ++i) {
output[destIndex++] = packet[srcIndex++];
}
if (code != 255 && srcIndex != srcPacketLength) {
output[destIndex++] = 0;
}
}

return output;
}

}
Expand Up @@ -39,4 +39,29 @@ public static <M extends Message> List<M> readDelimitedFrom(InputStream inputStr
}
return messages;
}

public static void writeCobsEncodedTo(OutputStream outputStream, List<Message> messages) throws IOException {
for (Message message : messages) {
writeCobsEncodedTo(outputStream, message);
}
}

public static void writeCobsEncodedTo(OutputStream outputStream, Message message) throws IOException {
BufferedSink sink = Okio.buffer(Okio.sink(outputStream));
sink.write(CobsUtils.encode(message.encode()));
sink.emit();
}

public static <M extends Message> List<M> readCobsEncodedFrom(InputStream inputStream, ProtoAdapter<M> adapter) throws IOException {
List<M> messages = new ArrayList<>();
BufferedSource source = Okio.buffer(Okio.source(inputStream));
while (!source.exhausted()) {
long length = source.indexOf((byte) 0);
byte[] decodedBytes = CobsUtils.decode(source.readByteArray(length + 1));
messages.add(adapter.decode(decodedBytes));
}
return messages;
}


}
2 changes: 1 addition & 1 deletion build.gradle
Expand Up @@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.android.tools.build:gradle:2.0.0'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Wed Oct 21 11:34:03 PDT 2015
#Mon Apr 11 22:23:35 EDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

0 comments on commit 3ca815a

Please sign in to comment.