1 5 6 package ppg.util; 7 8 import java.io.OutputStream ; 9 import java.io.OutputStreamWriter ; 10 import java.io.Writer ; 11 import java.io.IOException ; 12 import java.util.Vector ; 13 14 20 public class CodeWriter 21 { 22 26 27 public CodeWriter(OutputStream o, int width_) { 28 output = new OutputStreamWriter (o); 29 width = width_; 30 current = input = new Block(null, 0); 31 } 32 33 37 public CodeWriter(Writer w, int width_) { 38 output = w; 39 width = width_; 40 current = input = new Block(null, 0); 41 } 42 43 44 public void write(String s) { 45 if (s.length() > 0) 46 current.add(new StringItem(s)); 47 } 48 49 50 public void newline() 51 { 52 newline(0); 53 } 54 55 75 public void begin(int n) { 76 Block b = new Block(current, n); 77 current.add(b); 78 current = b; 79 } 80 81 84 public void end() { 85 current = current.parent; 86 if (current == null) throw new RuntimeException (); 87 } 88 89 96 public void allowBreak(int n) { 97 current.add(new AllowBreak(n, " ")); 98 } 99 100 108 public void allowBreak(int n, String alt) { 109 current.add(new AllowBreak(n, alt)); 110 } 111 112 120 public void newline(int n) { 121 current.add(new Newline(n)); 122 } 123 124 130 public boolean flush() throws IOException { 131 boolean success = true; 132 try { 133 Item.format(input,0, 0, width, width, true, true); 134 } catch (Overrun o) { success = false; } 135 input.sendOutput(output, 0, 0); 136 output.flush(); 137 input.free(); 138 current = input = new Block(null, 0); 139 return success; 140 } 141 145 146 Block input; 147 Block current; 148 149 Writer output; 150 int width; 151 } 152 153 157 class Overrun extends Exception 158 { 159 int amount; 160 Overrun(int amount_) { 161 amount = amount_; 162 } 163 } 164 165 169 abstract class Item 170 { 171 Item next; 172 173 protected Item() { next = null; } 174 175 191 192 abstract int formatN(int lmargin, int pos, int rmargin, int fin, 193 boolean can_break, boolean nofail) throws Overrun; 194 198 abstract int sendOutput(Writer o, int lmargin, int pos) 199 throws IOException ; 200 201 203 void free() { 204 if( next != null) { 205 next.free(); 206 next = null; 207 } 208 } 209 210 216 static int format(Item it, int lmargin, int pos, int rmargin, int fin, 217 boolean can_break, boolean nofail) throws Overrun { 218 if (!nofail && pos > rmargin) { throw new Overrun(pos - rmargin); 220 } 221 if (it == null) { if (!nofail && pos > fin) throw new Overrun(pos - fin); 223 return pos; 224 } 225 return it.formatN(lmargin, pos, rmargin, fin, can_break, nofail); 226 } 227 } 228 229 233 class Block extends Item { 234 Block parent; 235 Item first; 236 Item last; 237 int indent; 238 239 Block(Block parent_, int indent_) { 240 parent = parent_; 241 first = last = null; 242 indent = indent_; 243 } 244 245 250 void add(Item it) { 251 if (first == null) { 252 first = it; 253 } else { 254 if (it instanceof StringItem && last instanceof StringItem) { 255 StringItem lasts = (StringItem)last; 256 lasts.appendString(((StringItem)it).s); 257 return; 258 } else { 259 last.next = it; 260 } 261 } 262 last = it; 263 } 264 265 int formatN(int lmargin, int pos, int rmargin, int fin, boolean can_break, 266 boolean nofail) throws Overrun { 267 int this_fin = rmargin; 271 boolean this_nofail = false; 274 boolean this_break = false; 277 while (true) { 278 int next_pos; 279 try { 280 next_pos = format(first, pos + indent, pos, rmargin, 281 this_fin, this_break, this_nofail && this_break); 282 } catch (Overrun o) { 283 if (!can_break) throw o; 284 if (!this_break) { this_break = true; continue; } 285 if (nofail) { this_nofail = true; continue; } 286 throw o; 287 } 288 try { 289 return format(next, lmargin, next_pos, rmargin, fin, 290 can_break, nofail); 291 } catch (Overrun o) { 292 if (!can_break) throw o; if (next instanceof AllowBreak) throw o; this_break = true; 295 if (next_pos > this_fin) next_pos = this_fin; 296 this_fin = next_pos - o.amount; 297 } 298 } 299 } 300 301 int sendOutput(Writer o, int lmargin, int pos) throws IOException { 302 Item it = first; 303 lmargin = pos+indent; 304 while (it != null) { 305 pos = it.sendOutput(o, lmargin, pos); 306 it = it.next; 307 } 308 return pos; 309 } 310 311 void free() { 312 super.free(); 313 314 parent = null; 315 if( first != null) { 316 first.free(); 317 } 318 last = null; 319 } 320 } 321 322 class StringItem extends Item { 323 String s; 324 StringItem(String s_) { s = s_; } 325 326 int formatN(int lmargin, int pos, int rmargin, int fin, boolean can_break, 327 boolean nofail) throws Overrun { 328 return format(next, lmargin, pos + s.length(), rmargin, fin, 329 can_break, nofail); 330 } 331 int sendOutput(Writer o, int lm, int pos) throws IOException { 332 o.write(s); 333 return pos + s.length(); 334 } 335 void appendString(String s) { this.s = this.s + s; } 336 } 337 338 class AllowBreak extends Item 339 { 340 int indent; 341 boolean broken = true; 342 String alt; 343 344 AllowBreak(int n_, String alt_) { indent = n_; alt = alt_; } 345 346 int formatN(int lmargin, int pos, int rmargin, int fin, boolean can_break, 347 boolean nofail) throws Overrun { 348 if (can_break) { pos = lmargin + indent; broken = true; } 349 else { pos += alt.length(); broken = false; } 350 return format(next, lmargin, pos, rmargin, fin, can_break, nofail); 351 } 352 353 int sendOutput(Writer o, int lmargin, int pos) 354 throws IOException { 355 if (broken) { 356 o.write("\r\n"); 357 for (int i = 0; i < lmargin + indent; i++) o.write(" "); 358 return lmargin + indent; 359 } else { 360 o.write(alt); 361 return pos + alt.length(); 362 } 363 } 364 } 365 366 class Newline extends AllowBreak 367 { 368 Newline(int n_) { super(n_, ""); } 369 370 int formatN(int lmargin, int pos, int rmargin, int fin, boolean can_break, 371 boolean nofail) throws Overrun { 372 broken = true; 373 if (!can_break) throw new Overrun(1); 374 return format(next, lmargin, lmargin + indent, rmargin, fin, 375 can_break, nofail); 376 } 377 378 int sendOutput(Writer o, int lmargin, int pos) 379 throws IOException { 380 o.write("\r\n"); 381 for (int i = 0; i < lmargin + indent; i++) o.write(" "); 382 return lmargin + indent; 383 } 384 } 385 | Popular Tags |