/* * File : PCCFileSystem.java * Created : 20-jun-2000 10:00 * By : fbusquets * * JClic - Authoring and playing system for educational activities * * Copyright (C) 2000 - 2005 Francesc Busquets & Departament * d'Educacio de la Generalitat de Catalunya * * 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 (see the LICENSE file). */ package edu.xtec.jclic.fileSystem; import edu.xtec.jclic.clic3.Clic3; import edu.xtec.util.ResourceBridge; import java.awt.Image; import java.awt.Toolkit; import java.io.*; /** * * @author Francesc Busquets (fbusquets@xtec.cat) * @version 13.08.08 */ public abstract class PCCFileSystem extends FileSystem { String pccName; public String pccVersion; public String pccDescription; public int numFiles; public int baseOffset; PCCFileEntry[] fe; public PCCFileSystem(ResourceBridge rb) { super("", rb); } public PCCFileSystem(String rootPath, String pccFileName, ResourceBridge rb){ super(rootPath, rb); pccName = getCanonicalNameOf(pccFileName); } public static PCCFileSystem createPCCFileSystem(String rootPath, String pccFileName, ResourceBridge rb) throws Exception { if(isStrUrl(rootPath)) return new UrlPCC(rootPath, pccFileName, rb); else return new FilePCC(rootPath, pccFileName, rb); } @Override public String getFullRoot(){ return root+pccName; } protected class PCCFileEntry extends Object { String fileName; long size, offset; public PCCFileEntry(String fName, long o, long s){ fileName=stdFn(fName); size=s; offset=o; } } void initPCC(DataInputStream dis) throws Exception { if((pccVersion=extractLineFromDIS(dis))!=null && pccVersion.compareTo("PCC00")==0){ pccDescription=extractLineFromDIS(dis); numFiles=extractShortInt(dis); baseOffset=(int)extractShortLong(dis); fe = new PCCFileEntry[numFiles]; for(int i=0; i<numFiles; i++){ //fe[i]=new PCCFileEntry(Clic3.validFileName(normalizePath(extractSzString(dis))), fe[i]=new PCCFileEntry(Clic3.validFileName(extractSzString(dis)), extractShortLong(dis), extractShortLong(dis) ); if(fe[i].fileName.length()==0) break; } } } public String getEntryInfo(int n){ return (n<0 || n>=numFiles) ? "OUT OF INDEX!" : fe[n].toString(); } public String getEntryName(int n){ return (n<0 || n>=numFiles) ? "OUT OF INDEX!" : fe[n].fileName; } public int getEntryNum(String fName){ int i=-1; String normalizedFName=stdFn(fName); if(numFiles>0){ for(i=0; i<numFiles; i++){ if(fe[i].fileName.equals(normalizedFName)) break; } } if(i==numFiles && altFileNames.get(fName)!=null){ // not found, but found in altFileNames! normalizedFName=stdFn((String)altFileNames.get(fName)); for(i=0; i<numFiles; i++){ if(fe[i].fileName.equals(normalizedFName)) break; } } return (i==numFiles ? -1 : i); } protected abstract byte[] getBytes(int entryNum) throws IOException; @Override public byte[] getBytes(String fileName) throws IOException { int entryNum; if((entryNum=getEntryNum(fileName))==-1) return super.getBytes(fileName); return getBytes(entryNum); } @Override public long getFileLength(String fileName) throws IOException{ int entryNum; return (entryNum=getEntryNum(fileName))==-1 ? super.getFileLength(fileName) : fe[entryNum].size; } @Override public Image getImageFile(String fName) throws Exception { int entryNum; return (entryNum=getEntryNum(fName))==-1 ? super.getImageFile(fName) : Toolkit.getDefaultToolkit().createImage(getBytes(entryNum)); } public java.io.DataInputStream getDataInputStream(String fName) throws IOException { return new DataInputStream(super.getInputStream(fName)); } public String extractLine(BufferedReader bfr) throws IOException { return bfr.readLine(); } public String extractLineFromDIS(DataInputStream dis) throws IOException { StringBuilder str=new StringBuilder(); boolean skipNext=false; while(true) { byte b=dis.readByte(); if(skipNext) break; else if(b==0x0D) skipNext=true; else str.append((char)b); } return str.substring(0); } public String extractSzString(BufferedReader bfr) throws IOException { StringBuilder str=new StringBuilder(); char b[] = new char[1]; while(true){ bfr.read(b, 0, 1); if(b[0]==0) break; else str.append(b[0]); } return str.substring(0); } public String extractSzString(DataInputStream dis) throws IOException { StringBuilder str=new StringBuilder(); while(true){ byte b=dis.readByte(); if(b==0) break; else str.append((char)b); } return str.substring(0); } public int extractShortInt(DataInputStream bfr) throws IOException { int bt=bfr.readUnsignedByte(); int r=bt; bt=bfr.readUnsignedByte(); r+=(bt<<8); return r; } public long extractShortLong(DataInputStream bfr) throws IOException { long bt=bfr.readUnsignedByte(); long r=bt; bt=bfr.readUnsignedByte(); r+=(bt<<8); bt=bfr.readUnsignedByte(); r+=(bt<<16); bt=bfr.readUnsignedByte(); r+=(bt<<24); return r; } @Override public void close(){ fe=null; super.close(); } }