Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for dotLottie #1660

Merged
merged 8 commits into from
Oct 27, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import com.airbnb.lottie.model.LottieCompositionCache;
import com.airbnb.lottie.parser.LottieCompositionMoshiParser;
import com.airbnb.lottie.parser.moshi.JsonReader;

import com.airbnb.lottie.utils.Logger;
import com.airbnb.lottie.utils.Utils;

import org.json.JSONObject;
Expand All @@ -27,8 +27,10 @@
import androidx.annotation.Nullable;
import androidx.annotation.RawRes;
import androidx.annotation.WorkerThread;
import okio.BufferedSource;
import okio.Okio;

import static com.airbnb.lottie.parser.moshi.JsonReader.*;
import static com.airbnb.lottie.parser.moshi.JsonReader.of;
import static com.airbnb.lottie.utils.Utils.closeQuietly;
import static okio.Okio.buffer;
import static okio.Okio.source;
Expand All @@ -49,6 +51,13 @@ public class LottieCompositionFactory {
*/
private static final Map<String, LottieTask<LottieComposition>> taskCache = new HashMap<>();

/**
* reference magic bytes for zip compressed files.
* useful to determine if an InputStream is a zip file or not
*/
private static final byte[] MAGIC = new byte[] { 0x50, 0x4b, 0x03, 0x04 };


private LottieCompositionFactory() {
}

Expand Down Expand Up @@ -181,7 +190,7 @@ public static LottieResult<LottieComposition> fromAssetSync(Context context, Str
@WorkerThread
public static LottieResult<LottieComposition> fromAssetSync(Context context, String fileName, @Nullable String cacheKey) {
try {
if (fileName.endsWith(".zip")) {
if (fileName.endsWith(".zip") || fileName.endsWith(".lottie")) {
return fromZipStreamSync(new ZipInputStream(context.getAssets().open(fileName)), cacheKey);
}
return fromJsonInputStreamSync(context.getAssets().open(fileName), cacheKey);
Expand Down Expand Up @@ -253,7 +262,11 @@ public static LottieResult<LottieComposition> fromRawResSync(Context context, @R
@WorkerThread
public static LottieResult<LottieComposition> fromRawResSync(Context context, @RawRes int rawRes, @Nullable String cacheKey) {
try {
return fromJsonInputStreamSync(context.getResources().openRawResource(rawRes), cacheKey);
BufferedSource source = Okio.buffer(source(context.getResources().openRawResource(rawRes)));
if (isZipCompressed(source)) {
return fromZipStreamSync(new ZipInputStream(source.inputStream()), cacheKey);
}
return fromJsonInputStreamSync(source.inputStream(), cacheKey);
} catch (Resources.NotFoundException e) {
return new LottieResult<>(e);
}
Expand Down Expand Up @@ -423,6 +436,8 @@ private static LottieResult<LottieComposition> fromZipStreamSyncInternal(ZipInpu
final String entryName = entry.getName();
if (entryName.contains("__MACOSX")) {
inputStream.closeEntry();
} else if (entry.getName().equalsIgnoreCase("manifest.json")) { //ignore .lottie manifest
inputStream.closeEntry();
} else if (entry.getName().contains(".json")) {
com.airbnb.lottie.parser.moshi.JsonReader reader = of(buffer(source(inputStream)));
composition = LottieCompositionFactory.fromJsonReaderSyncInternal(reader, null, false).getValue();
Expand Down Expand Up @@ -465,6 +480,26 @@ private static LottieResult<LottieComposition> fromZipStreamSyncInternal(ZipInpu
return new LottieResult<>(composition);
}

/**
* Check if a given InputStream points to a .zip compressed file
*/
private static Boolean isZipCompressed(BufferedSource inputSource) {

try {
BufferedSource peek = inputSource.peek();
for (byte b: MAGIC) {
if(peek.readByte() != b)
return false;
}
peek.close();
return true;
} catch (Exception e) {
Logger.error("Failed to check zip file header", e);
return false;
}

}

@Nullable
private static LottieImageAsset findImageAssetForFileName(LottieComposition composition, String fileName) {
for (LottieImageAsset asset : composition.getImages().values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private LottieResult<LottieComposition> fromInputStream(@NonNull String url, @No
// in the result which is more useful than failing here.
contentType = "application/json";
}
if (contentType.contains("application/zip")) {
if (contentType.contains("application/zip") || url.split("\\?")[0].endsWith(".lottie")) {
Logger.debug("Handling zip response.");
extension = FileExtension.ZIP;
result = fromZipStream(url, inputStream, cacheKey);
Expand Down