mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2025-02-28 09:29:53 +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