Methods Summary |
---|
protected int | _read(byte[] b, int off, int len)
if (len < 0) throw new IllegalArgumentException
(Messages.getMessage("attach.readLengthError",
"" + len));
if (off < 0) throw new IllegalArgumentException
(Messages.getMessage("attach.readOffsetError",
"" + off));
if (b == null) throw new IllegalArgumentException
(Messages.getMessage("attach.readArrayNullError"));
if (b.length < off + len) throw new IllegalArgumentException
(Messages.getMessage("attach.readArraySizeError",
"" + b.length, "" + len, "" + off));
if (null != streamInError) throw streamInError;
if (0 == len) return 0; //quick.
if(recordLength == 0 && bytesRead == 0 && !moreChunks){
++bytesRead; //odd case no data to read -- give back 0 next time -1;
if(ME){
finalClose();
}
return 0;
}
if (bytesRead >= recordLength && !moreChunks) {
dataPadLength -= readPad(dataPadLength);
if(ME){
finalClose();
}
return -1;
}
int totalbytesread = 0;
int bytes2read = 0;
do {
if (bytesRead >= recordLength && moreChunks)
readHeader(true);
bytes2read = (int) Math.min(recordLength - bytesRead,
(long) len - totalbytesread);
bytes2read = (int) Math.min(recordLength - bytesRead,
(long) len - totalbytesread);
try {
bytes2read = is.read(b, off + totalbytesread,
bytes2read);
} catch (IOException e) {
streamInError = e;
throw e;
}
if (0 < bytes2read) {
totalbytesread += bytes2read;
bytesRead += bytes2read;
}
}
while (bytes2read > -1 && totalbytesread < len &&
(bytesRead < recordLength || moreChunks));
if (0 > bytes2read) {
if (moreChunks) {
streamInError = new IOException(Messages.getMessage(
"attach.DimeStreamError0"));
throw streamInError;
}
if (bytesRead < recordLength) {
streamInError = new IOException(Messages.getMessage
("attach.DimeStreamError1",
"" + (recordLength - bytesRead)));
throw streamInError;
}
if (!ME) {
streamInError = new IOException(Messages.getMessage(
"attach.DimeStreamError0"));
throw streamInError;
}
//in theory the last chunk of data should also have been padded, but lets be tolerant of that.
dataPadLength = 0;
} else if (bytesRead >= recordLength) {
//get rid of pading.
try {
dataPadLength -= readPad(dataPadLength);
} catch (IOException e) {
//in theory the last chunk of data should also have been padded, but lets be tolerant of that.
if (!ME) throw e;
else {
dataPadLength = 0;
streamInError = null;
}
}
}
if (bytesRead >= recordLength && ME) {
finalClose();
}
return totalbytesread >= 0 ? totalbytesread : -1;
|
public synchronized int | available()
if (null != streamInError) throw streamInError;
int chunkAvail = (int) Math.min((long)
Integer.MAX_VALUE, recordLength - bytesRead);
int streamAvail = 0;
try {
streamAvail = is.available();
} catch (IOException e) {
streamInError = e;
throw e;
}
if (chunkAvail == 0 && moreChunks && (12 + dataPadLength)
<= streamAvail) {
dataPadLength -= readPad(dataPadLength);
readHeader(true);
return available();
}
return Math.min(streamAvail, chunkAvail);
|
public void | close()Closes the stream.
This will take care of flushing any remaining data to the strea.
Multiple calls to this method will result in the stream being closed once
and then all subsequent calls being ignored.
synchronized(this){
if (closed) return;
closed = true; //mark it closed.
}
log.debug(Messages.getMessage("bStreamClosed", "" + streamNo));
if (bytesRead < recordLength || moreChunks) {
//We need get this off the stream.
//Easy way to flush through the stream;
byte[] readrest = new byte[1024 * 16];
int bread = 0;
do {
bread = _read(readrest, 0, readrest.length);//should also close the orginal stream.
}
while (bread > -1);
}
dataPadLength -= readPad(dataPadLength);
|
protected void | finalClose()
try{
theEnd = true;
if(null != is) is.close();
}finally{
is= null;
}
|
public java.lang.String | getContentId()Get the id for this stream part.
return id;
|
public DimeTypeNameFormat | getDimeTypeNameFormat()
return tnf;
|
synchronized org.apache.axis.attachments.DimeDelimitedInputStream | getNextStream()Gets the next stream. From the previous using new buffer reading size.
if (null != streamInError) throw streamInError;
if (theEnd) return null;
if (bytesRead < recordLength || moreChunks) //Stream must be read in succession
throw new RuntimeException(Messages.getMessage(
"attach.dimeReadFullyError"));
dataPadLength -= readPad(dataPadLength);
//Create an new dime stream that comes after this one.
return new DimeDelimitedInputStream(this.is);
|
public java.lang.String | getType()Get the type, as read from the header.
return type;
|
public void | mark(int readlimit)Mark the stream.
This is not supported.//do nothing
|
public boolean | markSupported()
return false;
|
protected static synchronized int | newStreamNo() //number of streams produced.
log.debug(Messages.getMessage("streamNo", "" + (streamCount + 1)));
return ++streamCount;
|
public synchronized int | read(byte[] b, int off, int len)Read from the DIME stream.
if (closed) {
dataPadLength -= readPad(dataPadLength);
throw new IOException(Messages.getMessage("streamClosed"));
}
return _read(b, off, len);
|
public int | read(byte[] b)Read from the delimited stream.
return read(b, 0, b.length);
|
public int | read()Read from the boundary delimited stream.
byte[] b = new byte[1];
int read = read(b, 0, 1);
if (read < 0)
return -1; // fixme: should we also check for read != 1?
return (b[0] & 0xff); // convert byte value to a positive int
|
private final int | readFromStream(byte[] b)
return readFromStream(b, 0, b.length);
|
private final int | readFromStream(byte[] b, int start, int length)
if (length == 0) return 0;
int br = 0;
int brTotal = 0;
do {
try {
br = is.read(b, brTotal + start, length - brTotal);
} catch (IOException e) {
streamInError = e;
throw e;
}
if (br > 0) brTotal += br;
}
while (br > -1 && brTotal < length);
return br > -1 ? brTotal : br;
|
void | readHeader(boolean isChunk)
bytesRead = 0; //How many bytes of the record have been read.
if (isChunk) {
if (!moreChunks) throw new RuntimeException(
Messages.getMessage("attach.DimeStreamError2"));
dataPadLength -= readPad(dataPadLength); //Just incase it was left over.
}
byte[] header = new byte[12];
if (header.length != readFromStream(header)) {
streamInError = new IOException(Messages.getMessage(
"attach.DimeStreamError3",
"" + header.length));
throw streamInError;
}
//VERSION
byte version = (byte) ((header[0] >>> 3) & 0x1f);
if (version > DimeMultiPart.CURRENT_VERSION) {
streamInError = new IOException(Messages.getMessage("attach.DimeStreamError4",
"" + version,
"" + DimeMultiPart.CURRENT_VERSION));
throw streamInError;
}
//B, E, C
MB = 0 != (0x4 & header[0]);
ME = 0 != (0x2 & header[0]);
moreChunks = 0 != (0x1 & header[0]);
//TYPE_T
if (!isChunk)
tnf = DimeTypeNameFormat.parseByte((byte) ((header[1] >>> 4) & (byte) 0xf));
//OPTIONS_LENGTH
int optionsLength =
((((int) header[2]) << 8) & 0xff00) | ((int) header[3]);
//ID_LENGTH
int idLength =
((((int) header[4]) << 8) & 0xff00) | ((int) header[5]);
//TYPE_LENGTH
int typeLength = ((((int) header[6]) << 8) & 0xff00)
| ((int) header[7]);
//DATA_LENGTH
recordLength = ((((long) header[8]) << 24) & 0xff000000L) |
((((long) header[9]) << 16) & 0xff0000L) |
((((long) header[10]) << 8) & 0xff00L) |
((long) header[11] & 0xffL);
//OPTIONS + PADDING
if (0 != optionsLength) {
byte[] optBytes = new byte[optionsLength];
if (optionsLength != readFromStream(optBytes)) {
streamInError = new IOException(Messages.getMessage(
"attach.DimeStreamError5",
"" + optionsLength));
throw streamInError;
}
optBytes = null; //Yup throw it away, don't know anything about options.
int pad = DimeBodyPart.dimePadding(optionsLength);
if (pad != readFromStream(header, 0, pad)) {
streamInError = new IOException(
Messages.getMessage("attach.DimeStreamError7"));
throw streamInError;
}
}
// ID + PADDING
if (0 < idLength) {
byte[] idBytes = new byte[ idLength];
if (idLength != readFromStream(idBytes)) {
streamInError = new IOException(
Messages.getMessage("attach.DimeStreamError8"));
throw streamInError;
}
if (idLength != 0 && !isChunk) {
id = new String(idBytes);
}
int pad = DimeBodyPart.dimePadding(idLength);
if (pad != readFromStream(header, 0, pad)) {
streamInError = new IOException(Messages.getMessage(
"attach.DimeStreamError9"));
throw streamInError;
}
}
//TYPE + PADDING
if (0 < typeLength) {
byte[] typeBytes = new byte[typeLength];
if (typeLength != readFromStream(typeBytes)) {
streamInError = new IOException(Messages.getMessage(
"attach.DimeStreamError10"));
throw streamInError;
}
if (typeLength != 0 && !isChunk) {
type = new String(typeBytes);
}
int pad = DimeBodyPart.dimePadding(typeLength);
if (pad != readFromStream(header, 0, pad)) {
streamInError = new IOException(Messages.getMessage(
"attach.DimeStreamError11"));
throw streamInError;
}
}
log.debug("MB:" + MB + ", ME:" + ME + ", CF:" + moreChunks +
"Option length:" + optionsLength +
", ID length:" + idLength +
", typeLength:" + typeLength + ", TYPE_T:" + tnf);
log.debug("id:\"" + id + "\"");
log.debug("type:\"" + type + "\"");
log.debug("recordlength:\"" + recordLength + "\"");
dataPadLength = DimeBodyPart.dimePadding(recordLength);
|
private final int | readPad(int size)
if (0 == size) return 0;
int read = readFromStream(trash, 0, size);
if (size != read) {
streamInError = new IOException(Messages.getMessage(
"attach.dimeNotPaddedCorrectly"));
throw streamInError;
}
return read;
|
public void | reset()
streamInError = new IOException(Messages.getMessage(
"attach.bounday.mns"));
throw streamInError;
|