Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.clustermate.service.msg;
  
  import java.io.*;
  
  import org.slf4j.Logger;
  
  
Simple (but not naive) StreamingResponseContent implementation used for returning content for inlined entries.
 
     implements StreamingResponseContent
 {
     private final Logger LOG = LoggerFactory.getLogger(getClass());
 
     // NOTE: changed from 8k to 16k in 
     
We can reuse read buffers as they are somewhat costly to allocate, reallocate all the time.
 
     final protected static BufferRecycler _bufferRecycler = new BufferRecycler(16000);
 
     /*
     /**********************************************************************
     /* Data to stream out
     /**********************************************************************
      */
     
     private final File _file;
 
     private final ByteContainer _data;
 	
     private final long _dataOffset;
 	
     private final long _dataLength;
 
     /*
     /**********************************************************************
     /* Metadata...
     /**********************************************************************
      */
 
     private final Compression _compression;

    
Content length as reported when caller asks for it; -1 if not known.
 
     private final long _contentLength;
     
     /*
     /**********************************************************************
     /* Construction
     /**********************************************************************
      */
     
     public StreamingResponseContentImpl(ByteContainer dataByteRange range,
             long contentLength)
     {
         if (data == null) {
             throw new IllegalArgumentException();
         }
          = data;
         // Range request? let's tweak offsets if so...
         if (range == null) {
              = -1L;
              = -1L;
              = contentLength;
         } else {
              = range.getStart();
              = range.calculateLength();
              = ;
         }
          = null;
          = null;
     }
 
     public StreamingResponseContentImpl(File fCompression compByteRange range,
             long contentLength)
     {
          = null;
         if (range == null) {
              = -1L;
              = -1L;
              = contentLength;
         } else {
             // Range can be stored in offset..
              = range.getStart();
              = range.calculateLength();
              = ;
         }
         = f;
         = comp;
    }
    @Override
    public long getLength()
    {
        return ;
    }
    @SuppressWarnings("resource")
    @Override
    public void writeContent(OutputStream outthrows IOException
    {
        /* Inline data is simple, because we have already decompressed it
         * if and as necessary; so all we do is just write is out.
         */
        if ( != null) {
            if ( <= 0L) {
                .writeBytes(out);
            } else { // casts are safe; inlined data relatively small
                .writeBytes(out, (int, (int);
            }
            return;
        }
        InputStream in = new FileInputStream();
        // First: LZF has special optimization to use, if we are to copy the whole thing:
        if (( == .) && ( == -1)) {
    	        LZFInputStream lzfIn = new LZFInputStream(in);
    	        try {
    	            lzfIn.readAndWrite(out);
    	        } finally {
    	            _close(lzfIn);
    	        }
    	        return;
        }
        // otherwise default handling via explicit copying
        final BufferRecycler.Holder bufferHolder = .getHolder();        
        final byte[] copyBuffer = bufferHolder.borrowBuffer();
        in = Compressors.uncompressingStream(in);
        // First: anything to skip (only the case for range requests)?
        if ( > 0) {
            long skipped = 0L;
            long toSkip = ;
            while (toSkip > 0) {
                long count = in.skip(toSkip);
                if (count <= 0L) { // should not occur really...
                    throw new IOException("Failed to skip more than "+skipped+" bytes (needed to skip "++")");
                }
                skipped += count;
                toSkip -= count;
            }
        }
        // Second: output the whole thing, or just subset?
        try {
            if ( < 0) { // all of it
                int count;
                while ((count = in.read(copyBuffer)) > 0) {
                    out.write(copyBuffer, 0, count);
                }
                return;
            }
            // Just some of it
            long left = ;
    	    
            while (left > 0) {
                int count = in.read(copyBuffer, 0, (int) Math.min(copyBuffer.lengthleft));
                if (count <= 0) {
                    break;
                }
                out.write(copyBuffer, 0, count);
                left -= count;
            }
            // Sanity check; can't fix or add headers as output has been written...
            if (left > 0) {
                .error("Failed to write request Range %d-%d (from File {}): only wrote {} bytes",
    	                new Object[] { ++1, .getAbsolutePath(),
    	                -left });
            }
        } finally {
            bufferHolder.returnBuffer(copyBuffer);
            _close(in);
        }
    }
    private final void _close(InputStream in)
    {
        try {
            in.close();
        } catch (IOException e) {
            .warn("Failed to close file '{}': {}"e.getMessage());
        }
    }
    
    /*
    /**********************************************************************
    /* Methods for helping testing
    /**********************************************************************
     */
    public boolean hasFile() { return  != null; }
    public boolean inline() { return  != null; }
New to GrepCode? Check out our FAQ X