Package: ContentLengthUpdater
ContentLengthUpdater
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ContentLengthUpdater(OutputStream, long) |
|
|
|
|
|
||||||||||||||||||||
main(String[]) |
|
|
|
|
|
||||||||||||||||||||
write(byte[]) |
|
|
|
|
|
||||||||||||||||||||
write(byte[], int, int) |
|
|
|
|
|
||||||||||||||||||||
write(int) |
|
|
|
|
|
Coverage
1: /*
2: * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
3: *
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.
7: *
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.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.eclipse.angus.mail.mbox;
18:
19: import java.io.*;
20:
21: /**
22: * Update the Content-Length header in the message written to the stream.
23: */
24: class ContentLengthUpdater extends FilterOutputStream {
25: private String contentLength;
26: private boolean inHeader = true;
27: private boolean sawContentLength = false;
28: private int lastb1 = -1, lastb2 = -1;
29: private StringBuilder line = new StringBuilder();
30:
31: public ContentLengthUpdater(OutputStream os, long contentLength) {
32:         super(os);
33:         this.contentLength = "Content-Length: " + contentLength;
34: }
35:
36: public void write(int b) throws IOException {
37:•        if (inHeader) {
38:          String eol = "\n";
39:          // First, determine if we're still in the header.
40:•         if (b == '\r') {
41:                 // if line terminator is CR
42:•                if (lastb1 == '\r') {
43:                  inHeader = false;
44:                  eol = "\r";
45:                 // else, if line terminator is CRLF
46:•                } else if (lastb1 == '\n' && lastb2 == '\r') {
47:                  inHeader = false;
48:                  eol = "\r\n";
49:                 }
50:          // else, if line terminator is \n
51:•         } else if (b == '\n') {
52:•                if (lastb1 == '\n') {
53:                  inHeader = false;
54:                  eol = "\n";
55:                 }
56:          }
57:
58:          // If we're no longer in the header, and we haven't seen
59:          // a Content-Length header yet, it's time to put one out.
60:•         if (!inHeader && !sawContentLength) {
61:                 out.write(contentLength.getBytes("iso-8859-1"));
62:                 out.write(eol.getBytes("iso-8859-1"));
63:          }
64:
65:          // If we have a full line, see if it's a Content-Length header.
66:•         if (b == '\r' || (b == '\n' && lastb1 != '\r')) {
67:•                if (line.toString().regionMatches(true, 0,
68:                                         "content-length:", 0, 15)) {
69:                  // yup, got it
70:                  sawContentLength = true;
71:                  // put out the new version
72:                  out.write(contentLength.getBytes("iso-8859-1"));
73:                 } else {
74:                  // not a Content-Length header, just write it out
75:                  out.write(line.toString().getBytes("iso-8859-1"));
76:                 }
77:                 line.setLength(0);        // clear buffer for next line
78:          }
79:•         if (b == '\r' || b == '\n')
80:                 out.write(b);        // write out line terminator immediately
81:          else
82:                 line.append((char)b);        // accumulate characters of the line
83:
84:          // rotate saved characters for next time through loop
85:          lastb2 = lastb1;
86:          lastb1 = b;
87:         } else
88:          out.write(b);                // not in the header, just write it out
89: }
90:
91: public void write(byte[] b) throws IOException {
92:•        if (inHeader)
93:          write(b, 0, b.length);
94:         else
95:          out.write(b);
96: }
97:
98: public void write(byte[] b, int off, int len) throws IOException {
99:•        if (inHeader) {
100:•         for (int i = 0 ; i < len ; i++) {
101:                 write(b[off + i]);
102:          }
103:         } else
104:          out.write(b, off, len);
105: }
106:
107: // for testing
108: public static void main(String argv[]) throws Exception {
109:         int b;
110:         ContentLengthUpdater os =
111:          new ContentLengthUpdater(System.out, Long.parseLong(argv[0]));
112:•        while ((b = System.in.read()) >= 0)
113:          os.write(b);
114:         os.flush();
115: }
116: }