2 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0, which is available at
6 * http://www.eclipse.org/legal/epl-2.0.
8 * This Source Code may also be made available under the following Secondary
9 * Licenses when the conditions for such availability set forth in the
10 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11 * version 2 with the GNU Classpath Exception, which is available at
12 * https://www.gnu.org/software/classpath/license.html.
14 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
17 package com
.sun
.mail
.mbox
;
20 import javax
.mail
.internet
.*;
21 import javax
.activation
.*;
24 import java
.nio
.charset
.StandardCharsets
;
25 import com
.sun
.mail
.util
.LineInputStream
;
28 * The SunV3Multipart class is an implementation of the abstract Multipart
29 * class that uses SunV3 conventions for the multipart data. <p>
31 * @author Bill Shannon
34 public class SunV3Multipart
extends MimeMultipart
{
35 private boolean parsing
;
38 * Constructs a SunV3Multipart object and its bodyparts from the
39 * given DataSource. <p>
41 * @param ds DataSource, can be a MultipartDataSource
43 public SunV3Multipart(DataSource ds
) throws MessagingException
{
48 * Set the subtype. Throws MethodNotSupportedException.
50 * @param subtype Subtype
52 public void setSubType(String subtype
) throws MessagingException
{
53 throw new MethodNotSupportedException(
54 "can't change SunV3Multipart subtype");
58 * Get the BodyPart referred to by the given ContentID (CID).
59 * Throws MethodNotSupportException.
61 public synchronized BodyPart
getBodyPart(String CID
)
62 throws MessagingException
{
63 throw new MethodNotSupportedException(
64 "SunV3Multipart doesn't support Content-ID");
68 * Update headers. Throws MethodNotSupportException.
70 protected void updateHeaders() throws MessagingException
{
71 throw new MethodNotSupportedException("SunV3Multipart not writable");
75 * Iterates through all the parts and outputs each SunV3 part
76 * separated by a boundary.
78 public void writeTo(OutputStream os
)
79 throws IOException
, MessagingException
{
80 throw new MethodNotSupportedException(
81 "SunV3Multipart writeTo not supported");
84 private static final String boundary
= "----------";
87 * Parse the contents of this multipart message and create the
90 protected synchronized void parse() throws MessagingException
{
92 * If the data has already been parsed, or we're in the middle of
93 * parsing it, there's nothing to do. The latter will occur when
94 * we call addBodyPart, which will call parse again. We really
95 * want to be able to call super.super.addBodyPart.
97 if (parsed
|| parsing
)
100 InputStream in
= null;
103 in
= ds
.getInputStream();
104 if (!(in
instanceof ByteArrayInputStream
) &&
105 !(in
instanceof BufferedInputStream
))
106 in
= new BufferedInputStream(in
);
107 } catch (IOException ex
) {
108 throw new MessagingException("No inputstream from datasource");
109 } catch (RuntimeException ex
) {
110 throw new MessagingException("No inputstream from datasource");
113 byte[] bndbytes
= boundary
.getBytes(StandardCharsets
.ISO_8859_1
);
114 int bl
= bndbytes
.length
;
120 * Skip any kind of junk until we get to the first
123 LineInputStream lin
= new LineInputStream(in
);
124 while ((line
= lin
.readLine()) != null) {
125 if (line
.trim().equals(boundary
))
129 throw new MessagingException("Missing start boundary");
132 * Read and process body parts until we see the
133 * terminating boundary line (or EOF).
137 * Collect the headers for this body part.
139 InternetHeaders headers
= new InternetHeaders(in
);
141 if (!in
.markSupported())
142 throw new MessagingException("Stream doesn't support mark");
144 ByteArrayOutputStream buf
= new ByteArrayOutputStream();
148 * Read and save the content bytes in buf.
150 while ((b
= in
.read()) >= 0) {
151 if (b
== '\r' || b
== '\n') {
153 * Found the end of a line, check whether the
154 * next line is a boundary.
157 in
.mark(bl
+ 4 + 1); // "4" for possible "--\r\n"
158 if (b
== '\r' && in
.read() != '\n') {
162 // read bytes, matching against the boundary
163 for (i
= 0; i
< bl
; i
++)
164 if (in
.read() != bndbytes
[i
])
168 // check for end of line
170 break; // got it! break out of the while loop
173 if (in
.read() != '\n')
175 break; // got it! break out of the while loop
178 // failed to match, reset and proceed normally
185 * Create a SunV3BodyPart to represent this body part.
188 new SunV3BodyPart(headers
, buf
.toByteArray());
193 } catch (IOException e
) {
194 throw new MessagingException("IO Error"); // XXX