1 /*
2  *  JIIC: Java ISO Image Creator. Copyright (C) 2007, Jens Hatlak <hatlak@rbg.informatik.tu-darmstadt.de>
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2.1 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19 
20 package de.tu_darmstadt.informatik.rbg.hatlak.iso9660.volumedescriptors;
21 
22 import java.nio.ByteBuffer;
23 import java.util.*;
24 
25 import de.tu_darmstadt.informatik.rbg.hatlak.iso9660.ISO9660File;
26 import de.tu_darmstadt.informatik.rbg.hatlak.iso9660.LayoutHelper;
27 import de.tu_darmstadt.informatik.rbg.hatlak.iso9660.StandardConfig;
28 import de.tu_darmstadt.informatik.rbg.hatlak.iso9660.impl.*;
29 import de.tu_darmstadt.informatik.rbg.hatlak.sabre.impl.*;
30 import de.tu_darmstadt.informatik.rbg.mhartle.sabre.*;
31 import de.tu_darmstadt.informatik.rbg.mhartle.sabre.impl.*;
32 
33 public abstract class StandardVolumeDescriptor extends ISO9660VolumeDescriptor {
34 	String systemId, volumeId, volSetId;
35 	int volSetSize, volSeqNo;
36 	Object publisher, dataPreparer, app;
37 	ISO9660File copyrightFile, abstractFile, bibFile;
38 	Date createDate, modDate, expireDate, effectiveDate;
39 
StandardVolumeDescriptor(StreamHandler streamHandler, int type, LayoutHelper helper)40 	public StandardVolumeDescriptor(StreamHandler streamHandler, int type, LayoutHelper helper) {
41 		super(streamHandler, type, helper);
42 		this.systemId = this.volumeId = this.volSetId = "";
43 		this.volSetSize = this.volSeqNo = 1;
44 		this.publisher = this.dataPreparer = this.app = null;
45 		this.copyrightFile = this.abstractFile = this.bibFile = null;
46 		this.createDate = this.modDate = this.expireDate = this.effectiveDate = null;
47 	}
48 
setMetadata(StandardConfig config)49 	public void setMetadata(StandardConfig config) {
50 		setSystemId(config.getSystemID());
51 		setVolumeId(config.getVolumeID());
52 		setPublisher(config.getPublisher());
53 		setDataPreparer(config.getDataPreparer());
54 		setApp(config.getApp());
55 		setCreateDate(config.getCreateDate());
56 		setModDate(config.getModDate());
57 		setExpireDate(config.getExpireDate());
58 		setEffectiveDate(config.getEffectiveDate());
59 		setAbstractFile(config.getAbstractFile());
60 		setBibFile(config.getBibFile());
61 		setCopyrightFile(config.getCopyrightFile());
62 		setVolSeqNo(config.getVolumeSequenceNumber());
63 		setVolSetId(config.getVolumeSetID());
64 		setVolSetSize(config.getVolumeSetSize());
65 	}
66 
setAbstractFile(ISO9660File abstractFile)67 	public void setAbstractFile(ISO9660File abstractFile) {
68 		this.abstractFile = abstractFile;
69 	}
70 
setApp(Object app)71 	public void setApp(Object app) {
72 		this.app = app;
73 	}
74 
setBibFile(ISO9660File bibFile)75 	public void setBibFile(ISO9660File bibFile) {
76 		this.bibFile = bibFile;
77 	}
78 
setCopyrightFile(ISO9660File copyrightFile)79 	public void setCopyrightFile(ISO9660File copyrightFile) {
80 		this.copyrightFile = copyrightFile;
81 	}
82 
setCreateDate(Date createDate)83 	public void setCreateDate(Date createDate) {
84 		this.createDate = createDate;
85 	}
86 
setDataPreparer(Object dataPreparer)87 	public void setDataPreparer(Object dataPreparer) {
88 		this.dataPreparer = dataPreparer;
89 	}
90 
setEffectiveDate(Date effectiveDate)91 	public void setEffectiveDate(Date effectiveDate) {
92 		this.effectiveDate = effectiveDate;
93 	}
94 
setExpireDate(Date expireDate)95 	public void setExpireDate(Date expireDate) {
96 		this.expireDate = expireDate;
97 	}
98 
setModDate(Date modDate)99 	public void setModDate(Date modDate) {
100 		this.modDate = modDate;
101 	}
102 
setPublisher(Object publisher)103 	public void setPublisher(Object publisher) {
104 		this.publisher = publisher;
105 	}
106 
setSystemId(String systemId)107 	public void setSystemId(String systemId) {
108 		this.systemId = systemId;
109 	}
110 
setVolSeqNo(int volSeqNo)111 	public void setVolSeqNo(int volSeqNo) {
112 		this.volSeqNo = volSeqNo;
113 	}
114 
setVolSetId(String volSetId)115 	public void setVolSetId(String volSetId) {
116 		this.volSetId = volSetId;
117 	}
118 
setVolSetSize(int volSetSize)119 	public void setVolSetSize(int volSetSize) {
120 		this.volSetSize = volSetSize;
121 	}
122 
setVolumeId(String volumeId)123 	public void setVolumeId(String volumeId) {
124 		this.volumeId = volumeId;
125 	}
126 
doStandardVD()127 	HashMap doStandardVD() throws HandlerException {
128 		HashMap memory = new HashMap();
129 
130 		// Volume Descriptor Type: Primary
131 		streamHandler.data(getType());
132 
133 		// Standard Identifier
134 		streamHandler.data(getStandardId());
135 
136 		// Volume Descriptor Version
137 		streamHandler.data(getVDVersion());
138 
139 		// Unused Field / Volume Flags (SVD): 1 byte
140 		Fixup vf = streamHandler.fixup(new ByteDataReference(0));
141 		memory.put("volumeFlagsFixup", vf);
142 
143 		// System Identifier: 32 bytes
144 		streamHandler.data(getSystemId());
145 
146 		// Volume Identifier: 32 bytes
147 		streamHandler.data(getVolumeId());
148 
149 		// Unused Field: 8 bytes
150 		streamHandler.data(new EmptyByteArrayDataReference(8));
151 
152 		// Volume Space Size
153 		Fixup vss = streamHandler.fixup(new BothWordDataReference(0));
154 		memory.put("volumeSpaceSizeFixup", vss);
155 
156 		// Unused Field / Escape Sequences (SVD): 32 bytes
157 		Fixup es = streamHandler.fixup(new EmptyByteArrayDataReference(32));
158 		memory.put("escapeSequencesFixup", es);
159 
160 		// Volume Set Size
161 		streamHandler.data(getVolumeSetSize());
162 
163 		// Volume Sequence Number
164 		streamHandler.data(getVolumeSeqNo());
165 
166 		// Logical Block Size
167 		streamHandler.data(getLogicalBlockSize());
168 
169 		// Path Table Size
170 		Fixup pts = streamHandler.fixup(new BothWordDataReference(0));
171 		memory.put("ptSizeFixup", pts);
172 
173 		// Type L Path Table Location
174 		Fixup tlpt = streamHandler.fixup(new LSBFWordDataReference(0));
175 		memory.put("typeLPTLocationFixup", tlpt);
176 		// Optional Type L Path Table Location: none
177 		streamHandler.data(new LSBFWordDataReference(0));
178 
179 		// Type M Path Table Location
180 		Fixup tmpt = streamHandler.fixup(new WordDataReference(0));
181 		memory.put("typeMPTLocationFixup", tmpt);
182 		// Optional Type M Path Table Location: none
183 		streamHandler.data(new WordDataReference(0));
184 
185 		// Directory Record for Root Directory: 34 bytes
186 		doRootDR(memory);
187 
188 		// Volume Set Identifier: 128 bytes
189 		streamHandler.data(getVolumeSetId());
190 
191 		// Publisher Identifier: 128 bytes
192 		streamHandler.data(getIdOrFile(publisher));
193 		// Data Preparer Identifier: 128 bytes
194 		streamHandler.data(getIdOrFile(dataPreparer));
195 		// Application Identifier: 128 bytes
196 		streamHandler.data(getIdOrFile(app));
197 
198 		// Copyright File Identifier: 37 bytes
199 		streamHandler.data(getFile(copyrightFile));
200 		// Abstract File Identifier: 37 bytes
201 		streamHandler.data(getFile(abstractFile));
202 		// Bibliographic File Identifier: 37 bytes
203 		streamHandler.data(getFile(bibFile));
204 
205 		// Volume Creation Date and Time: 17 bytes
206 		streamHandler.data(new ISO9660DateDataReference(createDate));
207 		// Volume Modification Date and Time: 17 bytes
208 		streamHandler.data(new ISO9660DateDataReference(modDate));
209 		// Volume Expiration Date and Time: 17 bytes
210 		streamHandler.data(new ISO9660DateDataReference(expireDate));
211 		// Volume Effective Date and Time: 17 bytes
212 		streamHandler.data(new ISO9660DateDataReference(effectiveDate));
213 
214 		// File Structure Version
215 		streamHandler.data(getFileStructureVersion());
216 
217 		// Reserved Field
218 		streamHandler.data(new ByteDataReference(0));
219 
220 		// Application Use and reserved bytes: handle externally
221 
222 		return memory;
223 	}
224 
doRootDR(HashMap memory)225 	private void doRootDR(HashMap memory) throws HandlerException {
226 		ISO9660DirectoryRecord rddr = new ISO9660DirectoryRecord(streamHandler, ISO9660Constants.FI_ROOT, helper.getRoot(), helper);
227 		HashMap drMemory = rddr.doDR();
228 
229 		// Length of Directory Record
230 		Fixup drLengthFixup = (Fixup) drMemory.get("drLengthFixup");
231 		int drLength = ((Integer) drMemory.get("drLength")).intValue();
232 		drLengthFixup.data(new ByteDataReference(drLength));
233 		drLengthFixup.close();
234 
235 		// Root Directory Location
236 		Fixup rootDirLocation = (Fixup) drMemory.get("drLocationFixup");
237 		memory.put("rootDirLocationFixup", rootDirLocation);
238 
239 		// Root Directory Length
240 		Fixup rootDirLength = (Fixup) drMemory.get("drDataLengthFixup");
241 		memory.put("rootDirLengthFixup", rootDirLength);
242 	}
243 
getSystemId()244 	private ByteArrayDataReference getSystemId()
245 			throws HandlerException {
246 		byte[] bytes = helper.pad(systemId, 32);
247 		return new ByteArrayDataReference(bytes);
248 	}
249 
getVolumeId()250 	private ByteArrayDataReference getVolumeId()
251 			throws HandlerException {
252 		byte[] bytes = helper.pad(volumeId, 32);
253 		return new ByteArrayDataReference(bytes);
254 	}
255 
getVolumeSetSize()256 	private BothShortDataReference getVolumeSetSize() {
257 		return new BothShortDataReference(volSetSize);
258 	}
259 
getVolumeSeqNo()260 	private BothShortDataReference getVolumeSeqNo() {
261 		return new BothShortDataReference(volSeqNo);
262 	}
263 
getLogicalBlockSize()264 	private BothShortDataReference getLogicalBlockSize() {
265 		return new BothShortDataReference(ISO9660Constants.LOGICAL_BLOCK_SIZE);
266 	}
267 
getFileStructureVersion()268 	private ByteDataReference getFileStructureVersion() {
269 		return new ByteDataReference(ISO9660Constants.FSV);
270 	}
271 
getVolumeSetId()272 	private DataReference getVolumeSetId() throws HandlerException {
273 		byte[] bytes = helper.pad(volSetId, 128);
274 		return new ByteArrayDataReference(bytes);
275 	}
276 
getIdOrFile(Object object)277 	DataReference getIdOrFile(Object object) throws HandlerException {
278 		String id;
279 		byte[] bytes;
280 
281 		if (object == null) {
282 			bytes = helper.pad("", 128);
283 		} else if (object instanceof String) {
284 			id = (String) object;
285 			bytes = helper.pad(id, 128);
286 		} else if (object instanceof ISO9660File) {
287 			ByteBuffer buf = ByteBuffer.allocate(128);
288 			buf.put((byte) 0x5F);
289 			ISO9660File file = (ISO9660File) object;
290 			file.enforce8plus3(true);
291 			id = helper.getFilenameDataReference(file).getName();
292 			buf.put(helper.pad(id, 127));
293 			bytes = buf.array();
294 		} else {
295 			throw new HandlerException(
296 					"String or ISO9660File expected in getIdOrFile, got "
297 							+ object.getClass());
298 		}
299 
300 		return new ByteArrayDataReference(bytes);
301 	}
302 
getFile(ISO9660File file)303 	DataReference getFile(ISO9660File file) throws HandlerException {
304 		String id;
305 		byte[] bytes;
306 
307 		if (file == null) {
308 			id = "";
309 			bytes = helper.pad(id, 37);
310 		} else {
311 			file.enforce8plus3(true);
312 			id = helper.getFilenameDataReference(file).getName();
313 			bytes = helper.pad(id, 37);
314 		}
315 
316 		return new ByteArrayDataReference(bytes);
317 	}
318 }
319