image-loader add datauri parser

This commit is contained in:
Dimitry Ivanov 2018-08-25 13:11:13 +03:00
parent 9d80637035
commit c57d06dc7d
4 changed files with 263 additions and 0 deletions

View File

@ -27,6 +27,11 @@ dependencies {
api it['android-gif']
api it['okhttp']
}
deps['test'].with {
testImplementation it['junit']
testImplementation it['robolectric']
}
}
afterEvaluate {

View File

@ -0,0 +1,60 @@
package ru.noties.markwon.il;
import android.support.annotation.Nullable;
public class DataUri {
private final String contentType;
private final boolean base64;
private final String data;
public DataUri(@Nullable String contentType, boolean base64, @Nullable String data) {
this.contentType = contentType;
this.base64 = base64;
this.data = data;
}
@Nullable
public String contentType() {
return contentType;
}
public boolean base64() {
return base64;
}
@Nullable
public String data() {
return data;
}
@Override
public String toString() {
return "DataUri{" +
"contentType='" + contentType + '\'' +
", base64=" + base64 +
", data='" + data + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DataUri dataUri = (DataUri) o;
if (base64 != dataUri.base64) return false;
if (contentType != null ? !contentType.equals(dataUri.contentType) : dataUri.contentType != null)
return false;
return data != null ? data.equals(dataUri.data) : dataUri.data == null;
}
@Override
public int hashCode() {
int result = contentType != null ? contentType.hashCode() : 0;
result = 31 * result + (base64 ? 1 : 0);
result = 31 * result + (data != null ? data.hashCode() : 0);
return result;
}
}

View File

@ -0,0 +1,79 @@
package ru.noties.markwon.il;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public abstract class DataUriParser {
@Nullable
public abstract DataUri parse(@NonNull String input);
@NonNull
public static DataUriParser create() {
return new Impl();
}
static class Impl extends DataUriParser {
@Nullable
@Override
public DataUri parse(@NonNull String input) {
final int index = input.indexOf(',');
// we expect exactly one comma
if (index < 0) {
return null;
}
final String contentType;
final boolean base64;
if (index > 0) {
final String part = input.substring(0, index);
final String[] parts = part.split(";");
final int length = parts.length;
if (length > 0) {
// if one: either content-type or base64
if (length == 1) {
final String value = parts[0];
if ("base64".equals(value)) {
contentType = null;
base64 = true;
} else {
contentType = value.indexOf('/') > -1
? value
: null;
base64 = false;
}
} else {
contentType = parts[0].indexOf('/') > -1
? parts[0]
: null;
base64 = "base64".equals(parts[length - 1]);
}
} else {
contentType = null;
base64 = false;
}
} else {
contentType = null;
base64 = false;
}
final String data;
if (index < input.length()) {
final String value = input.substring(index + 1, input.length()).replaceAll("\n", "");
if (value.length() == 0) {
data = null;
} else {
data = value;
}
} else {
data = null;
}
return new DataUri(contentType, base64, data);
}
}
}

View File

@ -0,0 +1,119 @@
package ru.noties.markwon.il;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class DataUriParserTest {
private DataUriParser.Impl impl;
@Before
public void before() {
impl = new DataUriParser.Impl();
}
@Test
public void test() {
final Map<String, DataUri> data = new LinkedHashMap<String, DataUri>() {{
put(",", new DataUri(null, false, null));
put("image/svg+xml;base64,!@#$%^&*(", new DataUri("image/svg+xml", true, "!@#$%^&*("));
put("text/vnd-example+xyz;foo=bar;base64,R0lGODdh", new DataUri("text/vnd-example+xyz", true, "R0lGODdh"));
put("text/plain;charset=UTF-8;page=21,the%20data:1234,5678", new DataUri("text/plain", false, "the%20data:1234,5678"));
}};
for (Map.Entry<String, DataUri> entry : data.entrySet()) {
assertEquals(entry.getKey(), entry.getValue(), impl.parse(entry.getKey()));
}
}
@Test
public void data_new_lines_are_ignored() {
final String input = "image/png;base64,iVBORw0KGgoAAA\n" +
"ANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4\n" +
"//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU\n" +
"5ErkJggg==";
assertEquals(
new DataUri("image/png", true, "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="),
impl.parse(input)
);
}
@Test
public void no_comma_returns_null() {
final String[] inputs = {
"",
"what-ever",
";;;;;;;",
"some crazy data"
};
for (String input : inputs) {
assertNull(input, impl.parse(input));
}
}
@Test
public void two_commas() {
final String input = ",,"; // <- second one would be considered data...
assertEquals(
input,
new DataUri(null, false, ","),
impl.parse(input)
);
}
@Test
public void more_commas() {
final String input = "first,second,third"; // <- first is just a value (will be ignored)
assertEquals(
input,
new DataUri(null, false, "second,third"),
impl.parse(input)
);
}
@Test
public void base64_no_content_type() {
final String input = ";base64,12345";
assertEquals(
input,
new DataUri(null, true, "12345"),
impl.parse(input)
);
}
@Test
public void not_base64_no_content_type() {
final String input = ",qweRTY";
assertEquals(
input,
new DataUri(null, false, "qweRTY"),
impl.parse(input)
);
}
@Test
public void content_type_data_no_base64() {
final String input = "image/png,aSdFg";
assertEquals(
input,
new DataUri("image/png", false, "aSdFg"),
impl.parse(input)
);
}
}