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

Last change on this file since 13061 was 13061, checked in by Don-vip, 6 years ago

fix #15505 - update to metadata-extractor 2.10.1

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