* Decompile and recreate Soul Browser v1.4.85 with APK CI builds Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix CI build: include bundled google.jks and remove PR trigger The apktool build failed in CI because app/unknown/.../google.jks was excluded by the *.jks gitignore rule. Whitelist app-bundled JKS files and commit the missing resource. Also remove the redundant pull_request workflow trigger. Co-authored-by: KaKi87 <KaKi87@pm.me> * Change package ID to com.github.kaki87.soulbrowser Rename the application ID so the rebuilt APK can be installed alongside the original Soul Browser from Google Play. - Update AndroidManifest package, permissions, providers, and actions - Update R class references in smali (com/github/kaki87/soulbrowser/R) - Update shortcuts.xml targetPackage - Rename app label to "Soul Rebuild" for easy identification Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix install compatibility: remove split APK metadata and bundle native libs The rebuilt APK still declared requiredSplitTypes and Play Store split metadata, causing Android to reject standalone installs as incompatible. - Remove requiredSplitTypes and split-related manifest meta-data - Merge native libs from all ABI splits with uncompressed storage - Page-align before signing for extractNativeLibs=false - Add .so to apktool doNotCompress list Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix install failure: use apksigner v2/v3 and bundle arm64 native libs Target SDK 36 requires APK Signature Scheme v2+, but jarsigner only produces v1 signatures, causing Android to reject the install. - Sign with apksigner (v1+v2+v3) instead of jarsigner - Add arm64-v8a native libraries from universal Soul Browser 1.4.79 - Set extractNativeLibs=true for reliable sideload installs - Commit stable debug keystore for consistent signatures across builds Co-authored-by: KaKi87 <KaKi87@pm.me> * Add committed debug keystore for consistent APK signatures Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix startup crash: use original classes2.dex desugar libraries Apktool recompiles smali_classes2 into a broken classes2.dex, causing ClassNotFoundException for j$.com.android.tools.r8.a at ML Kit init. Inject the original classes2.dex (Java 8+ desugar libs) after apktool build instead of using the recompiled version. Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix missing drawable resources from density split APKs The base APK is an app bundle module; density-specific drawables like seek_thumb_nor_b live in config.xhdpi.apk and were missing after rebuild, causing Resources$NotFoundException at runtime. - Merge non-9-patch resources from split APKs before apktool build - Sync public.xml IDs from R smali only when backing files exist - Add 713 density-specific resource IDs to public.xml Co-authored-by: KaKi87 <KaKi87@pm.me> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
454 lines
24 KiB
Java
454 lines
24 KiB
Java
package kotlin.io;
|
|
|
|
import com.google.android.gms.ads.RequestConfiguration;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import kotlin.Deprecated;
|
|
import kotlin.Metadata;
|
|
import kotlin.Unit;
|
|
import kotlin.collections.CollectionsKt;
|
|
import kotlin.collections.CollectionsKt___CollectionsKt;
|
|
import kotlin.jvm.functions.Function2;
|
|
import kotlin.jvm.internal.Intrinsics;
|
|
import kotlin.jvm.internal.SourceDebugExtension;
|
|
import kotlin.text.StringsKt__StringsJVMKt;
|
|
import kotlin.text.StringsKt__StringsKt;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
@Metadata(d1 = {"\u0000<\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\u000e\n\u0002\b\u0014\n\u0002\u0010\u000b\n\u0000\n\u0002\u0010\b\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010 \n\u0002\b\u0004\u001a*\u0010\u0000\u001a\u00020\u00012\b\b\u0002\u0010\u0002\u001a\u00020\u00032\n\b\u0002\u0010\u0004\u001a\u0004\u0018\u00010\u00032\n\b\u0002\u0010\u0005\u001a\u0004\u0018\u00010\u0001H\u0007\u001a*\u0010\u0006\u001a\u00020\u00012\b\b\u0002\u0010\u0002\u001a\u00020\u00032\n\b\u0002\u0010\u0004\u001a\u0004\u0018\u00010\u00032\n\b\u0002\u0010\u0005\u001a\u0004\u0018\u00010\u0001H\u0007\u001a\u0012\u0010\u000e\u001a\u00020\u0003*\u00020\u00012\u0006\u0010\u000f\u001a\u00020\u0001\u001a\u0012\u0010\u0010\u001a\u00020\u0001*\u00020\u00012\u0006\u0010\u000f\u001a\u00020\u0001\u001a\u0012\u0010\u0011\u001a\u00020\u0001*\u00020\u00012\u0006\u0010\u000f\u001a\u00020\u0001\u001a\u0014\u0010\u0012\u001a\u0004\u0018\u00010\u0001*\u00020\u00012\u0006\u0010\u000f\u001a\u00020\u0001\u001a\u001b\u0010\u0013\u001a\u0004\u0018\u00010\u0003*\u00020\u00012\u0006\u0010\u000f\u001a\u00020\u0001H\u0002¢\u0006\u0002\b\u0014\u001a&\u0010\u0015\u001a\u00020\u0001*\u00020\u00012\u0006\u0010\u0016\u001a\u00020\u00012\b\b\u0002\u0010\u0017\u001a\u00020\u00182\b\b\u0002\u0010\u0019\u001a\u00020\u001a\u001a8\u0010\u001b\u001a\u00020\u0018*\u00020\u00012\u0006\u0010\u0016\u001a\u00020\u00012\b\b\u0002\u0010\u0017\u001a\u00020\u00182\u001a\b\u0002\u0010\u001c\u001a\u0014\u0012\u0004\u0012\u00020\u0001\u0012\u0004\u0012\u00020\u001e\u0012\u0004\u0012\u00020\u001f0\u001d\u001a\n\u0010 \u001a\u00020\u0018*\u00020\u0001\u001a\u0012\u0010!\u001a\u00020\u0018*\u00020\u00012\u0006\u0010\"\u001a\u00020\u0001\u001a\u0012\u0010!\u001a\u00020\u0018*\u00020\u00012\u0006\u0010\"\u001a\u00020\u0003\u001a\u0012\u0010#\u001a\u00020\u0018*\u00020\u00012\u0006\u0010\"\u001a\u00020\u0001\u001a\u0012\u0010#\u001a\u00020\u0018*\u00020\u00012\u0006\u0010\"\u001a\u00020\u0003\u001a\n\u0010$\u001a\u00020\u0001*\u00020\u0001\u001a\u0011\u0010$\u001a\u00020%*\u00020%H\u0002¢\u0006\u0002\b&\u001a\u001d\u0010$\u001a\b\u0012\u0004\u0012\u00020\u00010'*\b\u0012\u0004\u0012\u00020\u00010'H\u0002¢\u0006\u0002\b&\u001a\u0012\u0010(\u001a\u00020\u0001*\u00020\u00012\u0006\u0010)\u001a\u00020\u0001\u001a\u0012\u0010(\u001a\u00020\u0001*\u00020\u00012\u0006\u0010)\u001a\u00020\u0003\u001a\u0012\u0010*\u001a\u00020\u0001*\u00020\u00012\u0006\u0010)\u001a\u00020\u0001\u001a\u0012\u0010*\u001a\u00020\u0001*\u00020\u00012\u0006\u0010)\u001a\u00020\u0003\"\u0015\u0010\u0007\u001a\u00020\u0003*\u00020\u00018F¢\u0006\u0006\u001a\u0004\b\b\u0010\t\"\u0015\u0010\n\u001a\u00020\u0003*\u00020\u00018F¢\u0006\u0006\u001a\u0004\b\u000b\u0010\t\"\u0015\u0010\f\u001a\u00020\u0003*\u00020\u00018F¢\u0006\u0006\u001a\u0004\b\r\u0010\t¨\u0006+"}, d2 = {"createTempDir", "Ljava/io/File;", "prefix", RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED, "suffix", "directory", "createTempFile", "extension", "getExtension", "(Ljava/io/File;)Ljava/lang/String;", "invariantSeparatorsPath", "getInvariantSeparatorsPath", "nameWithoutExtension", "getNameWithoutExtension", "toRelativeString", "base", "relativeTo", "relativeToOrSelf", "relativeToOrNull", "toRelativeStringOrNull", "toRelativeStringOrNull$FilesKt__UtilsKt", "copyTo", "target", "overwrite", RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED, "bufferSize", RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED, "copyRecursively", "onError", "Lkotlin/Function2;", "Ljava/io/IOException;", "Lkotlin/io/OnErrorAction;", "deleteRecursively", "startsWith", "other", "endsWith", "normalize", "Lkotlin/io/FilePathComponents;", "normalize$FilesKt__UtilsKt", RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED, "resolve", "relative", "resolveSibling", "kotlin-stdlib"}, k = 5, mv = {2, 2, 0}, xi = 49, xs = "kotlin/io/FilesKt")
|
|
@SourceDebugExtension({"SMAP\nUtils.kt\nKotlin\n*S Kotlin\n*F\n+ 1 Utils.kt\nkotlin/io/FilesKt__UtilsKt\n+ 2 fake.kt\nkotlin/jvm/internal/FakeKt\n+ 3 _Sequences.kt\nkotlin/sequences/SequencesKt___SequencesKt\n*L\n1#1,473:1\n1#2:474\n1292#3,3:475\n*S KotlinDebug\n*F\n+ 1 Utils.kt\nkotlin/io/FilesKt__UtilsKt\n*L\n347#1:475,3\n*E\n"})
|
|
/* loaded from: classes.dex */
|
|
class FilesKt__UtilsKt extends FilesKt__FileTreeWalkKt {
|
|
public static final boolean copyRecursively(@NotNull File file, @NotNull File target, boolean z, @NotNull final Function2<? super File, ? super IOException, ? extends OnErrorAction> onError) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(target, "target");
|
|
Intrinsics.checkNotNullParameter(onError, "onError");
|
|
if (!file.exists()) {
|
|
if (onError.invoke(file, new NoSuchFileException(file, null, "The source file doesn't exist.", 2, null)) != OnErrorAction.TERMINATE) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
try {
|
|
Iterator<File> it = FilesKt__FileTreeWalkKt.walkTopDown(file).onFail(new Function2() { // from class: kotlin.io.b
|
|
@Override // kotlin.jvm.functions.Function2
|
|
public final Object invoke(Object obj, Object obj2) {
|
|
Unit copyRecursively$lambda$0$FilesKt__UtilsKt;
|
|
copyRecursively$lambda$0$FilesKt__UtilsKt = FilesKt__UtilsKt.copyRecursively$lambda$0$FilesKt__UtilsKt(Function2.this, (File) obj, (IOException) obj2);
|
|
return copyRecursively$lambda$0$FilesKt__UtilsKt;
|
|
}
|
|
}).iterator();
|
|
while (it.hasNext()) {
|
|
File next = it.next();
|
|
if (!next.exists()) {
|
|
if (onError.invoke(next, new NoSuchFileException(next, null, "The source file doesn't exist.", 2, null)) == OnErrorAction.TERMINATE) {
|
|
return false;
|
|
}
|
|
} else {
|
|
File file2 = new File(target, toRelativeString(next, file));
|
|
if (file2.exists() && (!next.isDirectory() || !file2.isDirectory())) {
|
|
if (z) {
|
|
if (file2.isDirectory()) {
|
|
if (!deleteRecursively(file2)) {
|
|
}
|
|
} else if (!file2.delete()) {
|
|
}
|
|
}
|
|
if (onError.invoke(file2, new FileAlreadyExistsException(next, file2, "The destination file already exists.")) == OnErrorAction.TERMINATE) {
|
|
return false;
|
|
}
|
|
}
|
|
if (next.isDirectory()) {
|
|
file2.mkdirs();
|
|
} else {
|
|
boolean z2 = z;
|
|
if (copyTo$default(next, file2, z2, 0, 4, null).length() == next.length() || onError.invoke(next, new IOException("Source file wasn't copied completely, length of destination file differs.")) != OnErrorAction.TERMINATE) {
|
|
z = z2;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
} catch (TerminateException unused) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static /* synthetic */ boolean copyRecursively$default(File file, File file2, boolean z, Function2 function2, int i, Object obj) {
|
|
if ((i & 2) != 0) {
|
|
z = false;
|
|
}
|
|
if ((i & 4) != 0) {
|
|
function2 = new Function2() { // from class: kotlin.io.FilesKt__UtilsKt$copyRecursively$1
|
|
@Override // kotlin.jvm.functions.Function2
|
|
public final Void invoke(File file3, IOException exception) {
|
|
Intrinsics.checkNotNullParameter(file3, "<unused var>");
|
|
Intrinsics.checkNotNullParameter(exception, "exception");
|
|
throw exception;
|
|
}
|
|
};
|
|
}
|
|
return copyRecursively(file, file2, z, function2);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public static final Unit copyRecursively$lambda$0$FilesKt__UtilsKt(Function2 function2, File f, IOException e) {
|
|
Intrinsics.checkNotNullParameter(f, "f");
|
|
Intrinsics.checkNotNullParameter(e, "e");
|
|
if (function2.invoke(f, e) != OnErrorAction.TERMINATE) {
|
|
return Unit.INSTANCE;
|
|
}
|
|
throw new TerminateException(f);
|
|
}
|
|
|
|
@NotNull
|
|
public static final File copyTo(@NotNull File file, @NotNull File target, boolean z, int i) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(target, "target");
|
|
if (file.exists()) {
|
|
if (target.exists()) {
|
|
if (z) {
|
|
if (!target.delete()) {
|
|
throw new FileAlreadyExistsException(file, target, "Tried to overwrite the destination, but failed to delete it.");
|
|
}
|
|
} else {
|
|
throw new FileAlreadyExistsException(file, target, "The destination file already exists.");
|
|
}
|
|
}
|
|
if (file.isDirectory()) {
|
|
if (target.mkdirs()) {
|
|
return target;
|
|
}
|
|
throw new FileSystemException(file, target, "Failed to create target directory.");
|
|
}
|
|
File parentFile = target.getParentFile();
|
|
if (parentFile != null) {
|
|
parentFile.mkdirs();
|
|
}
|
|
FileInputStream fileInputStream = new FileInputStream(file);
|
|
try {
|
|
FileOutputStream fileOutputStream = new FileOutputStream(target);
|
|
try {
|
|
ByteStreamsKt.copyTo(fileInputStream, fileOutputStream, i);
|
|
CloseableKt.closeFinally(fileOutputStream, null);
|
|
CloseableKt.closeFinally(fileInputStream, null);
|
|
return target;
|
|
} finally {
|
|
}
|
|
} finally {
|
|
}
|
|
} else {
|
|
throw new NoSuchFileException(file, null, "The source file doesn't exist.", 2, null);
|
|
}
|
|
}
|
|
|
|
public static /* synthetic */ File copyTo$default(File file, File file2, boolean z, int i, int i2, Object obj) {
|
|
if ((i2 & 2) != 0) {
|
|
z = false;
|
|
}
|
|
if ((i2 & 4) != 0) {
|
|
i = 8192;
|
|
}
|
|
return copyTo(file, file2, z, i);
|
|
}
|
|
|
|
@Deprecated(message = "Avoid creating temporary directories in the default temp location with this function due to too wide permissions on the newly created directory. Use kotlin.io.path.createTempDirectory instead.")
|
|
@NotNull
|
|
public static final File createTempDir(@NotNull String prefix, @Nullable String str, @Nullable File file) {
|
|
Intrinsics.checkNotNullParameter(prefix, "prefix");
|
|
File createTempFile = File.createTempFile(prefix, str, file);
|
|
createTempFile.delete();
|
|
if (createTempFile.mkdir()) {
|
|
Intrinsics.checkNotNull(createTempFile);
|
|
return createTempFile;
|
|
}
|
|
throw new IOException("Unable to create temporary directory " + createTempFile + '.');
|
|
}
|
|
|
|
public static /* synthetic */ File createTempDir$default(String str, String str2, File file, int i, Object obj) {
|
|
if ((i & 1) != 0) {
|
|
str = "tmp";
|
|
}
|
|
if ((i & 2) != 0) {
|
|
str2 = null;
|
|
}
|
|
if ((i & 4) != 0) {
|
|
file = null;
|
|
}
|
|
return createTempDir(str, str2, file);
|
|
}
|
|
|
|
@Deprecated(message = "Avoid creating temporary files in the default temp location with this function due to too wide permissions on the newly created file. Use kotlin.io.path.createTempFile instead or resort to java.io.File.createTempFile.")
|
|
@NotNull
|
|
public static final File createTempFile(@NotNull String prefix, @Nullable String str, @Nullable File file) {
|
|
Intrinsics.checkNotNullParameter(prefix, "prefix");
|
|
File createTempFile = File.createTempFile(prefix, str, file);
|
|
Intrinsics.checkNotNullExpressionValue(createTempFile, "createTempFile(...)");
|
|
return createTempFile;
|
|
}
|
|
|
|
public static /* synthetic */ File createTempFile$default(String str, String str2, File file, int i, Object obj) {
|
|
if ((i & 1) != 0) {
|
|
str = "tmp";
|
|
}
|
|
if ((i & 2) != 0) {
|
|
str2 = null;
|
|
}
|
|
if ((i & 4) != 0) {
|
|
file = null;
|
|
}
|
|
return createTempFile(str, str2, file);
|
|
}
|
|
|
|
public static final boolean deleteRecursively(@NotNull File file) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
while (true) {
|
|
boolean z = true;
|
|
for (File file2 : FilesKt__FileTreeWalkKt.walkBottomUp(file)) {
|
|
if (file2.delete() || !file2.exists()) {
|
|
if (z) {
|
|
break;
|
|
}
|
|
}
|
|
z = false;
|
|
}
|
|
return z;
|
|
}
|
|
}
|
|
|
|
public static final boolean endsWith(@NotNull File file, @NotNull File other) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(other, "other");
|
|
FilePathComponents components = FilesKt__FilePathComponentsKt.toComponents(file);
|
|
FilePathComponents components2 = FilesKt__FilePathComponentsKt.toComponents(other);
|
|
if (components2.isRooted()) {
|
|
return Intrinsics.areEqual(file, other);
|
|
}
|
|
int size = components.getSize() - components2.getSize();
|
|
if (size < 0) {
|
|
return false;
|
|
}
|
|
return components.getSegments().subList(size, components.getSize()).equals(components2.getSegments());
|
|
}
|
|
|
|
@NotNull
|
|
public static final String getExtension(@NotNull File file) {
|
|
String substringAfterLast;
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
String name = file.getName();
|
|
Intrinsics.checkNotNullExpressionValue(name, "getName(...)");
|
|
substringAfterLast = StringsKt__StringsKt.substringAfterLast(name, '.', RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED);
|
|
return substringAfterLast;
|
|
}
|
|
|
|
@NotNull
|
|
public static final String getInvariantSeparatorsPath(@NotNull File file) {
|
|
String replace$default;
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
char c2 = File.separatorChar;
|
|
String path = file.getPath();
|
|
Intrinsics.checkNotNullExpressionValue(path, "getPath(...)");
|
|
if (c2 != '/') {
|
|
replace$default = StringsKt__StringsJVMKt.replace$default(path, c2, '/', false, 4, (Object) null);
|
|
return replace$default;
|
|
}
|
|
return path;
|
|
}
|
|
|
|
@NotNull
|
|
public static final String getNameWithoutExtension(@NotNull File file) {
|
|
String substringBeforeLast$default;
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
String name = file.getName();
|
|
Intrinsics.checkNotNullExpressionValue(name, "getName(...)");
|
|
substringBeforeLast$default = StringsKt__StringsKt.substringBeforeLast$default(name, ".", (String) null, 2, (Object) null);
|
|
return substringBeforeLast$default;
|
|
}
|
|
|
|
@NotNull
|
|
public static final File normalize(@NotNull File file) {
|
|
String joinToString$default;
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
FilePathComponents components = FilesKt__FilePathComponentsKt.toComponents(file);
|
|
File root = components.getRoot();
|
|
List<File> normalize$FilesKt__UtilsKt = normalize$FilesKt__UtilsKt(components.getSegments());
|
|
String separator = File.separator;
|
|
Intrinsics.checkNotNullExpressionValue(separator, "separator");
|
|
joinToString$default = CollectionsKt___CollectionsKt.joinToString$default(normalize$FilesKt__UtilsKt, separator, null, null, 0, null, null, 62, null);
|
|
return resolve(root, joinToString$default);
|
|
}
|
|
|
|
private static final FilePathComponents normalize$FilesKt__UtilsKt(FilePathComponents filePathComponents) {
|
|
return new FilePathComponents(filePathComponents.getRoot(), normalize$FilesKt__UtilsKt(filePathComponents.getSegments()));
|
|
}
|
|
|
|
@NotNull
|
|
public static final File relativeTo(@NotNull File file, @NotNull File base) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(base, "base");
|
|
return new File(toRelativeString(file, base));
|
|
}
|
|
|
|
@Nullable
|
|
public static final File relativeToOrNull(@NotNull File file, @NotNull File base) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(base, "base");
|
|
String relativeStringOrNull$FilesKt__UtilsKt = toRelativeStringOrNull$FilesKt__UtilsKt(file, base);
|
|
if (relativeStringOrNull$FilesKt__UtilsKt != null) {
|
|
return new File(relativeStringOrNull$FilesKt__UtilsKt);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@NotNull
|
|
public static final File relativeToOrSelf(@NotNull File file, @NotNull File base) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(base, "base");
|
|
String relativeStringOrNull$FilesKt__UtilsKt = toRelativeStringOrNull$FilesKt__UtilsKt(file, base);
|
|
if (relativeStringOrNull$FilesKt__UtilsKt != null) {
|
|
return new File(relativeStringOrNull$FilesKt__UtilsKt);
|
|
}
|
|
return file;
|
|
}
|
|
|
|
@NotNull
|
|
public static final File resolve(@NotNull File file, @NotNull File relative) {
|
|
boolean endsWith$default;
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(relative, "relative");
|
|
if (FilesKt__FilePathComponentsKt.isRooted(relative)) {
|
|
return relative;
|
|
}
|
|
String file2 = file.toString();
|
|
Intrinsics.checkNotNullExpressionValue(file2, "toString(...)");
|
|
if (file2.length() != 0) {
|
|
char c2 = File.separatorChar;
|
|
endsWith$default = StringsKt__StringsKt.endsWith$default((CharSequence) file2, c2, false, 2, (Object) null);
|
|
if (!endsWith$default) {
|
|
return new File(file2 + c2 + relative);
|
|
}
|
|
}
|
|
return new File(file2 + relative);
|
|
}
|
|
|
|
@NotNull
|
|
public static final File resolveSibling(@NotNull File file, @NotNull File relative) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(relative, "relative");
|
|
FilePathComponents components = FilesKt__FilePathComponentsKt.toComponents(file);
|
|
return resolve(resolve(components.getRoot(), components.getSize() == 0 ? new File("..") : components.subPath(0, components.getSize() - 1)), relative);
|
|
}
|
|
|
|
public static final boolean startsWith(@NotNull File file, @NotNull File other) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(other, "other");
|
|
FilePathComponents components = FilesKt__FilePathComponentsKt.toComponents(file);
|
|
FilePathComponents components2 = FilesKt__FilePathComponentsKt.toComponents(other);
|
|
if (Intrinsics.areEqual(components.getRoot(), components2.getRoot()) && components.getSize() >= components2.getSize()) {
|
|
return components.getSegments().subList(0, components2.getSize()).equals(components2.getSegments());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@NotNull
|
|
public static final String toRelativeString(@NotNull File file, @NotNull File base) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(base, "base");
|
|
String relativeStringOrNull$FilesKt__UtilsKt = toRelativeStringOrNull$FilesKt__UtilsKt(file, base);
|
|
if (relativeStringOrNull$FilesKt__UtilsKt != null) {
|
|
return relativeStringOrNull$FilesKt__UtilsKt;
|
|
}
|
|
throw new IllegalArgumentException("this and base files have different roots: " + file + " and " + base + '.');
|
|
}
|
|
|
|
private static final String toRelativeStringOrNull$FilesKt__UtilsKt(File file, File file2) {
|
|
List drop;
|
|
FilePathComponents normalize$FilesKt__UtilsKt = normalize$FilesKt__UtilsKt(FilesKt__FilePathComponentsKt.toComponents(file));
|
|
FilePathComponents normalize$FilesKt__UtilsKt2 = normalize$FilesKt__UtilsKt(FilesKt__FilePathComponentsKt.toComponents(file2));
|
|
if (Intrinsics.areEqual(normalize$FilesKt__UtilsKt.getRoot(), normalize$FilesKt__UtilsKt2.getRoot())) {
|
|
int size = normalize$FilesKt__UtilsKt2.getSize();
|
|
int size2 = normalize$FilesKt__UtilsKt.getSize();
|
|
int min = Math.min(size2, size);
|
|
int i = 0;
|
|
while (i < min && Intrinsics.areEqual(normalize$FilesKt__UtilsKt.getSegments().get(i), normalize$FilesKt__UtilsKt2.getSegments().get(i))) {
|
|
i++;
|
|
}
|
|
StringBuilder sb = new StringBuilder();
|
|
int i2 = size - 1;
|
|
if (i <= i2) {
|
|
while (!Intrinsics.areEqual(normalize$FilesKt__UtilsKt2.getSegments().get(i2).getName(), "..")) {
|
|
sb.append("..");
|
|
if (i2 != i) {
|
|
sb.append(File.separatorChar);
|
|
}
|
|
if (i2 != i) {
|
|
i2--;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
if (i < size2) {
|
|
if (i < size) {
|
|
sb.append(File.separatorChar);
|
|
}
|
|
drop = CollectionsKt___CollectionsKt.drop(normalize$FilesKt__UtilsKt.getSegments(), i);
|
|
String separator = File.separator;
|
|
Intrinsics.checkNotNullExpressionValue(separator, "separator");
|
|
CollectionsKt___CollectionsKt.joinTo$default(drop, sb, separator, null, null, 0, null, null, 124, null);
|
|
}
|
|
return sb.toString();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static final List<File> normalize$FilesKt__UtilsKt(List<? extends File> list) {
|
|
ArrayList arrayList = new ArrayList(list.size());
|
|
for (File file : list) {
|
|
String name = file.getName();
|
|
if (Intrinsics.areEqual(name, ".")) {
|
|
Unit unit = Unit.INSTANCE;
|
|
} else if (Intrinsics.areEqual(name, "..")) {
|
|
if (arrayList.isEmpty() || Intrinsics.areEqual(((File) CollectionsKt.last((List) arrayList)).getName(), "..")) {
|
|
arrayList.add(file);
|
|
}
|
|
} else {
|
|
arrayList.add(file);
|
|
}
|
|
}
|
|
return arrayList;
|
|
}
|
|
|
|
@NotNull
|
|
public static final File resolve(@NotNull File file, @NotNull String relative) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(relative, "relative");
|
|
return resolve(file, new File(relative));
|
|
}
|
|
|
|
@NotNull
|
|
public static final File resolveSibling(@NotNull File file, @NotNull String relative) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(relative, "relative");
|
|
return resolveSibling(file, new File(relative));
|
|
}
|
|
|
|
public static final boolean startsWith(@NotNull File file, @NotNull String other) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(other, "other");
|
|
return startsWith(file, new File(other));
|
|
}
|
|
|
|
public static final boolean endsWith(@NotNull File file, @NotNull String other) {
|
|
Intrinsics.checkNotNullParameter(file, "<this>");
|
|
Intrinsics.checkNotNullParameter(other, "other");
|
|
return endsWith(file, new File(other));
|
|
}
|
|
}
|