001: /*
002: * WordMode.java
003: *
004: * Copyright (C) 2002 Peter Graves
005: * $Id: WordMode.java,v 1.3 2002/10/11 01:42:37 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import java.awt.event.KeyEvent;
025: import java.io.IOException;
026: import java.io.InputStream;
027:
028: public final class WordMode extends AbstractMode implements Constants,
029: Mode {
030: private static final WordMode mode = new WordMode();
031:
032: private WordMode() {
033: super (WORD_MODE, WORD_MODE_NAME);
034: setProperty(Property.VERTICAL_RULE, 0);
035: setProperty(Property.SHOW_LINE_NUMBERS, false);
036: }
037:
038: public static final WordMode getMode() {
039: return mode;
040: }
041:
042: public final Formatter getFormatter(Buffer buffer) {
043: return new PlainTextFormatter(buffer);
044: }
045:
046: protected void setKeyMapDefaults(KeyMap km) {
047: km.mapKey(KeyEvent.VK_B, CTRL_MASK | ALT_MASK, "binaryMode");
048: }
049:
050: public void loadFile(Buffer buffer, File toBeLoaded) {
051: try {
052: load(buffer, toBeLoaded.getInputStream());
053: } catch (IOException e) {
054: Log.debug(e);
055: }
056: }
057:
058: private static void load(Buffer buffer, InputStream inputStream) {
059: byte[] bytes = new byte[4096];
060: int totalBytes = 0;
061: try {
062: int bytesRead = inputStream.read(bytes);
063: if (bytesRead < 0x400)
064: return;
065: int magic = getWord(bytes, 0x200);
066: Log.debug("magic = 0x" + Integer.toHexString(magic));
067: if (magic != 0xa5ec)
068: return;
069: int version = getWord(bytes, 0x202);
070: Log.debug("version = " + version);
071: if (version < 101)
072: return;
073: int status = getWord(bytes, 0x20a);
074: Log.debug("status = 0x" + Integer.toHexString(status));
075: if ((status & 4) != 0)
076: Log.debug("document is fast saved");
077: long beginText = getLong(bytes, 0x218) + 0x200;
078: Log.debug("beginText = 0x" + Long.toHexString(beginText));
079: if (beginText > bytesRead)
080: return; // BUG! We could handle this case.
081: long endText = getLong(bytes, 0x21c) + 0x200;
082: long textLength = endText - beginText;
083: Log.debug("textLength = " + textLength);
084: final String encoding = "Cp1252";
085: ByteBuffer bb = new ByteBuffer(256);
086: boolean done = false;
087: Debug.assertTrue(beginText < Integer.MAX_VALUE);
088: int start = (int) beginText;
089: while (bytesRead > 0) {
090: for (int i = start; i < bytesRead; i++) {
091: byte b = bytes[i];
092: switch (b) {
093: case 13:
094: if (bb.length() > 0)
095: wrapAndAppend(buffer, new String(bb
096: .getBytes(), 0, bb.length(),
097: encoding));
098: buffer.appendLine("");
099: bb.setLength(0);
100: break;
101: case 0:
102: if (bb.length() > 0)
103: wrapAndAppend(buffer, new String(bb
104: .getBytes(), 0, bb.length(),
105: encoding));
106: bb.setLength(0);
107: done = true;
108: break;
109: default:
110: // Normal char.
111: bb.append(b);
112: break;
113: }
114: if (done)
115: break;
116: }
117: if (done)
118: break;
119: bytesRead = inputStream.read(bytes);
120: start = 0;
121: if (bytesRead > 0)
122: buffer.loadProgress(totalBytes = totalBytes
123: + bytesRead);
124: }
125: buffer.unmodified();
126: buffer.setLoaded(true);
127: buffer.setForceReadOnly(true);
128: } catch (Exception e) {
129: Log.error(e);
130: }
131: buffer.loadFinished(buffer.isLoaded());
132: }
133:
134: private static final void wrapAndAppend(Buffer buffer, String s) {
135: buffer.append(Utilities.wrap(s, 65, 8));
136: }
137:
138: // 4 bytes
139: private static long getLong(byte[] bytes, int offset) {
140: long byte0 = bytes[offset] & 0xff;
141: long byte1 = bytes[offset + 1] & 0xff;
142: long byte2 = bytes[offset + 2] & 0xff;
143: long byte3 = bytes[offset + 3] & 0xff;
144: return (byte3 << 24) + (byte2 << 16) + (byte1 << 8) + byte0;
145: }
146:
147: // 2 bytes
148: private static int getWord(byte[] bytes, int offset) {
149: int hi = bytes[offset + 1] & 0xff;
150: int lo = bytes[offset] & 0xff;
151: return (hi << 8) + lo;
152: }
153: }
|