More suitiable for Android

This commit is contained in:
topjohnwu 2019-04-01 23:52:32 -04:00
parent 219e8b25f1
commit 35bdb657b6
4 changed files with 24 additions and 138 deletions

View File

@ -1,109 +0,0 @@
package org.kamranzafar.jtar;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Helps dealing with file permissions.
*/
public class PermissionUtils {
/**
* XXX: When using standard Java permissions, we treat 'owner' and 'group' equally and give no
* permissions for 'others'.
*/
private static enum StandardFilePermission {
EXECUTE(0110), WRITE(0220), READ(0440);
private int mode;
private StandardFilePermission(int mode) {
this.mode = mode;
}
}
private static Map<PosixFilePermission, Integer> posixPermissionToInteger = new HashMap<>();
static {
posixPermissionToInteger.put(PosixFilePermission.OWNER_EXECUTE, 0100);
posixPermissionToInteger.put(PosixFilePermission.OWNER_WRITE, 0200);
posixPermissionToInteger.put(PosixFilePermission.OWNER_READ, 0400);
posixPermissionToInteger.put(PosixFilePermission.GROUP_EXECUTE, 0010);
posixPermissionToInteger.put(PosixFilePermission.GROUP_WRITE, 0020);
posixPermissionToInteger.put(PosixFilePermission.GROUP_READ, 0040);
posixPermissionToInteger.put(PosixFilePermission.OTHERS_EXECUTE, 0001);
posixPermissionToInteger.put(PosixFilePermission.OTHERS_WRITE, 0002);
posixPermissionToInteger.put(PosixFilePermission.OTHERS_READ, 0004);
}
/**
* Get file permissions in octal mode, e.g. 0755.
*
* Note: it uses `java.nio.file.attribute.PosixFilePermission` if OS supports this, otherwise reverts to
* using standard Java file operations, e.g. `java.io.File#canExecute()`. In the first case permissions will
* be precisely as reported by the OS, in the second case 'owner' and 'group' will have equal permissions and
* 'others' will have no permissions, e.g. if file on Windows OS is `read-only` permissions will be `0550`.
*
* @throws NullPointerException if file is null.
* @throws IllegalArgumentException if file does not exist.
*/
public static int permissions(File f) {
if(f == null) {
throw new NullPointerException("File is null.");
}
if(!f.exists()) {
throw new IllegalArgumentException("File " + f + " does not exist.");
}
return isPosix ? posixPermissions(f) : standardPermissions(f);
}
private static final boolean isPosix = FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
private static int posixPermissions(File f) {
int number = 0;
try {
Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(f.toPath());
for (Map.Entry<PosixFilePermission, Integer> entry : posixPermissionToInteger.entrySet()) {
if (permissions.contains(entry.getKey())) {
number += entry.getValue();
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return number;
}
private static Set<StandardFilePermission> readStandardPermissions(File f) {
Set<StandardFilePermission> permissions = new HashSet<>();
if(f.canExecute()) {
permissions.add(StandardFilePermission.EXECUTE);
}
if(f.canWrite()) {
permissions.add(StandardFilePermission.WRITE);
}
if(f.canRead()) {
permissions.add(StandardFilePermission.READ);
}
return permissions;
}
private static Integer standardPermissions(File f) {
int number = 0;
Set<StandardFilePermission> permissions = readStandardPermissions(f);
for (StandardFilePermission permission : permissions) {
number += permission.mode;
}
return number;
}
}

View File

@ -87,7 +87,7 @@ public class TarEntry {
}
public void setName(String name) {
header.name = new StringBuffer(name);
header.name = new StringBuilder(name);
}
public int getUserId() {
@ -111,7 +111,7 @@ public class TarEntry {
}
public void setUserName(String userName) {
header.userName = new StringBuffer(userName);
header.userName = new StringBuilder(userName);
}
public String getGroupName() {
@ -119,7 +119,7 @@ public class TarEntry {
}
public void setGroupName(String groupName) {
header.groupName = new StringBuffer(groupName);
header.groupName = new StringBuilder(groupName);
}
public void setIds(int userId, int groupId) {
@ -173,7 +173,7 @@ public class TarEntry {
* Extract header from File
*/
public void extractTarHeader(String entryName) {
int permissions = PermissionUtils.permissions(file);
int permissions = file.isDirectory() ? 0755 : 0644; // Default umask
header = TarHeader.createHeader(entryName, file.length(), file.lastModified() / 1000, file.isDirectory(), permissions);
}

View File

@ -106,7 +106,7 @@ public class TarHeader {
public static final int USTAR_FILENAME_PREFIX = 155;
// Header values
public StringBuffer name;
public StringBuilder name;
public int mode;
public int userId;
public int groupId;
@ -114,30 +114,25 @@ public class TarHeader {
public long modTime;
public int checkSum;
public byte linkFlag;
public StringBuffer linkName;
public StringBuffer magic; // ustar indicator and version
public StringBuffer userName;
public StringBuffer groupName;
public StringBuilder linkName;
public StringBuilder magic; // ustar indicator and version
public StringBuilder userName;
public StringBuilder groupName;
public int devMajor;
public int devMinor;
public StringBuffer namePrefix;
public StringBuilder namePrefix;
public TarHeader() {
this.magic = new StringBuffer(TarHeader.USTAR_MAGIC);
this.magic = new StringBuilder(TarHeader.USTAR_MAGIC);
this.name = new StringBuffer();
this.linkName = new StringBuffer();
String user = System.getProperty("user.name", "");
if (user.length() > 31)
user = user.substring(0, 31);
this.name = new StringBuilder();
this.linkName = new StringBuilder();
this.userId = 0;
this.groupId = 0;
this.userName = new StringBuffer(user);
this.groupName = new StringBuffer("");
this.namePrefix = new StringBuffer();
this.userName = new StringBuilder();
this.groupName = new StringBuilder();
this.namePrefix = new StringBuilder();
}
/**
@ -151,8 +146,8 @@ public class TarHeader {
* The number of header bytes to parse.
* @return The header's entry name.
*/
public static StringBuffer parseName(byte[] header, int offset, int length) {
StringBuffer result = new StringBuffer(length);
public static StringBuilder parseName(byte[] header, int offset, int length) {
StringBuilder result = new StringBuilder(length);
int end = offset + length;
for (int i = offset; i < end; ++i) {
@ -175,7 +170,7 @@ public class TarHeader {
* The number of header bytes to parse.
* @return The number of bytes in a header's entry name.
*/
public static int getNameBytes(StringBuffer name, byte[] buf, int offset, int length) {
public static int getNameBytes(StringBuilder name, byte[] buf, int offset, int length) {
int i;
for (i = 0; i < length && i < name.length(); ++i) {
@ -207,14 +202,14 @@ public class TarHeader {
name = TarUtils.trim(name.replace(File.separatorChar, '/'), '/');
TarHeader header = new TarHeader();
header.linkName = new StringBuffer("");
header.linkName = new StringBuilder();
header.mode = permissions;
if (name.length() > 100) {
header.namePrefix = new StringBuffer(name.substring(0, name.lastIndexOf('/')));
header.name = new StringBuffer(name.substring(name.lastIndexOf('/') + 1));
header.namePrefix = new StringBuilder(name.substring(0, name.lastIndexOf('/')));
header.name = new StringBuilder(name.substring(name.lastIndexOf('/') + 1));
} else {
header.name = new StringBuffer(name);
header.name = new StringBuilder(name);
}
if (dir) {
header.linkFlag = TarHeader.LF_DIR;

View File

@ -71,7 +71,7 @@ public class TarUtils {
}
public static String trim(String s, char c) {
StringBuffer tmp = new StringBuffer(s);
StringBuilder tmp = new StringBuilder(s);
for (int i = 0; i < tmp.length(); i++) {
if (tmp.charAt(i) != c) {
break;