View Javadoc

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          // First 16 bytes are uninteresting header data
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; // End of list
78              }
79              final String name = getTemplateName(buffer);
80  
81              final int templateSize = ByteArrayUtils.getInt(buffer, 4);
82              // TODO: Find out what is at offset 8 in the index record
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 }