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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | package Torello.Java; class Abbrev { static String print1( final String s, final int abbrevPos, final boolean escapeNewLines, final String abbrevStrInput, final int maxLength ) { if (maxLength < 0) throw new IllegalArgumentException ("The value passed to 'maxLength' " + maxLength + ", may not be zero or negative."); if (abbrevPos < 0) throw new IllegalArgumentException ("You have passed a negative value to parameter 'abbrevPos': " + abbrevPos); // if (abbrevStr == null) abbrevStr = "..."; String abbrevStr = (abbrevStrInput == null) ? "..." : abbrevStrInput; int SLEN = s.length(); int ALEN = abbrevStr.length(); if ((abbrevPos + ALEN) >= maxLength) throw new IllegalArgumentException( "The value passed to parameter 'abbrevPos', " + abbrevPos + ", added to the length " + "of the abbreviation-ellipsis String, \"" + abbrevStr + "\", is longer than the " + "value provided to parameter 'maxLength' " + maxLength ); if (! escapeNewLines) if (SLEN <= maxLength) return s; char[] cArr = new char[maxLength]; // NOTE: Two lines ago, if the input string 's' actually fit, it would already have been // returned (in the case that escaping new-lines was NOT requested) if (! escapeNewLines) { s.getChars(0, abbrevPos, cArr, 0); abbrevStr.getChars(0, ALEN, cArr, abbrevPos); s.getChars(SLEN - (maxLength - (abbrevPos + ALEN)), SLEN, cArr, abbrevPos + ALEN); return new String(cArr); } // Beginning Here: It has been determined that new-lines are to be escaped.... int targetPos=0, srcPos=0, oldSrcPos=0; char c; while ((targetPos < abbrevPos) && (srcPos < SLEN)) // When / If a new-line character is encountered, just insert the "\\n" // substring. Otherwise, normally copy the next character in the source-string if ((c = s.charAt(srcPos++)) == '\n') { cArr[targetPos++] = '\\'; if ((targetPos < cArr.length) && (targetPos < abbrevPos)) cArr[targetPos++] = 'n'; } else cArr[targetPos++] = c; // This is the case where the String was short enough to fit before the // abbrev-pos. if (srcPos == SLEN) return new String(cArr, 0, targetPos); // In this loop, the iteration is done in reverse. It starts at the end of the // source-String, and at the end of the out char-array, and works backward. // LOOP CONTINUES: Continues until the 'abbrevPos' has been reached. oldSrcPos = srcPos; srcPos = SLEN - 1; targetPos = cArr.length - 1; while ((targetPos >= abbrevPos) && (srcPos >= oldSrcPos)) // Here, we need to make sure not to over-write the if ((c = s.charAt(srcPos--)) == '\n') { cArr[targetPos--] = 'n'; if (targetPos >= abbrevPos) cArr[targetPos--] = '\\'; } else cArr[targetPos--] = c; // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // CASE 1: The String didn't fit into the 'maxLength' specified array // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // // so it *DOES* need to be abbreviated. // Copy the abbreviation-string into cArr, and return it. if (srcPos >= oldSrcPos) { abbrevStr.getChars(0, ALEN, cArr, abbrevPos); return new String(cArr); } // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // CASE 2: The String did fit (even with escaped '\n' ==> "\\n") // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // // **AND** It fit PRECISELY-EXACTLY into the output char-array if ((targetPos == (abbrevPos-1)) && (srcPos == (oldSrcPos-1))) return new String(cArr); // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // CASE 3: There is extra-room in the output-String // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // // This means that the copy which just occurred in the previous loop was wrong // There isn't an easy way to avoid this (other than counting new-lines first) // Instead, shift the char-array, and then return it srcPos = targetPos + 1; targetPos = abbrevPos; while (srcPos < cArr.length) cArr[targetPos++] = cArr[srcPos++]; return new String(cArr, 0, targetPos); } static String print2( final String s, final boolean spaceBeforeAbbrev, final boolean escapeNewLines, final String abbrevStrInput, final int maxLength ) { if (maxLength < 0) throw new IllegalArgumentException ("The value passed to 'maxLength' " + maxLength + ", may not be zero or negative."); // If the original String is shorter than the 'maxLength' parameter, return the original // String immediately - **UNLESS** the user has requested to replace new-line characters // with the "Escaped New-Line Sequence "\\n" if (! escapeNewLines) if (s.length() <= maxLength) return s; // The default abbreviation is just the ellipsis. // if (abbrevStr == null) abbrevStr = "..."; final String abbrevStr = (abbrevStrInput == null) ? "..." : abbrevStrInput; char[] cArr = new char[maxLength]; int srcPos = 0; int targetPos = 0; char c = 0; int LEN = s.length(); int END = maxLength - abbrevStr.length() - (spaceBeforeAbbrev ? 1 : 0); if (END < 0) throw new IllegalArgumentException( "The value provided to 'maxLength' was : " + maxLength + ", but this isn't long " + "enough to even contain the abbreviation-string: \"" + (spaceBeforeAbbrev ? " " : "") + abbrevStr + "\"" ); if (! escapeNewLines) // NOTE: Here, the abbreviation will be necessary, so use 'END' instead of 'LEN' // This is because at the top, if the whole-String fit, this method would have // already returned ... if (! escapeNewLines) *above* // ALSO: More efficient at copying String-arrays than a 'for-loop' is 'getChars' s.getChars(0, targetPos = END, cArr, 0); else { while ((targetPos < maxLength) && (srcPos < LEN)) // When / If a new-line character is encountered, just insert the "\\n" // substring. Otherwise, normally copy the next character in the source-string if ((c = s.charAt(srcPos++)) == '\n') { cArr[targetPos++] = '\\'; if (targetPos < cArr.length) cArr[targetPos++] = 'n'; } else cArr[targetPos++] = c; // If every single character from the input String has been appended to the output, // then there is no need to add the abbreviation String (usually, the ellipsis '...'). // In this case, just return original-String immediately (with the escaped newlines). if (srcPos == LEN) return new String(cArr, 0, targetPos); targetPos -= (abbrevStr.length() + (spaceBeforeAbbrev ? 1 : 0)); } // NOTE: There is a (false) special-case, where there *ALREADY* IS a space before the // addition of the "ellipsis" - so it *MIGHT SEEM* you wouldn't want to add another // a second-space, unfortunately, if they have asked for a space before the // abbreviation-ellipsis, it is also inappropriate to add another character from the // original String. // // LONG-STORY-SHORT: There is a (small) chance that there will be two spaces in a row here, // but in order to comply with the 'maxLength' parameter, there is no // alternative. if (spaceBeforeAbbrev) cArr[targetPos++] = ' '; abbrevStr.getChars(0, abbrevStr.length(), cArr, targetPos); return new String(cArr, 0, targetPos + abbrevStr.length()); } } |