source: josm/trunk/src/com/drew/lang/StreamReader.java@ 9514

Last change on this file since 9514 was 8132, checked in by Don-vip, 9 years ago

fix #11162 - update to metadata-extractor 2.7.2

File size: 3.3 KB
Line 
1/*
2 * Copyright 2002-2015 Drew Noakes
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * More information about this project is available at:
17 *
18 * https://drewnoakes.com/code/exif/
19 * https://github.com/drewnoakes/metadata-extractor
20 */
21
22package com.drew.lang;
23
24import com.drew.lang.annotations.NotNull;
25
26import java.io.EOFException;
27import java.io.IOException;
28import java.io.InputStream;
29
30/**
31 *
32 * @author Drew Noakes https://drewnoakes.com
33 */
34public class StreamReader extends SequentialReader
35{
36 @NotNull
37 private final InputStream _stream;
38
39 @SuppressWarnings("ConstantConditions")
40 public StreamReader(@NotNull InputStream stream)
41 {
42 if (stream == null)
43 throw new NullPointerException();
44
45 _stream = stream;
46 }
47
48 @Override
49 protected byte getByte() throws IOException
50 {
51 int value = _stream.read();
52 if (value == -1)
53 throw new EOFException("End of data reached.");
54 return (byte)value;
55 }
56
57 @NotNull
58 @Override
59 public byte[] getBytes(int count) throws IOException
60 {
61 byte[] bytes = new byte[count];
62 int totalBytesRead = 0;
63
64 while (totalBytesRead != count) {
65 final int bytesRead = _stream.read(bytes, totalBytesRead, count - totalBytesRead);
66 if (bytesRead == -1)
67 throw new EOFException("End of data reached.");
68 totalBytesRead += bytesRead;
69 assert(totalBytesRead <= count);
70 }
71
72 return bytes;
73 }
74
75 @Override
76 public void skip(long n) throws IOException
77 {
78 if (n < 0)
79 throw new IllegalArgumentException("n must be zero or greater.");
80
81 long skippedCount = skipInternal(n);
82
83 if (skippedCount != n)
84 throw new EOFException(String.format("Unable to skip. Requested %d bytes but skipped %d.", n, skippedCount));
85 }
86
87 @Override
88 public boolean trySkip(long n) throws IOException
89 {
90 if (n < 0)
91 throw new IllegalArgumentException("n must be zero or greater.");
92
93 return skipInternal(n) == n;
94 }
95
96 private long skipInternal(long n) throws IOException
97 {
98 // It seems that for some streams, such as BufferedInputStream, that skip can return
99 // some smaller number than was requested. So loop until we either skip enough, or
100 // InputStream.skip returns zero.
101 //
102 // See http://stackoverflow.com/questions/14057720/robust-skipping-of-data-in-a-java-io-inputstream-and-its-subtypes
103 //
104 long skippedTotal = 0;
105 while (skippedTotal != n) {
106 long skipped = _stream.skip(n - skippedTotal);
107 assert(skipped >= 0);
108 skippedTotal += skipped;
109 if (skipped == 0)
110 break;
111 }
112 return skippedTotal;
113 }
114}
Note: See TracBrowser for help on using the repository browser.