@@ 54,20 54,64 @@ public class GeminiClient {
return connect(doc.meta, 1965);
}
- StringBuilder sb = new StringBuilder();
- byte[] buffer = new byte[2000];
-
- while (true) {
- int bytesRead = is.read(buffer, 0, 2000);
- if (bytesRead == -1) {
- doc.lines = parseLines(sb.toString());
- return doc;
+ if (doc.getMeta().startsWith("text/")) {
+ //TODO: Should this apply for text/xml; text/plain; etc. as well
+ //as text/gemini? Quite possible not. Leaving it for now as I
+ //haven't seen any issues with pretending text/plain; is
+ //text/gemini;, yet, and non-text; needs more support first.
+ StringBuilder sb = new StringBuilder();
+ byte[] buffer = new byte[2000];
+
+ while (true) {
+ int bytesRead = is.read(buffer, 0, 2000);
+ if (bytesRead == -1) {
+ doc.lines = parseLines(sb.toString());
+ return doc;
+ }
+ sb.append(new String(buffer, 0, bytesRead, "UTF-8"));
}
- sb.append(new String(buffer, 0, bytesRead, "UTF-8"));
+ }
+ else {
+ byte[] fileContents = new byte[4096];
+ byte[] buffer = new byte[2000];
+ int fileContentsIndex = 0;
+
+ while (true) {
+ int bytesRead = is.read(buffer, 0, 2000);
+ if (bytesRead == -1) {
+ fileContents = trimBufferToSize(fileContents, fileContentsIndex);
+
+ doc.setBinaryContents(fileContents);
+ return doc;
+ }
+
+ //expand and re-allocate wholeBuffer if need be
+ if (fileContentsIndex + bytesRead > fileContents.length) {
+ fileContents = expandFileContents(fileContents, fileContentsIndex);
+ }
+
+ System.arraycopy(buffer, 0, fileContents, fileContentsIndex, bytesRead);
+ fileContentsIndex += bytesRead;
+ }
}
}
+ private static byte[] trimBufferToSize(byte[] fileContents, int wholeBufferIndex) {
+ //trim to size
+ byte[] oldBuffer = fileContents;
+ fileContents = new byte[wholeBufferIndex];
+ System.arraycopy(oldBuffer, 0, fileContents, 0, wholeBufferIndex);
+ return fileContents;
+ }
+
+ private static byte[] expandFileContents(byte[] wholeBuffer, int wholeBufferIndex) {
+ byte[] oldBuffer = wholeBuffer;
+ wholeBuffer = new byte[wholeBuffer.length * 2];
+ System.arraycopy(oldBuffer, 0, wholeBuffer, 0, wholeBufferIndex);
+ return wholeBuffer;
+ }
+
private static String extractHost(String url) {
// String hardcodedURL = "rawtext.club";
@@ 4,6 4,18 @@ import com.ajtjp.geminiclient.lines.Gemi
import java.util.ArrayList;
import java.util.List;
+/**
+ * This class really represents two things:
+ * - A Gemini (the format) document
+ * - A resource loaded via the Gemini protocol
+ * Initially, when the focus was entirely on loading Gemini format documents
+ * over the Gemini protocol, these were basically the same.
+ * However, now that support for loading things that aren't even text over the
+ * Gemini protocol is being added, these should probably be de-conflated at
+ * some point. Leaving that as tech debt for now, to see if that looks like a
+ * concern once the non-Gemini (format) support is working.
+ * @author Andrew
+ */
public class GeminiDocument {
String documentURL;
String headers; //eventually, will parse this out more semantically
@@ 11,6 23,7 @@ public class GeminiDocument {
String meta;
List<GeminiLine> lines;
+ private byte[] binaryContents;
public GeminiDocument(String url) {
this.documentURL = url;
@@ 47,4 60,12 @@ public class GeminiDocument {
public String getMeta() {
return meta;
}
+
+ public byte[] getBinaryContents() {
+ return binaryContents;
+ }
+
+ public void setBinaryContents(byte[] binaryContents) {
+ this.binaryContents = binaryContents;
+ }
}