001package net.bramp.ffmpeg.nut; 002 003import static com.google.common.base.Preconditions.checkNotNull; 004 005import com.google.common.io.CountingInputStream; 006import java.io.DataInput; 007import java.io.DataInputStream; 008import java.io.IOException; 009import java.io.InputStream; 010import net.bramp.ffmpeg.io.CRC32InputStream; 011 012/** A DataInputStream that implements a couple of custom FFmpeg Nut datatypes. */ 013public class NutDataInputStream implements DataInput { 014 015 final DataInputStream in; 016 final CRC32InputStream crc; 017 final CountingInputStream count; 018 019 // These are for debugging, remove later 020 long startCrcRange; 021 long endCrcRange; 022 023 public NutDataInputStream(InputStream in) { 024 checkNotNull(in); 025 this.count = new CountingInputStream(in); 026 this.crc = new CRC32InputStream(count); 027 this.in = new DataInputStream(crc); 028 } 029 030 public void resetCRC() { 031 startCrcRange = count.getCount(); 032 crc.resetCrc(); 033 } 034 035 public long getCRC() { 036 endCrcRange = count.getCount(); 037 return crc.getValue(); 038 } 039 040 // Read a simple var int up to 32 bits 041 public int readVarInt() throws IOException { 042 boolean more; 043 int result = 0; 044 do { 045 int b = in.readUnsignedByte(); 046 more = (b & 0x80) == 0x80; 047 result = 128 * result + (b & 0x7F); 048 049 // TODO Check for int overflow 050 } while (more); 051 052 return result; 053 } 054 055 // Read a simple var int up to 64 bits 056 public long readVarLong() throws IOException { 057 boolean more; 058 long result = 0; 059 do { 060 int b = in.readUnsignedByte(); 061 more = (b & 0x80) == 0x80; 062 result = 128 * result + (b & 0x7F); 063 064 // TODO Check for long overflow 065 } while (more); 066 067 return result; 068 } 069 070 // Read a signed var int 071 public long readSignedVarInt() throws IOException { 072 long temp = readVarLong() + 1; 073 if ((temp & 1) == 1) { 074 return -(temp >> 1); 075 } 076 return temp >> 1; 077 } 078 079 // Read a array with a varint prefixed length 080 public byte[] readVarArray() throws IOException { 081 int len = (int) readVarLong(); 082 byte[] result = new byte[len]; 083 in.read(result); 084 return result; 085 } 086 087 // Returns the start code, OR frame_code if the code doesn't start with 'N' 088 public long readStartCode() throws IOException { 089 byte frameCode = in.readByte(); 090 if (frameCode != 'N') { 091 return (long) (frameCode & 0xff); 092 } 093 094 // Otherwise read the remaining 64bit startCode 095 byte[] buffer = new byte[8]; 096 buffer[0] = frameCode; 097 readFully(buffer, 1, 7); 098 return (((long) buffer[0] << 56) 099 + ((long) (buffer[1] & 255) << 48) 100 + ((long) (buffer[2] & 255) << 40) 101 + ((long) (buffer[3] & 255) << 32) 102 + ((long) (buffer[4] & 255) << 24) 103 + ((buffer[5] & 255) << 16) 104 + ((buffer[6] & 255) << 8) 105 + ((buffer[7] & 255) << 0)); 106 } 107 108 public long offset() { 109 return count.getCount(); 110 } 111 112 @Override 113 public void readFully(byte[] b) throws IOException { 114 in.readFully(b); 115 } 116 117 @Override 118 public void readFully(byte[] b, int off, int len) throws IOException { 119 in.readFully(b, off, len); 120 } 121 122 @Override 123 public int skipBytes(int n) throws IOException { 124 return in.skipBytes(n); 125 } 126 127 @Override 128 public boolean readBoolean() throws IOException { 129 return in.readBoolean(); 130 } 131 132 @Override 133 public byte readByte() throws IOException { 134 return in.readByte(); 135 } 136 137 @Override 138 public int readUnsignedByte() throws IOException { 139 return in.readUnsignedByte(); 140 } 141 142 @Override 143 public short readShort() throws IOException { 144 return in.readShort(); 145 } 146 147 @Override 148 public int readUnsignedShort() throws IOException { 149 return in.readUnsignedShort(); 150 } 151 152 @Override 153 public char readChar() throws IOException { 154 return in.readChar(); 155 } 156 157 @Override 158 public int readInt() throws IOException { 159 return in.readInt(); 160 } 161 162 @Override 163 public long readLong() throws IOException { 164 return in.readLong(); 165 } 166 167 @Override 168 public float readFloat() throws IOException { 169 return in.readFloat(); 170 } 171 172 @Override 173 public double readDouble() throws IOException { 174 return in.readDouble(); 175 } 176 177 @Override 178 @Deprecated 179 public String readLine() throws IOException { 180 return in.readLine(); 181 } 182 183 @Override 184 public String readUTF() throws IOException { 185 return in.readUTF(); 186 } 187}