summaryrefslogtreecommitdiff
path: root/src/JSONReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/JSONReader.java')
-rw-r--r--src/JSONReader.java96
1 files changed, 76 insertions, 20 deletions
diff --git a/src/JSONReader.java b/src/JSONReader.java
index 45f6bd5..44831c9 100644
--- a/src/JSONReader.java
+++ b/src/JSONReader.java
@@ -1,5 +1,6 @@
import java.util.HashMap;
import java.util.ArrayList;
+
import java.io.*;
/*
@@ -9,6 +10,8 @@ import java.io.*;
* References:
* https://googlefonts.github.io/gf-guide/metadata.html
* https://stackoverflow.com/questions/3880274/how-to-convert-the-object-to-string-in-java
+ * https://stackoverflow.com/questions/8938498/get-the-index-of-a-pattern-in-a-string-using-regex
+ * https://howtodoinjava.com/java/regex/start-end-of-string/
*
* Date:
* 2024-05-08
@@ -21,15 +24,23 @@ public class JSONReader extends Reader {
/* metadata.pb is not exactly JSON, but so close to it
that it's practically a subset of JSON with fewer quotation
marks. If set, this is a pb file. */
- private boolean pb;
+ private boolean isMetadata;
public JSONReader(File file) {
- super(file);
- pb = false;
+ super(file); // Call constructor.
+ isMetadata = false; // By default, not metadata.
}
private String composeKey(String key) {
- if (!pb) {
+ /* Call static version. This has the benefit of reducing code size.
+ Rather than write two separate static and instantiated versions, the
+ instantiated version may call the static version. */
+ return composeKey(key, this.isMetadata);
+ }
+
+ private static String composeKey(String key, boolean isMetadata) {
+ /* JSON usually has quotes surrounding keys. Google's metadata doesn't. */
+ if (!isMetadata) {
key = "\"" + key + "\"";
}
key += ": ";
@@ -42,20 +53,32 @@ public class JSONReader extends Reader {
* match.
*/
public String get(String key) {
- key = composeKey(key);
-
- int start = this.getContents().indexOf(key);
+ /* Call static version. */
+ return JSONReader.get(this.getContents(), key, isMetadata);
+ }
+
+ public static String get(String json, String key) {
+ /* No isMetadata boolean passed, presumably irrelevant. */
+ return JSONReader.get(json, key, false);
+ }
+
+ /**
+ * Get a value given a key and a block of JSON to search.
+ */
+ public static String get(String json, String key, boolean isMetadata) {
+ key = composeKey(key, isMetadata); // Compose a key
+ int start = json.indexOf(key); // Index of key
if (start == -1) {
/* No match. */
return null;
}
- start += key.length();
+ start += key.length(); // Start of data past key
/* This JSON is pretty-printed. */
- int nl = this.getContents().indexOf("\n", start);
+ int nl = json.indexOf("\n", start);
/* Extract substring. Remove any quotation marks and commas. */
- String substring = this.getContents().substring(start, nl);
+ String substring = json.substring(start, nl);
return substring.replaceAll("[\",]", "");
}
@@ -63,12 +86,13 @@ public class JSONReader extends Reader {
* Search for and return all matches.
*/
public String[] getAll(String key) {
- key = composeKey(key);
+ key = composeKey(key); // Compose key
- ArrayList<String> list = new ArrayList<String>();
- int lastMatch = 0;
+ ArrayList<String> list = new ArrayList<String>(); // ArrayList to compose output array
+ int lastMatch = 0; // Previous match's index. Necessary for iteration through file contents.
+ /* While matches exist, continue. */
while ((lastMatch = this.getContents().indexOf(key, lastMatch)) != -1) {
- lastMatch += key.length();
+ lastMatch += key.length(); // Data starts after key.
int start = lastMatch;
/* This JSON is pretty-printed. */
int nl = this.getContents().indexOf("\n", start);
@@ -90,16 +114,48 @@ public class JSONReader extends Reader {
}
/**
- * Search for and return a table of fields.
+ * @return a block of JSON associated with a font family.
+ * Heavily reliant on the format of popularity.json. Not
+ * suitable for generic JSON parsing.
*/
- public String getTable(HashMap<String,String> name) {
- return null;
+ public String getFamily(String family) {
+ /* Taking advantage of the specific structure
+ of popularity.json. Find the index of the family
+ name declaration. Then, all items until the next line
+ starting with ' }' are included. */
+ String contents = this.getContents();
+ int start = contents.indexOf(" \"family\": \"" + family + "\",");
+ if (start == -1) {
+ /* No match. */
+ return null;
+ }
+
+ /* Restring input starting from family name declaration. */
+ contents = contents.substring(start);
+
+ String[] lines = contents.split("\n");
+ int i = 0;
+ /* In this format, an end block is guaranteed.
+ Iterate through lines until the desired level of end
+ block is found. */
+ while (!lines[i].startsWith(" }")) {
+ i++;
+ }
+
+ /* For each of the lines in the block preceding the end block,
+ add to output. */
+ String result = "";
+ for (int j = 0; j < i; j++) {
+ result += lines[j] + "\n";
+ }
+
+ return result;
}
/**
- * Specify that this is the special PB format.
+ * Specify that this is the special pb metadata format. Almost JSON.
* See https://googlefonts.github.io/gf-guide/metadata.html. */
- public void setPb() {
- this.pb = true;
+ public void setMetadata() {
+ this.isMetadata = true;
}
}