001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.attachment;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.PushbackInputStream;
023:
024: public class MimeBodyPartInputStream extends InputStream {
025:
026: PushbackInputStream inStream;
027:
028: boolean boundaryFound;
029:
030: byte[] boundary;
031:
032: public MimeBodyPartInputStream(PushbackInputStream inStreamParam,
033: byte[] boundaryParam) {
034: super ();
035: this .inStream = inStreamParam;
036: this .boundary = boundaryParam;
037: }
038:
039: public int read() throws IOException {
040: boolean needUnread0d0a = false;
041: if (boundaryFound) {
042: return -1;
043: }
044:
045: // read the next value from stream
046: int value = inStream.read();
047: // A problem occurred because all the mime parts tends to have a /r/n
048: // at the end. Making it hard to transform them to correct
049: // DataSources.
050: // This logic introduced to handle it
051: if (value == 13) {
052: value = inStream.read();
053: if (value != 10) {
054: inStream.unread(value);
055: return 13;
056: } else {
057: value = inStream.read();
058: if ((byte) value != boundary[0]) {
059: inStream.unread(value);
060: inStream.unread(10);
061: return 13;
062: } else {
063: needUnread0d0a = true;
064: }
065: }
066: } else if ((byte) value != boundary[0]) {
067: return value;
068: }
069: // read value is the first byte of the boundary. Start matching the
070: // next characters to find a boundary
071: int boundaryIndex = 0;
072: while ((boundaryIndex < boundary.length)
073: && ((byte) value == boundary[boundaryIndex])) {
074: value = inStream.read();
075: boundaryIndex++;
076: }
077: if (boundaryIndex == boundary.length) {
078: // boundary found
079: boundaryFound = true;
080: // read the end of line character
081: if (inStream.read() == 45 && value == 45) {
082: // Last mime boundary should have a succeeding "--"
083: // as we are on it, read the terminating CRLF
084: inStream.read();
085: inStream.read();
086: }
087: return -1;
088: }
089: // Boundary not found. Restoring bytes skipped.
090: // write first skipped byte, push back the rest
091: if (value != -1) {
092: // Stream might have ended
093: inStream.unread(value);
094: }
095: if (needUnread0d0a) {
096: inStream.unread(boundary, 0, boundaryIndex);
097: inStream.unread(10);
098: value = 13;
099: } else {
100: inStream.unread(boundary, 1, boundaryIndex - 1);
101: value = boundary[0];
102: }
103: return value;
104: }
105: }
|