1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package Torello.Java;

class RightTrimAll
{
    static String run(String s)
    {
        // SPECIAL-CASE: There is
        if (s.length() == 0) return s;

        char[]  cArr        = s.toCharArray();
        int     targetPos   = 0;
        int     nlPos       = 0;


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Set up the Loop Variables 'nlPos' and 'targetPos'
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        // SKIP: Skip past all leading new-lines.  They don't need to be moved at all in the loop!
        for (nlPos=0; (nlPos < cArr.length) && (cArr[nlPos] == '\n'); nlPos++);

        // SPECIAL-CASE: The String had **ONLY** new-lines in it...
        if (nlPos == cArr.length) return s;


        // IF THERE WERE LEADING NEWLINES:
        // 
        // AFTER-LOOP:  'nlPos' will be pointing at the character IMMEDIATELY-AFTER the last
        //              leading newline.
        // 
        // NOTE:        IF there WERE NOT leading newlines, 'nlPos' is ZERO,
        //              which is just fine for assigning to 'targetPos' anyway!

        targetPos = nlPos;


        // Continue to initialize 'nlPos' and 'targetPos'
        // 
        // PART ONE: Find the FIRST new-line AFTER the first CONTENT-CONTAINING line.
        // 
        // PART TWO: Set 'targetPos' to the last character that is non-white-space.  'targetPos'
        //           will be incremented-by-one later to point to white-space.

        while ((++nlPos < cArr.length) && (cArr[nlPos] != '\n'))
            if (! Character.isWhitespace(cArr[nlPos]))
                targetPos = nlPos;


        // Now increment 'targetPos' because in MOST-CASES it will be pointing to the last
        // non-white-space character in the first line.  (and we *CANNOT* clobber that character!)
        // 
        // HOWEVER: if 'targetPos' is still pointing at White-Space (after the previous loop),
        //          then it must be that the ENTIRE-FIRST-LINE was BLANK!

        if (! Character.isWhitespace(cArr[targetPos])) targetPos++;

        // SPECIAL-CASE: The first CONTENT-FUL LINE is the ONLY-LINE in the text.
        // 
        //          ===> Return the input-String.
        //               **BUT** make sure to right-trim that CONTENT-FUL line.

        if (nlPos == cArr.length) return s.substring(0, targetPos);


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Now do the 'Shifting Loop'
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        while (nlPos < cArr.length)
        {
            int nextNLPos               = nlPos + 1;
            int lastNonWhiteSpacePos    = nlPos;
            int sourcePos               = nlPos;


            // Compute 'nextNLPos' and 'lastNonWhiteSpacePos': In the Example *SUBSTRING* Below:
            // "...\nHello, How are you?   \n..."
            //
            // NEW-LINE-POS was set to the first '\n' you see in the above-String
            // The '?' is the LAST-NON-WHITE-SPACE
            // The '\n' after that is the NEXT-NEWLINE-POS

            while ((nextNLPos < cArr.length) && (cArr[nextNLPos] != '\n'))
            {
                if (! Character.isWhitespace(cArr[nextNLPos]))
                    lastNonWhiteSpacePos = nextNLPos;

                nextNLPos++;
            }

            // Shift all characters BEGINNING with the OLD new-line position (since 'sourcePos')
            // is initiliazed with 'nlPos') ... 
            // 
            // AGAIN: Shift all characters beginning with 'nlPos' UP-TO-AND-INCLUDING
            // 'lastNonWhiteSpacePos' for the NEXT line of text to the appropriate position.

            while (sourcePos <= lastNonWhiteSpacePos) cArr[targetPos++] = cArr[sourcePos++];

            // The next loop-iteration will start with the next line in the text.
            nlPos = nextNLPos;
        }

        return new String(cArr, 0, targetPos);
    }
}