Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2013 Square, Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package com.koushikdutta.ion.bitmap;
 
An input stream wrapper that supports unlimited independent cursors for marking and resetting. Each cursor is a token, and it's the caller's responsibility to keep track of these.
 
 final class MarkableInputStream extends InputStream {
     private final InputStream in;
 
     private long offset;
     private long reset;
     private long limit;
 
     private long defaultMark = -1;
 
     public MarkableInputStream(InputStream in) {
         if (!in.markSupported()) {
             in = new BufferedInputStream(in);
         }
         this. = in;
     }

    
Marks this place in the stream so we can reset back to it later.
 
     @Override public void mark(int readLimit) {
          = savePosition(readLimit);
     }

    
Returns an opaque token representing the current position in the stream. Call reset(long) to return to this position in the stream later. It is an error to call reset(long) after consuming more than readLimit bytes from this stream.
 
     public long savePosition(int readLimit) {
         long offsetLimit =  + readLimit;
         if ( < offsetLimit) {
             setLimit(offsetLimit);
         }
         return ;
     }

    
Makes sure that the underlying stream can backtrack the full range from reset thru limit. Since we can't call mark() without also adjusting the reset-to-position on the underlying stream this method resets first and then marks the union of the two byte ranges. On buffered streams this additional cursor motion shouldn't result in any additional I/O.
 
     private void setLimit(long limit) {
         try {
             if ( <  &&  <= this.) {
                 .reset();
                 .mark((int) (limit - ));
                 skip();
             } else {
                  = ;
                 .mark((int) (limit - ));
             }
             this. = limit;
         } catch (IOException e) {
             throw new IllegalStateException("Unable to mark: " + e);
         }
     }

    
Resets the stream to the most recent mark.
 
     @Override public void reset() throws IOException {
         reset();
     }

    
Resets the stream to the position recorded by token.
 
     public void reset(long tokenthrows IOException {
         if ( >  || token < ) {
             throw new IOException("Cannot reset");
         }
         .reset();
         skip(token);
          = token;
     }

    
Skips target - current bytes and returns.
    private void skip(long currentlong targetthrows IOException {
        while (current < target) {
            long skipped = .skip(target - current);
            if (skipped == 0) {
                if (read() == -1) {
                    break// EOF
                } else {
                    skipped = 1;
                }
            }
            current += skipped;
        }
    }
    @Override public int read() throws IOException {
        int result = .read();
        if (result != -1) {
            ++;
        }
        return result;
    }
    @Override public int read(byte[] bufferthrows IOException {
        int count = .read(buffer);
        if (count != -1) {
             += count;
        }
        return count;
    }
    @Override public int read(byte[] bufferint offsetint lengththrows IOException {
        int count = .read(bufferoffsetlength);
        if (count != -1) {
            this. += count;
        }
        return count;
    }
    @Override public long skip(long byteCountthrows IOException {
        long skipped = .skip(byteCount);
         += skipped;
        return skipped;
    }
    @Override public int available() throws IOException {
        return .available();
    }
    @Override public void close() throws IOException {
        .close();
    }
    @Override public boolean markSupported() {
        return .markSupported();
    }
New to GrepCode? Check out our FAQ X