/** Returns the cache entry with the specified key if it exists, null otherwise. */ @Override public synchronized Entry get(String key) { CacheHeader entry = mEntries.get(key); // 获取摘要 // if the entry does not exist, return. if (entry == null) { return null; } File file = getFileForKey(key); // 获取文件 CountingInputStream cis = null; try { cis = new CountingInputStream(new FileInputStream(file)); CacheHeader.readHeader(cis); // eat header文件的具体内容在摘要之后,所有先读取摘要,将当前读取位置移动到摘要之后 byte[] data = streamToBytes(cis, (int) (file.length() - cis.bytesRead)); // 当前位置移动到摘要之后,读取缓存内容 return entry.toCacheEntry(data); // 根据读取的缓存内容,结合缓存摘要,生成Cache.Entry对象 } catch (IOException e) { VolleyLog.d("%s: %s", file.getAbsolutePath(), e.toString()); remove(key); // 发生异常则删除异常缓存 return null; } finally { if (cis != null) { try { cis.close(); } catch (IOException ioe) { return null; } } } }
/** Returns the cache entry with the specified key if it exists, null otherwise. */ @Override public synchronized Entry get(String key) { CacheHeader entry = mEntries.get(key); // if the entry does not exist, return. if (entry == null) { return null; } File file = getFileForKey(key); CountingInputStream cis = null; try { cis = new CountingInputStream(new BufferedInputStream(new FileInputStream(file))); CacheHeader.readHeader(cis); // eat header byte[] data = streamToBytes(cis, (int) (file.length() - cis.bytesRead)); return entry.toCacheEntry(data); } catch (IOException e) { VolleyLog.d("%s: %s", file.getAbsolutePath(), e.toString()); remove(key); return null; } finally { if (cis != null) { try { cis.close(); } catch (IOException ioe) { return null; } } } }
/** Test that constructor offsets work */ @Test public void testConstructor() throws Exception { CountingInputStream cis; cis = new CountingInputStream(NULL_INPUTSTREAM, 5l); assertEquals(5l, cis.getPos()); cis.close(); cis = new CountingInputStream(NULL_INPUTSTREAM, 500000000000l); assertEquals(500000000000l, cis.getPos()); cis.close(); }
public static void compareMapFiles(MapLoader expectedSavegame, MapLoader actualSavegame) throws IOException, MapLoadException, ClassNotFoundException { System.out.println( "Comparing expected '" + expectedSavegame + "' with actual '" + actualSavegame + "' (uncompressed!)"); try (InputStream expectedStream = RemakeMapLoader.getMapInputStream(expectedSavegame.getListedMap()); CountingInputStream actualStream = new CountingInputStream( RemakeMapLoader.getMapInputStream(actualSavegame.getListedMap()))) { MapFileHeader expectedHeader = MapFileHeader.readFromStream(expectedStream); MatchConstants.init(new NetworkTimer(true), 0L); MatchConstants.deserialize(new ObjectInputStream(expectedStream)); int expectedTime = MatchConstants.clock().getTime(); ExtendedRandom expectedRandom = MatchConstants.random(); MatchConstants.clearState(); MapFileHeader actualHeader = MapFileHeader.readFromStream(actualStream); MatchConstants.init(new NetworkTimer(true), 1L); MatchConstants.deserialize(new ObjectInputStream(actualStream)); int actualTime = MatchConstants.clock().getTime(); ExtendedRandom actualRandom = MatchConstants.random(); MatchConstants.clearState(); assertEquals(expectedHeader.getBaseMapId(), actualHeader.getBaseMapId()); assertEquals(expectedTime, actualTime); // Test the random behavior a bit to have a high probability of equality. An equals method // does not exist for Random. assertEquals(expectedRandom.nextInt(), actualRandom.nextInt()); assertEquals(expectedRandom.nextInt(), actualRandom.nextInt()); assertEquals(expectedRandom.nextInt(), actualRandom.nextInt()); int e, a; while (((e = expectedStream.read()) != -1) & ((a = actualStream.read()) != -1)) { assertEquals("difference at (uncompressed) byte " + actualStream.getByteCounter(), e, a); } assertEquals("files have different lengths (uncompressed)", e, a); } }
/** Test that single byte reads have the desired effect on counting */ @Test public void testSingleByteReads() throws Exception { ByteArrayInputStream bais = new ByteArrayInputStream(TEST_ARRAY); CountingInputStream cis = new CountingInputStream(bais); assertEquals((long) 0, cis.getPos()); for (long i = 0; i < TEST_ARRAY.length; i++) { assertEquals(i, cis.getPos()); int b = cis.read(); assertEquals((byte) b, TEST_ARRAY[(int) i]); assertEquals(i + 1, cis.getPos()); } assertEquals(TEST_ARRAY.length, cis.getPos()); assertEquals(-1, cis.read()); assertEquals(TEST_ARRAY.length, cis.getPos()); }
/** Test that two byte reads have the desired effect on counting */ @Test public void testTwoByteReads() throws Exception { ByteArrayInputStream bais = new ByteArrayInputStream(TEST_ARRAY); CountingInputStream cis = new CountingInputStream(bais); assertEquals((long) 0, cis.getPos()); for (long i = 0; i < TEST_ARRAY.length / 2; i++) { assertEquals(i * 2, cis.getPos()); final byte[] read = new byte[2]; final int rtr = cis.read(read); assertEquals(rtr, read.length); assertEquals(read[0], TEST_ARRAY[(int) i * 2]); assertEquals(read[1], TEST_ARRAY[(int) (i * 2) + 1]); assertEquals("offset after read i=" + i + "; ", (i * 2) + read.length, cis.getPos()); } assertEquals(TEST_ARRAY.length, cis.getPos()); assertEquals(-1, cis.read()); assertEquals(TEST_ARRAY.length, cis.getPos()); }
private void validate() throws IOException { long compressedSize = inCounted.getSize(); // Validate Compressed Size and Uncompressed Size if they were // present in Block Header. if ((compressedSizeInHeader != -1 && compressedSizeInHeader != compressedSize) || (uncompressedSizeInHeader != -1 && uncompressedSizeInHeader != uncompressedSize)) throw new CorruptedInputException(); // Block Padding bytes must be zeros. while ((compressedSize++ & 3) != 0) if (inData.readUnsignedByte() != 0x00) throw new CorruptedInputException(); // Validate the integrity check. byte[] storedCheck = new byte[check.getSize()]; inData.readFully(storedCheck); if (!Arrays.equals(check.finish(), storedCheck)) throw new CorruptedInputException("Integrity check (" + check.getName() + ") does not match"); }
@Override public int read(byte[] buf, int off, int len) throws IOException { if (endReached) return -1; int ret = filterChain.read(buf, off, len); if (ret > 0) { check.update(buf, off, ret); uncompressedSize += ret; // Catch invalid values. long compressedSize = inCounted.getSize(); if (compressedSize < 0 || compressedSize > compressedSizeLimit || uncompressedSize < 0 || (uncompressedSizeInHeader != -1 && uncompressedSize > uncompressedSizeInHeader)) throw new CorruptedInputException(); // Check the Block integrity as soon as possible: // - The filter chain shouldn't return less than requested // unless it hit the end of the input. // - If the uncompressed size is known, we know when there // shouldn't be more data coming. We still need to read // one byte to let the filter chain catch errors and to // let it read end of payload marker(s). if (ret < len || uncompressedSize == uncompressedSizeInHeader) { if (filterChain.read() != -1) throw new CorruptedInputException(); validate(); endReached = true; } } else if (ret == -1) { validate(); endReached = true; } return ret; }
public int getProgress() { return in.getByteCount(); }
public long getUnpaddedSize() { return headerSize + inCounted.getSize() + check.getSize(); }