001 /*
002 * Copyright 2005 The Apache Software Foundation.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.vafer.jdeb.ar;
017
018 import java.io.IOException;
019 import java.io.InputStream;
020
021 /**
022 * To be replace by commons compress once released
023 *
024 * @author Torsten Curdt <tcurdt@vafer.org>
025 */
026 public class ArInputStream extends InputStream implements ArConstants {
027
028 private final InputStream input;
029 private long offset = 0;
030
031 public ArInputStream( final InputStream pInput ) {
032 input = pInput;
033 }
034
035 public ArEntry getNextEntry() throws IOException {
036
037 if (offset == 0) {
038 final byte[] expected = HEADER;
039 final byte[] realized = new byte[expected.length];
040 final int read = input.read(realized);
041 if (read != expected.length) {
042 throw new IOException("failed to read header");
043 }
044 for (int i = 0; i < expected.length; i++) {
045 if (expected[i] != realized[i]) {
046 throw new IOException("invalid header " + new String(realized));
047 }
048 }
049 }
050
051 if (input.available() == 0) {
052 return null;
053 }
054
055 if (offset % 2 != 0) {
056 read();
057 }
058
059 final byte[] name = new byte[FIELD_SIZE_NAME];
060 final byte[] lastmodified = new byte[FIELD_SIZE_LASTMODIFIED];
061 final byte[] userid = new byte[FIELD_SIZE_UID];
062 final byte[] groupid = new byte[FIELD_SIZE_GID];
063 final byte[] filemode = new byte[FIELD_SIZE_MODE];
064 final byte[] length = new byte[FIELD_SIZE_LENGTH];
065
066 read(name);
067 read(lastmodified);
068 read(userid);
069 read(groupid);
070 read(filemode);
071 read(length);
072
073 final byte[] expected = ENTRY_TERMINATOR;
074 final byte[] realized = new byte[expected.length];
075 final int read = input.read(realized);
076 if (read != expected.length) {
077 throw new IOException("failed to read entry header");
078 }
079 for (int i = 0; i < expected.length; i++) {
080 if (expected[i] != realized[i]) {
081 throw new IOException("invalid entry header. not read the content?");
082 }
083 }
084
085 return new ArEntry(new String(name).trim(), Long.parseLong(new String(length).trim()));
086 }
087
088
089 public int read() throws IOException {
090 final int ret = input.read();
091 offset++;
092 return ret;
093 }
094
095 public void close() throws IOException {
096 input.close();
097 super.close();
098 }
099
100 }