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

Last change on this file since 12288 was 10862, checked in by Don-vip, 8 years ago

update to metadata-extractor 2.9.1

File size: 3.3 KB
Line 
1/*
2 * Copyright 2002-2016 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 public StreamReader(@NotNull InputStream stream)
40 {
41 if (stream == null)
42 throw new NullPointerException();
43
44 _stream = stream;
45 }
46
47 @Override
48 protected byte getByte() throws IOException
49 {
50 int value = _stream.read();
51 if (value == -1)
52 throw new EOFException("End of data reached.");
53 return (byte)value;
54 }
55
56 @NotNull
57 @Override
58 public byte[] getBytes(int count) throws IOException
59 {
60 byte[] bytes = new byte[count];
61 int totalBytesRead = 0;
62
63 while (totalBytesRead != count) {
64 final int bytesRead = _stream.read(bytes, totalBytesRead, count - totalBytesRead);
65 if (bytesRead == -1)
66 throw new EOFException("End of data reached.");
67 totalBytesRead += bytesRead;
68 assert(totalBytesRead <= count);
69 }
70
71 return bytes;
72 }
73
74 @Override
75 public void skip(long n) throws IOException
76 {
77 if (n < 0)
78 throw new IllegalArgumentException("n must be zero or greater.");
79
80 long skippedCount = skipInternal(n);
81
82 if (skippedCount != n)
83 throw new EOFException(String.format("Unable to skip. Requested %d bytes but skipped %d.", n, skippedCount));
84 }
85
86 @Override
87 public boolean trySkip(long n) throws IOException
88 {
89 if (n < 0)
90 throw new IllegalArgumentException("n must be zero or greater.");
91
92 return skipInternal(n) == n;
93 }
94
95 private long skipInternal(long n) throws IOException
96 {
97 // It seems that for some streams, such as BufferedInputStream, that skip can return
98 // some smaller number than was requested. So loop until we either skip enough, or
99 // InputStream.skip returns zero.
100 //
101 // See http://stackoverflow.com/questions/14057720/robust-skipping-of-data-in-a-java-io-inputstream-and-its-subtypes
102 //
103 long skippedTotal = 0;
104 while (skippedTotal != n) {
105 long skipped = _stream.skip(n - skippedTotal);
106 assert(skipped >= 0);
107 skippedTotal += skipped;
108 if (skipped == 0)
109 break;
110 }
111 return skippedTotal;
112 }
113}
Note: See TracBrowser for help on using the repository browser.