public static String unfold()

in geronimo-mail_2.1_spec/src/main/java/jakarta/mail/internet/MimeUtility.java [1197:1298]


    public static String unfold(final String s) {
        // if folding is disable, unfolding is also.  Return the string unchanged.
        if (!SessionUtil.getBooleanProperty(MIME_FOLDTEXT, true)) {
            return s;
        }

        // if there are no line break characters in the string, we can just return this.
        if (s.indexOf('\n') < 0 && s.indexOf('\r') < 0) {
            return s;
        }

        // we need to scan and fix things up.
        final int length = s.length();

        final StringBuffer newString = new StringBuffer(length);

        // scan the entire string
        for (int i = 0; i < length; i++) {
            final char ch = s.charAt(i);

            // we have a backslash.  In folded strings, escape characters are only processed as such if
            // they precede line breaks.  Otherwise, we leave it be.
            if (ch == '\\') {
                // escape at the very end?  Just add the character.
                if (i == length - 1) {
                    newString.append(ch);
                }
                else {
                    final int nextChar = s.charAt(i + 1);

                    // naked newline?  Add the new line to the buffer, and skip the escape char.
                    if (nextChar == '\n') {
                        newString.append('\n');
                        i++;
                    }
                    else if (nextChar == '\r') {
                        // just the CR left?  Add it, removing the escape.
                        if (i == length - 2 || s.charAt(i + 2) != '\r') {
                            newString.append('\r');
                            i++;
                        }
                        else {
                            // toss the escape, add both parts of the CRLF, and skip over two chars.
                            newString.append('\r');
                            newString.append('\n');
                            i += 2;
                        }
                    }
                    else {
                        // an escape for another purpose, just copy it over.
                        newString.append(ch);
                    }
                }
            }
            // we have an unescaped line break
            else if (ch == '\n' || ch == '\r') {
                // remember the position in case we need to backtrack.
                boolean CRLF = false;

                if (ch == '\r') {
                    // check to see if we need to step over this.
                    if (i < length - 1 && s.charAt(i + 1) == '\n') {
                        i++;
                        // flag the type so we know what we might need to preserve.
                        CRLF = true;
                    }
                }

                // get a temp position scanner.
                final int scan = i + 1;

                // does a blank follow this new line?  we need to scrap the new line and reduce the leading blanks
                // down to a single blank.
                if (scan < length && s.charAt(scan) == ' ') {
                    // add the character
                    newString.append(' ');

                    // scan over the rest of the blanks
                    i = scan + 1;
                    while (i < length && s.charAt(i) == ' ') {
                        i++;
                    }
                    // we'll increment down below, so back up to the last blank as the current char.
                    i--;
                }
                else {
                    // we must keep this line break.  Append the appropriate style.
                    if (CRLF) {
                        newString.append("\r\n");
                    }
                    else {
                        newString.append(ch);
                    }
                }
            }
            else {
                // just a normal, ordinary character
                newString.append(ch);
            }
        }
        return newString.toString();
    }