1 package com.tapina.robe.swi.wimp;
2
3 import com.tapina.robe.runtime.ByteArrayUtils;
4
5 import java.io.RandomAccessFile;
6 import java.io.IOException;
7 import java.io.UnsupportedEncodingException;
8 import java.util.*;
9
10 /***
11 * This class represents an open template file, opened by {@link com.tapina.robe.swi.Wimp#OpenTemplate(com.tapina.robe.runtime.Environment)}
12 */
13 public class TemplateFile {
14 RandomAccessFile file;
15 Map templates = new HashMap();
16 private static final int HEADER_SIZE = 16;
17 private static final int INDEX_SIZE = 24;
18
19 public class Template {
20 final String name;
21 final int dataOffset;
22 final int templateSize;
23 byte[] data = null;
24
25 public Template(String name, int dataOffset, int templateSize) {
26 this.name = name;
27 this.dataOffset = dataOffset;
28 this.templateSize = templateSize;
29 }
30
31 public String getName() {
32 return name;
33 }
34
35 public int getDataOffset() {
36 return dataOffset;
37 }
38
39 public int getTemplateSize() {
40 return templateSize;
41 }
42
43 public byte[] load() throws IOException {
44 if (data == null) {
45 data = new byte[templateSize];
46 file.seek(dataOffset);
47 file.read(data);
48 }
49 return data;
50 }
51 }
52
53 public TemplateFile(RandomAccessFile file) throws IOException {
54 this.file = file;
55 readHeader();
56 }
57
58 public RandomAccessFile getFile() {
59 return file;
60 }
61
62 public void setFile(RandomAccessFile file) {
63 this.file = file;
64 }
65
66 private void readHeader() throws IOException {
67
68 file.seek(HEADER_SIZE);
69 int numTemplates = 0;
70 byte[] buffer = new byte[INDEX_SIZE];
71 while (true) {
72 if (file.read(buffer) != INDEX_SIZE) {
73 throw new IOException("Unable to read enough bytes for index entry");
74 }
75 final int dataOffset = ByteArrayUtils.getInt(buffer, 0);
76 if (dataOffset == 0) {
77 break;
78 }
79 final String name = getTemplateName(buffer);
80
81 final int templateSize = ByteArrayUtils.getInt(buffer, 4);
82
83 templates.put(name, new Template(name, dataOffset, templateSize));
84 }
85 }
86
87 private String getTemplateName(byte[] buffer) {
88 final String name;
89 int i;
90
91 for (i = 12; i < INDEX_SIZE; i++) {
92 if (buffer[i] < 32) break;
93 }
94 try {
95 name = new String(buffer, 12, i - 12, "ISO-8859-1");
96 } catch (UnsupportedEncodingException e) {
97 throw new RuntimeException(e);
98 }
99 return name;
100 }
101
102 public Template getTemplate(String name) {
103 return (Template) templates.get(name);
104 }
105
106 public Template[] getTemplates(String nameToMatch) {
107 boolean matchStart = nameToMatch.endsWith("*");
108 if (matchStart) {
109 nameToMatch = nameToMatch.substring(0, nameToMatch.length() - 1);
110 }
111 final ArrayList list = new ArrayList(templates.size());
112 for (Iterator iterator = templates.values().iterator(); iterator.hasNext();) {
113 final Template template = (Template) iterator.next();
114 if ((matchStart && template.getName().startsWith(nameToMatch)) || template.getName().equals(nameToMatch)) {
115 list.add(template);
116 }
117 }
118 return (Template[]) list.toArray(new Template[list.size()]);
119 }
120 }