--- /dev/null
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+import java.io.File;
+import java.util.Date;
+
+/**
+ * @author Kamran Zafar
+ *
+ */
+public class TarEntry {
+ protected File file;
+ protected TarHeader header;
+
+ private TarEntry() {
+ this.file = null;
+ header = new TarHeader();
+ }
+
+ public TarEntry(File file, String entryName) {
+ this();
+ this.file = file;
+ this.extractTarHeader(entryName);
+ }
+
+ public TarEntry(byte[] headerBuf) {
+ this();
+ this.parseTarHeader(headerBuf);
+ }
+
+ /**
+ * Constructor to create an entry from an existing TarHeader object.
+ *
+ * This method is useful to add new entries programmatically (e.g. for
+ * adding files or directories that do not exist in the file system).
+ *
+ * @param header
+ *
+ */
+ public TarEntry(TarHeader header) {
+ this.file = null;
+ this.header = header;
+ }
+
+ @Override
+ public boolean equals(Object it) {
+ if (!(it instanceof TarEntry)) {
+ return false;
+ }
+ return header.name.toString().equals(
+ ((TarEntry) it).header.name.toString());
+ }
+
+ @Override
+ public int hashCode() {
+ return header.name.hashCode();
+ }
+
+ public boolean isDescendent(TarEntry desc) {
+ return desc.header.name.toString().startsWith(header.name.toString());
+ }
+
+ public TarHeader getHeader() {
+ return header;
+ }
+
+ public String getName() {
+ String name = header.name.toString();
+ if (header.namePrefix != null
+ && !header.namePrefix.toString().equals("")) {
+ name = header.namePrefix.toString() + "/" + name;
+ }
+
+ return name;
+ }
+
+ public void setName(String name) {
+ header.name = new StringBuffer(name);
+ }
+
+ public int getUserId() {
+ return header.userId;
+ }
+
+ public void setUserId(int userId) {
+ header.userId = userId;
+ }
+
+ public int getGroupId() {
+ return header.groupId;
+ }
+
+ public void setGroupId(int groupId) {
+ header.groupId = groupId;
+ }
+
+ public String getUserName() {
+ return header.userName.toString();
+ }
+
+ public void setUserName(String userName) {
+ header.userName = new StringBuffer(userName);
+ }
+
+ public String getGroupName() {
+ return header.groupName.toString();
+ }
+
+ public void setGroupName(String groupName) {
+ header.groupName = new StringBuffer(groupName);
+ }
+
+ public void setIds(int userId, int groupId) {
+ this.setUserId(userId);
+ this.setGroupId(groupId);
+ }
+
+ public void setModTime(long time) {
+ header.modTime = time / 1000;
+ }
+
+ public void setModTime(Date time) {
+ header.modTime = time.getTime() / 1000;
+ }
+
+ public Date getModTime() {
+ return new Date(header.modTime * 1000);
+ }
+
+ public File getFile() {
+ return this.file;
+ }
+
+ public long getSize() {
+ return header.size;
+ }
+
+ public void setSize(long size) {
+ header.size = size;
+ }
+
+ /**
+ * Checks if the org.kamrazafar.jtar entry is a directory
+ *
+ * @return
+ */
+ public boolean isDirectory() {
+ if (this.file != null) {
+ return this.file.isDirectory();
+ }
+
+ if (header != null) {
+ if (header.linkFlag == TarHeader.LF_DIR) {
+ return true;
+ }
+
+ if (header.name.toString().endsWith("/")) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Extract header from File
+ *
+ * @param entryName
+ */
+ public void extractTarHeader(String entryName) {
+ header = TarHeader.createHeader(entryName, file.length(),
+ file.lastModified() / 1000, file.isDirectory());
+ }
+
+ /**
+ * Calculate checksum
+ *
+ * @param buf
+ * @return
+ */
+ public long computeCheckSum(byte[] buf) {
+ long sum = 0;
+
+ for (int i = 0; i < buf.length; ++i) {
+ sum += 255 & buf[i];
+ }
+
+ return sum;
+ }
+
+ /**
+ * Writes the header to the byte buffer
+ *
+ * @param outbuf
+ */
+ public void writeEntryHeader(byte[] outbuf) {
+ int offset = 0;
+
+ offset = TarHeader.getNameBytes(header.name, outbuf, offset,
+ TarHeader.NAMELEN);
+ offset = Octal.getOctalBytes(header.mode, outbuf, offset,
+ TarHeader.MODELEN);
+ offset = Octal.getOctalBytes(header.userId, outbuf, offset,
+ TarHeader.UIDLEN);
+ offset = Octal.getOctalBytes(header.groupId, outbuf, offset,
+ TarHeader.GIDLEN);
+
+ long size = header.size;
+
+ offset = Octal.getLongOctalBytes(size, outbuf, offset,
+ TarHeader.SIZELEN);
+ offset = Octal.getLongOctalBytes(header.modTime, outbuf, offset,
+ TarHeader.MODTIMELEN);
+
+ int csOffset = offset;
+ for (int c = 0; c < TarHeader.CHKSUMLEN; ++c) {
+ outbuf[offset++] = (byte) ' ';
+ }
+
+ outbuf[offset++] = header.linkFlag;
+
+ offset = TarHeader.getNameBytes(header.linkName, outbuf, offset,
+ TarHeader.NAMELEN);
+ offset = TarHeader.getNameBytes(header.magic, outbuf, offset,
+ TarHeader.USTAR_MAGICLEN);
+ offset = TarHeader.getNameBytes(header.userName, outbuf, offset,
+ TarHeader.USTAR_USER_NAMELEN);
+ offset = TarHeader.getNameBytes(header.groupName, outbuf, offset,
+ TarHeader.USTAR_GROUP_NAMELEN);
+ offset = Octal.getOctalBytes(header.devMajor, outbuf, offset,
+ TarHeader.USTAR_DEVLEN);
+ offset = Octal.getOctalBytes(header.devMinor, outbuf, offset,
+ TarHeader.USTAR_DEVLEN);
+ offset = TarHeader.getNameBytes(header.namePrefix, outbuf, offset,
+ TarHeader.USTAR_FILENAME_PREFIX);
+
+ for (; offset < outbuf.length;) {
+ outbuf[offset++] = 0;
+ }
+
+ long checkSum = this.computeCheckSum(outbuf);
+
+ Octal.getCheckSumOctalBytes(checkSum, outbuf, csOffset,
+ TarHeader.CHKSUMLEN);
+ }
+
+ /**
+ * Parses the tar header to the byte buffer
+ *
+ * @param header
+ * @param bh
+ */
+ public void parseTarHeader(byte[] bh) {
+ int offset = 0;
+
+ header.name = TarHeader.parseName(bh, offset, TarHeader.NAMELEN);
+ offset += TarHeader.NAMELEN;
+
+ header.mode = (int) Octal.parseOctal(bh, offset, TarHeader.MODELEN);
+ offset += TarHeader.MODELEN;
+
+ header.userId = (int) Octal.parseOctal(bh, offset, TarHeader.UIDLEN);
+ offset += TarHeader.UIDLEN;
+
+ header.groupId = (int) Octal.parseOctal(bh, offset, TarHeader.GIDLEN);
+ offset += TarHeader.GIDLEN;
+
+ header.size = Octal.parseOctal(bh, offset, TarHeader.SIZELEN);
+ offset += TarHeader.SIZELEN;
+
+ header.modTime = Octal.parseOctal(bh, offset, TarHeader.MODTIMELEN);
+ offset += TarHeader.MODTIMELEN;
+
+ header.checkSum = (int) Octal.parseOctal(bh, offset,
+ TarHeader.CHKSUMLEN);
+ offset += TarHeader.CHKSUMLEN;
+
+ header.linkFlag = bh[offset++];
+
+ header.linkName = TarHeader.parseName(bh, offset, TarHeader.NAMELEN);
+ offset += TarHeader.NAMELEN;
+
+ header.magic = TarHeader
+ .parseName(bh, offset, TarHeader.USTAR_MAGICLEN);
+ offset += TarHeader.USTAR_MAGICLEN;
+
+ header.userName = TarHeader.parseName(bh, offset,
+ TarHeader.USTAR_USER_NAMELEN);
+ offset += TarHeader.USTAR_USER_NAMELEN;
+
+ header.groupName = TarHeader.parseName(bh, offset,
+ TarHeader.USTAR_GROUP_NAMELEN);
+ offset += TarHeader.USTAR_GROUP_NAMELEN;
+
+ header.devMajor = (int) Octal.parseOctal(bh, offset,
+ TarHeader.USTAR_DEVLEN);
+ offset += TarHeader.USTAR_DEVLEN;
+
+ header.devMinor = (int) Octal.parseOctal(bh, offset,
+ TarHeader.USTAR_DEVLEN);
+ offset += TarHeader.USTAR_DEVLEN;
+
+ header.namePrefix = TarHeader.parseName(bh, offset,
+ TarHeader.USTAR_FILENAME_PREFIX);
+ }
+}
\ No newline at end of file