• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.core.format;
2 
3 import java.io.*;
4 
5 import com.fasterxml.jackson.core.JsonFactory;
6 
7 /**
8  * Interface used to expose beginning of a data file to data format
9  * detection code.
10  */
11 public interface InputAccessor
12 {
13     /**
14      * Method to call to check if more input is available.
15      * Since this may result in more content to be read (at least
16      * one more byte), a {@link IOException} may get thrown.
17      */
hasMoreBytes()18     boolean hasMoreBytes() throws IOException;
19 
20     /**
21      * Returns next byte available, if any; if no more bytes are
22      * available, will throw {@link java.io.EOFException}.
23      */
nextByte()24     byte nextByte() throws IOException;
25 
26     /**
27      * Method that can be called to reset accessor to read from beginning
28      * of input.
29      */
reset()30     void reset();
31 
32     /*
33     /**********************************************************
34     /* Standard implementation
35     /**********************************************************
36      */
37 
38     /**
39      * Basic implementation that reads data from given
40      * {@link InputStream} and buffers it as necessary.
41      */
42     class Std implements InputAccessor
43     {
44         protected final InputStream _in;
45 
46         protected final byte[] _buffer;
47 
48         protected final int _bufferedStart;
49 
50         /**
51          * End of valid bytes in the buffer (points to one past last valid)
52          */
53         protected int _bufferedEnd;
54 
55         /**
56          * Pointer to next available buffered byte in {@link #_buffer}.
57          */
58         protected int _ptr;
59 
60         /**
61          * Constructor used when content to check is available via
62          * input stream and must be read.
63          */
Std(InputStream in, byte[] buffer)64         public Std(InputStream in, byte[] buffer)
65         {
66             _in = in;
67             _buffer = buffer;
68             _bufferedStart = 0;
69             _ptr = 0;
70             _bufferedEnd = 0;
71         }
72 
73         /**
74          * Constructor used when the full input (or at least enough leading bytes
75          * of full input) is available.
76          */
Std(byte[] inputDocument)77         public Std(byte[] inputDocument) {
78             this(inputDocument, 0, inputDocument.length);
79         }
80 
81         /**
82          * Constructor used when the full input (or at least enough leading bytes
83          * of full input) is available.
84          *
85          * @since 2.1
86          */
Std(byte[] inputDocument, int start, int len)87         public Std(byte[] inputDocument, int start, int len)
88         {
89             _in = null;
90             _buffer = inputDocument;
91             _ptr = start;
92             _bufferedStart = start;
93             _bufferedEnd = start+len;
94         }
95 
96         @Override
hasMoreBytes()97         public boolean hasMoreBytes() throws IOException
98         {
99             if (_ptr < _bufferedEnd) { // already got more
100                 return true;
101             }
102             if (_in == null) { // nowhere to read from
103                 return false;
104             }
105             int amount = _buffer.length - _ptr;
106             if (amount < 1) { // can not load any more
107                 return false;
108             }
109             int count = _in.read(_buffer, _ptr, amount);
110             if (count <= 0) { // EOF
111                 return false;
112             }
113             _bufferedEnd += count;
114             return true;
115         }
116 
117        @Override
nextByte()118         public byte nextByte() throws IOException
119         {
120             // should we just try loading more automatically?
121             if (_ptr >= _bufferedEnd) {
122                 if (!hasMoreBytes()) {
123                     throw new EOFException("Failed auto-detect: could not read more than "+_ptr+" bytes (max buffer size: "+_buffer.length+")");
124                 }
125             }
126             return _buffer[_ptr++];
127         }
128 
129         @Override
reset()130         public void reset() {
131             _ptr = _bufferedStart;
132         }
133 
134         /*
135         /**********************************************************
136         /* Extended API for DataFormatDetector/Matcher
137         /**********************************************************
138          */
139 
createMatcher(JsonFactory match, MatchStrength matchStrength)140         public DataFormatMatcher createMatcher(JsonFactory match, MatchStrength matchStrength)
141         {
142             return new DataFormatMatcher(_in, _buffer, _bufferedStart, (_bufferedEnd - _bufferedStart),
143                     match, matchStrength);
144         }
145     }
146 }
147