mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2025-01-18 04:34:25 +00:00
Supports Pascal ".text" file formats.
This commit is contained in:
parent
ff763dd371
commit
da3177feea
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* AppleCommander - An Apple ][ image utility.
|
||||
* Copyright (C) 2004 by Robert Greene
|
||||
* robgreene at users.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
package com.webcodepro.applecommander.storage.filters;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import com.webcodepro.applecommander.storage.FileEntry;
|
||||
import com.webcodepro.applecommander.storage.FileFilter;
|
||||
|
||||
/**
|
||||
* Filter the given file as a Pascal ".text" file.
|
||||
* <p>
|
||||
* From the Apple Pascal v1.2 Operating System Reference manual:
|
||||
* <quote>
|
||||
* <b>Text files in Apple Pascal</b>
|
||||
* <hr>
|
||||
* At the beginning of each textfile is a 1024-byte (two blocks on
|
||||
* diskette) header page, which contains information for the texteditor.
|
||||
* This space is reserved for use by the text editor, and is respected
|
||||
* by all portions of the system. When a user program opens a text file,
|
||||
* and REWRITEs or RESETs it with a title ending in .TEXT, the I/O
|
||||
* subsystem will create and skip over the initial header page. This is
|
||||
* done to faciliatie users editing their input and/or output data. The
|
||||
* file-handler wil transfer the header page only on a disk-to-disk
|
||||
* transfer, and will omit it on a transfer to a serial device (thus
|
||||
* transfers to PRINTER: abd CONSOLE: will omit the header page).
|
||||
* <p>
|
||||
* Following the initial header page, the text itself appears in
|
||||
* subsequent 1024-byte text pages (two block each, on diskette),
|
||||
* where a text page is defined:<br>
|
||||
* <pre>
|
||||
* [DLE] [indent] [text] [cr] [dle] [indent] [text] [CR] .. [nulls]
|
||||
* </pre>
|
||||
* DLE's (Data Link Escapes) are followed by an indent-code, which is a
|
||||
* byte containing the value 32+(number to indent). The nulls at the
|
||||
* end of the page follow a [CR} in all cases, and are a pad to the end
|
||||
* of a 1024-byte page (because the compiler wants integral numbers of
|
||||
* lines on a page). The Data Link Escape and corresponding indentation
|
||||
* code are optional. In a given text file, some lines will have the
|
||||
* codes, and some won't.
|
||||
* </quote>
|
||||
* (Thanks to Hans Otten for sending in this information.)
|
||||
*
|
||||
* @author: Rob Greene
|
||||
*/
|
||||
public class PascalTextFileFilter implements FileFilter {
|
||||
private static final char NUL = 0x00;
|
||||
private static final char CR = 0x0d;
|
||||
private static final char DLE = 0x10;
|
||||
private static final int HEADER_SIZE = 1024;
|
||||
private static final int INDENT_BASE_VALUE = 0x20;
|
||||
|
||||
/**
|
||||
* Constructor for PascalTextFileFilter.
|
||||
*/
|
||||
public PascalTextFileFilter() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the given FileEntry and return a byte array
|
||||
* with filtered data; use PrintWriter to get platform
|
||||
* agnostic line endings.
|
||||
*/
|
||||
public byte[] filter(FileEntry fileEntry) {
|
||||
byte[] fileData = fileEntry.getFileData();
|
||||
int offset = HEADER_SIZE;
|
||||
ByteArrayOutputStream byteArray = new
|
||||
ByteArrayOutputStream(fileData.length);
|
||||
PrintWriter printWriter = new PrintWriter(byteArray, true);
|
||||
while (offset < fileData.length) {
|
||||
char c = (char)(fileData[offset] & 0x7f); // Will the bitwise AND be a problem??
|
||||
switch (c) {
|
||||
case NUL: break; // ignore
|
||||
case CR: printWriter.println();
|
||||
break;
|
||||
case DLE: if (offset+1 < fileData.length) {
|
||||
offset++;
|
||||
int indent = fileData[offset] - INDENT_BASE_VALUE;
|
||||
while (indent-- > 0) {
|
||||
printWriter.print(' ');
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: printWriter.print(c);
|
||||
break;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
return byteArray.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Give suggested file name.
|
||||
*/
|
||||
public String getSuggestedFileName(FileEntry fileEntry) {
|
||||
String fileName = fileEntry.getFilename().trim();
|
||||
if (!fileName.toLowerCase().endsWith(".txt")) {
|
||||
fileName = fileName + ".txt";
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user