All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.marklogic.http.PartInputStream Maven / Gradle / Ivy

/*
 * Copyright 2003-2019 MarkLogic Corporation
 *
 * 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.marklogic.http;

import java.io.IOException;
import java.io.InputStream;

public class PartInputStream extends InputStream {
    private MultipartSplitter splitter;

    /**
     * Create a new PartInputStream backed by a given (shared)
     * MultipartSplitter. This input stream will return bytes until the underlying
     * MultipartSplitter detects an end-of-part boundary, in which case the
     * PartInputStream returns a length of -1 as an EOF indicator.
     */
    public PartInputStream(MultipartSplitter splitter) {
        this.splitter = splitter;
    }

    // implement InputStream

    /*
     * Returns the number of bytes that can be read (or skipped over) from this input stream without
     * blocking by the next caller of a method for this input stream.
     */
    @Override
    public int available() {
        return (0);
    }

    /**
     * Closes this input stream and releases any system resources associated with the stream.
     */
    @Override
    public void close() {
        splitter = null;
    }

    /**
     * Marks the current position in this input stream.
     */
    @Override
    public void mark(int readlimit) {
        throw new UnsupportedOperationException();
    }

    /**
     * Tests if this input stream supports the mark and reset methods.
     */
    @Override
    public boolean markSupported() {
        return false;
    }

    /**
     * Reads the next byte of data from the input stream.
     */
    @Override
    public int read() throws IOException {
        return splitter.read();
    }

    /**
     * Reads some number of bytes from the input stream and stores them into the buffer array b.
     */
    @Override
    public int read(byte[] buf) throws IOException {
        return read(buf, 0, buf.length);
    }

    /**
     * Reads up to len bytes of data from the input stream into an array of bytes. An
     * attempt is made to read as many as len bytes, but a smaller number may be read,
     * possibly zero. The number of bytes actually read is returned as an integer.
     * 

*

* This method blocks until input data is available, end of file is detected, or an exception is * thrown. *

*

* If buf is null, a NullPointerException is thrown. *

*

* If offset is negative, or len is negative, or * offset+len is greater than the length of the array buf, then an * IndexOutOfBoundsException is thrown. *

*

* If len is zero, then no bytes are read and 0 is returned; * otherwise, there is an attempt to read at least one byte. If no byte is available because the * stream is at end of file, the value -1 is returned; otherwise, at least one byte * is read and stored into buf. *

*

* In every case, elements buf[0] through buf[offset] and elements * buf[offset+len] through buf[buf.length-1] are unaffected. *

*

* If the first byte cannot be read for any reason other than end of file, then an * IOException is thrown. In particular, an IOException is thrown if * the input stream has been closed. * * @param buf * - the buffer into which the data is read. * @param offset * - the start offset in array b at which the data is written. * @param len * - the maximum number of bytes to read. * @return the total number of bytes read into the buffer, or -1 if there is no * more data because the end of the stream has been reached. * @throws IOException * - if an I/O error occurs. */ @Override public int read(byte[] buf, int offset, int len) throws IOException { if (splitter == null) { throw new IOException("Splitter stream closed"); } if (offset < 0 || len < 0 || offset + len > buf.length) { throw new IndexOutOfBoundsException("offset or length error"); } return (splitter.read(buf, offset, len)); } /** * Repositions this stream to the position at the time the mark method was last called on this * input stream. */ @Override public void reset() { throw new UnsupportedOperationException(); } // FIXME: Check this logic, should pass through to splitter? /** * Skips over and discards n bytes of data from this input stream. */ @Override public long skip(long n) throws IOException { // Not 1<<31; int only goes up to 2^31-1 if (n < (1 << 30)) { byte[] buf = new byte[(int)n]; return read(buf, 0, (int)n); } byte[] buf = new byte[1 << 30]; long resultLen = 0; long residualLen = n; for (int m = (1 << 30); m < n; m += (1 << 30), residualLen -= (1 << 30)) { resultLen += read(buf, 0, (residualLen < (1 << 30) ? (int)residualLen : (1 << 30))); } return resultLen; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy