|
|
@@ -1,23 +1,18 @@
|
|
|
package info.knacki.pass.git;
|
|
|
|
|
|
-import android.arch.core.util.Function;
|
|
|
import android.os.AsyncTask;
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStreamReader;
|
|
|
-import java.io.StringReader;
|
|
|
-import java.io.UnsupportedEncodingException;
|
|
|
+import java.math.BigInteger;
|
|
|
import java.net.Authenticator;
|
|
|
import java.net.MalformedURLException;
|
|
|
import java.net.PasswordAuthentication;
|
|
|
import java.net.URL;
|
|
|
import java.net.URLConnection;
|
|
|
import java.nio.charset.Charset;
|
|
|
-import java.security.InvalidKeyException;
|
|
|
import java.util.ArrayList;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.InvalidPropertiesFormatException;
|
|
|
import java.util.logging.Level;
|
|
|
import java.util.logging.Logger;
|
|
|
import java.util.zip.InflaterInputStream;
|
|
|
@@ -25,7 +20,6 @@ import java.util.zip.InflaterInputStream;
|
|
|
import info.knacki.pass.git.entities.GitCommit;
|
|
|
import info.knacki.pass.git.entities.GitObject;
|
|
|
import info.knacki.pass.git.entities.GitRef;
|
|
|
-import info.knacki.pass.git.entities.Util;
|
|
|
import info.knacki.pass.settings.SettingsManager;
|
|
|
|
|
|
class DumbGitInterface implements GitInterface {
|
|
|
@@ -73,7 +67,16 @@ class DumbGitInterface implements GitInterface {
|
|
|
}
|
|
|
++i;
|
|
|
}
|
|
|
- callback.onResponse(buffer);
|
|
|
+
|
|
|
+ for (i =0; i < totalRead && buffer[i] != 0; ++i);
|
|
|
+ if (i != totalRead) {
|
|
|
+ ++i;
|
|
|
+ byte []arr = new byte[buffer.length -i];
|
|
|
+ System.arraycopy(buffer, i, arr, 0, totalRead -i);
|
|
|
+ callback.onResponse(arr);
|
|
|
+ } else {
|
|
|
+ callback.onResponse(buffer);
|
|
|
+ }
|
|
|
}
|
|
|
catch (MalformedURLException e) {
|
|
|
log.log(Level.WARNING, e.getMessage(), e);
|
|
|
@@ -178,52 +181,86 @@ class DumbGitInterface implements GitInterface {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- // FIXME recursive strategy
|
|
|
-
|
|
|
- public void RecursiveFetchTree(final GitObject.GitTree rootTree, final OnResponseListener<GitObject.GitTree> response) {
|
|
|
- response.onResponse(rootTree);
|
|
|
- }
|
|
|
+ public void FetchTree(final GitCommit ci, final OnStreamResponseListener<GitObject.GitTree> response) {
|
|
|
+ class RecursiveFetchTreeWalker implements OnResponseListener<byte[]> {
|
|
|
+ private final GitObject.GitTree fRoot;
|
|
|
+ private GitObject.GitTree fCurrentTree;
|
|
|
+ private final OnStreamResponseListener<GitObject.GitTree> fResponseListener;
|
|
|
|
|
|
- private void FillTree(final GitObject.GitTree tree, byte[] data) {
|
|
|
- int i = 3;
|
|
|
+ private RecursiveFetchTreeWalker(GitCommit ci, final OnStreamResponseListener<GitObject.GitTree> responseListener) {
|
|
|
+ fRoot = fCurrentTree = new GitObject.GitTree(ci.GetTree()).Initialize();
|
|
|
+ fResponseListener = responseListener;
|
|
|
+ }
|
|
|
|
|
|
- while (data[i -1] != 0 && i < data.length)
|
|
|
- ++i;
|
|
|
- while (i < data.length) {
|
|
|
- byte[] mode = new byte[6];
|
|
|
- System.arraycopy(data, i, mode, 0, 6);
|
|
|
- i += 6;
|
|
|
- int len = 0;
|
|
|
- while (i +len < data.length && data[i +len] != 0)
|
|
|
- ++len;
|
|
|
- byte[] filenameBytes = new byte[len];
|
|
|
- System.arraycopy(data, i, filenameBytes, 0, len);
|
|
|
- i += len +1;
|
|
|
- String fileName = new String(filenameBytes, Charset.defaultCharset());
|
|
|
- byte []sha1 = new byte[20];
|
|
|
- System.arraycopy(data, i, sha1, 0, 20);
|
|
|
- i += 20;
|
|
|
- tree.AddItem(GitObject.factory(new String(mode, Charset.defaultCharset()).toCharArray(), fileName, sha1));
|
|
|
- }
|
|
|
- }
|
|
|
+ public void run() {
|
|
|
+ PullHash(ci.GetTree());
|
|
|
+ }
|
|
|
|
|
|
- public void FetchTree(final GitCommit ci, final OnResponseListener<GitObject.GitTree> response) {
|
|
|
- PullHash(ci.GetTree(), new OnResponseListener<byte[]>() {
|
|
|
@Override
|
|
|
public void onResponse(byte[] result) {
|
|
|
- GitObject.GitTree tree = new GitObject.GitTree(ci.GetTree()).Initialize();
|
|
|
- FillTree(tree, result);
|
|
|
- RecursiveFetchTree(tree, response);
|
|
|
+ FillTree(fCurrentTree, result);
|
|
|
+ fCurrentTree = fRoot.FindNextUninitialiazedTree();
|
|
|
+ if (fCurrentTree != null)
|
|
|
+ PullHash(fCurrentTree.Initialize().GetHash());
|
|
|
+ else
|
|
|
+ fResponseListener.onResponse(fRoot);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void onError(String msg, Throwable e) {
|
|
|
- response.onError(msg, e);
|
|
|
+ fResponseListener.onError(msg, e);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void PullHash(String hash) {
|
|
|
+ fResponseListener.onMsg("Reading tree " +hash);
|
|
|
+ DumbGitInterface.this.PullHash(hash, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void FillTree(final GitObject.GitTree tree, byte[] data) {
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ while (i < data.length) {
|
|
|
+ byte[] mode = new byte[6];
|
|
|
+ if (i +6 >= data.length)
|
|
|
+ break;
|
|
|
+ System.arraycopy(data, i, mode, 0, 6);
|
|
|
+ i += 6;
|
|
|
+ int len = 0;
|
|
|
+ while (i +len < data.length && data[i +len] != 0)
|
|
|
+ ++len;
|
|
|
+ byte[] filenameBytes = new byte[len];
|
|
|
+ System.arraycopy(data, i, filenameBytes, 0, len);
|
|
|
+ i += len;
|
|
|
+ String fileName = new String(filenameBytes, Charset.defaultCharset());
|
|
|
+ if (i +21 > data.length)
|
|
|
+ break;
|
|
|
+ byte []sha1 = new byte[21];
|
|
|
+ System.arraycopy(data, i, sha1, 0, 21);
|
|
|
+ i += 21;
|
|
|
+ tree.AddItem(GitObject.factory(new String(mode, Charset.defaultCharset()).toCharArray(), fileName, sha1ToString(sha1)));
|
|
|
+ }
|
|
|
}
|
|
|
- });
|
|
|
+
|
|
|
+ private String sha1ToString(byte[] sha1) {
|
|
|
+ String out = new BigInteger(1, sha1).toString(16);
|
|
|
+ if (out.length() == 40)
|
|
|
+ return out;
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ for (int i = 40 -out.length(); i > 0; --i)
|
|
|
+ sb.append('0');
|
|
|
+ return sb.toString() +out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ new RecursiveFetchTreeWalker(ci, response).run();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void FetchBlob(final GitObject.GitBlob blob, final OnResponseListener<byte[]> response) {
|
|
|
+ PullHash(blob.GetHash(), response);
|
|
|
}
|
|
|
|
|
|
- public void Pull(final OnStreamResponseListener<Void> response) {
|
|
|
+ public void FetchTree(final OnStreamResponseListener<GitObject.GitTree> response) {
|
|
|
GetRefs(new GitInterface.OnResponseListener<GitRef[]>() {
|
|
|
@Override
|
|
|
public void onResponse(final GitRef[] result) {
|
|
|
@@ -242,10 +279,16 @@ class DumbGitInterface implements GitInterface {
|
|
|
response.onMsg("Finished read commit");
|
|
|
response.onMsg(result.GetMessage());
|
|
|
response.onMsg("Reading tree #" +result.GetTree());
|
|
|
- FetchTree(result, new OnResponseListener<GitObject.GitTree>() {
|
|
|
+ FetchTree(result, new OnStreamResponseListener<GitObject.GitTree>() {
|
|
|
+ @Override
|
|
|
+ public void onMsg(String message) {
|
|
|
+ response.onMsg(message);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void onResponse(GitObject.GitTree result) {
|
|
|
response.onMsg("Finished read tree");
|
|
|
+ response.onResponse(result);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -272,7 +315,7 @@ class DumbGitInterface implements GitInterface {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- public void PullHash(String hash, final OnResponseListener<byte[]> response) {
|
|
|
+ private void PullHash(String hash, final OnResponseListener<byte[]> response) {
|
|
|
URL url;
|
|
|
try {
|
|
|
url = new URL(fConfig.GetUrl() + "/objects/" + hash.substring(0, 2) + "/" + hash.substring(2));
|
|
|
@@ -281,16 +324,6 @@ class DumbGitInterface implements GitInterface {
|
|
|
response.onError(e.getClass().getName() +": " +e.getMessage(), e);
|
|
|
return;
|
|
|
}
|
|
|
- protoInflateGet(url, new OnResponseListener<byte[]>() {
|
|
|
- @Override
|
|
|
- public void onResponse(byte []result) {
|
|
|
- response.onResponse(result);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void onError(String msg, Throwable e) {
|
|
|
- response.onError(msg, e);
|
|
|
- }
|
|
|
- });
|
|
|
+ protoInflateGet(url, response);
|
|
|
}
|
|
|
}
|