Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/jguild/jrpm/io/Header.java


1   /*
2    * jGuild Project: jRPM
3    * Released under the Apache License ( http://www.apache.org/LICENSE )
4    */
5   package com.jguild.jrpm.io;
6   
7   import com.jguild.jrpm.io.datatype.*;
8   
9   import org.apache.log4j.Logger;
10  
11  import java.io.DataInputStream;
12  import java.io.IOException;
13  
14  import java.util.Comparator;
15  import java.util.HashMap;
16  import java.util.TreeSet;
17  
18  
19  /**
20   * This class represents the abstract definition of a header structur.
21   * It can be either a signature or a header. The tags of such a structure
22   * can be accessed by either their tag id or by their tag name.
23   * Also all available and all read tag names in this structure can be accessed.
24   *
25   * @author kuss
26   * @version $Id: Header.java,v 1.8 2003/10/20 16:32:11 mkuss Exp $
27   **/
28  public abstract class Header {
29      private static final int HEADER_LENGTH = 16;
30      private static final Logger logger = Logger.getLogger(Header.class);
31      protected long size;
32      private HashMap store = new HashMap();
33      private IndexEntry[] indexes;
34      private int version;
35      private long indexDataSize;
36      private long indexNumber;
37  
38      /**
39       * Construct a header structure for the given input stream.
40       * The header structure of a signature or a header can be read and
41       * also the index entries containig the tags for this rpm section
42       * (signature or header).
43       * First a header is read consisting of the following fields:
44       * <code><pre>
45       * byte magic[3];      (3  byte)  (8e ad e8)
46       * int version;        (1  byte)
47       * byte reserved[4];   (4  byte)
48       * long num_index;     (4  byte)
49       * long num_data;      (4  byte)
50       * </pre></code>
51       * Afterwareds the index entries are read and then the tags and the
52       * correspondig data entries are read.
53       *
54       * @param inputStream An inputstream containing rpm file informations
55       * @throws IOException if an error occurs on reading informations
56       * out of the stream
57       */
58      public Header(DataInputStream inputStream) throws IOException {
59          if (logger.isDebugEnabled()) {
60              logger.debug("Start Reading Header");
61          }
62  
63          // Read header
64          size = HEADER_LENGTH;
65  
66          check(inputStream.readUnsignedByte() == 0x8E);
67          check(inputStream.readUnsignedByte() == 0xAD);
68          check(inputStream.readUnsignedByte() == 0xE8);
69          version = inputStream.readUnsignedByte();
70  
71          if (logger.isDebugEnabled()) {
72              logger.debug("version: " + version);
73          }
74  
75          // skip reserved bytes
76          inputStream.skipBytes(4);
77          indexNumber = (long) inputStream.readInt();
78  
79          if (logger.isDebugEnabled()) {
80              logger.debug("indexes available: " + indexNumber);
81          }
82  
83          indexDataSize = (long) inputStream.readInt();
84  
85          if (logger.isDebugEnabled()) {
86              logger.debug("index data size: " + indexDataSize);
87          }
88  
89          // Read indexes
90          // make sure to sort them in order of offset to
91          // be able to read the store without jumping arround in
92          // the file
93          TreeSet _indexes = new TreeSet(new Comparator() {
94                      public int compare(Object o1, Object o2) {
95                          return (int) (((IndexEntry) o1).getOffset() - ((IndexEntry) o2).getOffset());
96                      }
97  
98                      public boolean equals(Object o) {
99                          return false;
100                     }
101                 });
102 
103         for (int i = 0; i < indexNumber; i++) {
104             IndexEntry index = new IndexEntry(inputStream);
105 
106             _indexes.add(index);
107             size += index.getSize();
108         }
109 
110         indexes = new IndexEntry[0];
111         indexes = (IndexEntry[]) _indexes.toArray(indexes);
112 
113         // Read store
114         for (int i = 0; i < indexes.length; i++) {
115             IndexEntry index = indexes[i];
116 
117             //            if (index.getType().equals(RPMIndexType.STRING_ARRAY) || index.getType().equals(RPMIndexType.STRING) ||
118             //                    index.getType().equals(RPMIndexType.I18NSTRING)) {
119             //                if (i < (indexes.length - 1)) {
120             //                    IndexEntry next = indexes[i + 1];
121             //
122             //                    length = next.getOffset() - index.getOffset();
123             //                } else {
124             //                    length = indexDataSize - index.getOffset();
125             //                }
126             //
127             //                // and initialize temporary space for data
128             //                stringData = new byte[(int) length];
129             //
130             //                // and read it from stream
131             //                inputStream.readFully(stringData);
132             //            }
133             DataTypeIf dataObject = null;
134 
135             if (logger.isDebugEnabled()) {
136                 logger.debug("Reading for tag '" + getTagNameForId(index.getTag()) + "' '" + index.getCount() + "' entries of type '" +
137                     index.getType().getName() + "'");
138             }
139 
140             dataObject = TypeFactory.createFromStream(inputStream, index,
141                     (i < (indexes.length - 1)) ? (indexes[i + 1].getOffset() - index.getOffset()) : (indexDataSize - index.getOffset()));
142 
143             // adjust size
144             size += dataObject.getSize();
145 
146             store.put(new Long(index.getTag()), dataObject);
147         }
148 
149         if (logger.isDebugEnabled()) {
150             logger.debug("");
151         }
152 
153         if (logger.isDebugEnabled()) {
154             logger.debug("Finished Reading Header");
155         }
156     }
157 
158     /**
159      * Read all known tag names for this header structure.
160      *
161      * @return An array of tag names
162      */
163     public static String[] getKnownTagNames() {
164         return new String[0];
165     }
166 
167     /**
168      * Get the size in bytes of this structure
169      *
170      * @return The size in bytes.
171      */
172     public long getSize() {
173         return size;
174     }
175 
176     /**
177      * Get a tag by id as a Long
178      *
179      * @param tag A tag id as a Long
180      * @return A data struct containing the data of this tag
181      */
182     public DataTypeIf getTag(Long tag) {
183         return (DataTypeIf) store.get(tag);
184     }
185 
186     /**
187      * Get a tag by id as a long
188      *
189      * @param tag A tag id as a long
190      * @return A data struct containing the data of this tag
191      */
192     public DataTypeIf getTag(long tag) {
193         return getTag(new Long(tag));
194     }
195 
196     /**
197      * Get a tag by name
198      *
199      * @param tagname A tag name
200      * @return A data struct containing the data of this tag
201      */
202     public DataTypeIf getTag(String tagname) {
203         return getTag(getTagIdForName(tagname));
204     }
205 
206     /**
207      * Read a tag with a given tag name. The tag will be read out of the
208      * class defined in getTagEnum().
209      *
210      * @param tagname A RPM tag name
211      * @return The id of the RPM tag
212      * @throws IllegalArgumentException if the tag name was not found
213      */
214     public abstract long getTagIdForName(String tagname);
215 
216     /**
217      * Get all tag ids contained in this rpm file.
218      *
219      * @return All tag ids contained in this rpm file.
220      */
221     public long[] getTagIds() {
222         Long[] tmp = (Long[]) store.keySet().toArray(new Long[0]);
223         long[] ret = new long[tmp.length];
224 
225         for (int i = 0; i < tmp.length; i++) {
226             ret[i] = tmp[i].longValue();
227         }
228 
229         return ret;
230     }
231 
232     /**
233      * Read a tag with a given tag id. The tag will be read out of the
234      * class defined in getTagEnum().
235      *
236      * @param tagid A RPM tag id
237      * @return The name of the RPM tag
238      * @throws IllegalArgumentException if the tag id was not found
239      */
240     public abstract String getTagNameForId(long tagid);
241 
242     /**
243      * Get all tag names contained in this rpm file.
244      *
245      * @return All tag names contained in this rpm file.
246      */
247     public String[] getTagNames() {
248         Long[] tmp = (Long[]) store.keySet().toArray(new Long[0]);
249         String[] ret = new String[tmp.length];
250 
251         for (int i = 0; i < tmp.length; i++) {
252             ret[i] = getTagNameForId(tmp[i].longValue());
253         }
254 
255         return ret;
256     }
257 
258     /**
259      * Asserts a boolean value and throws an exception if it
260      * is false
261      * @param test A boolean test variable
262      * @throws IOException if the variable test is false
263      */
264     private static final void check(boolean test)
265         throws IOException {
266         if (!test) {
267             throw new IOException("Corrupted archive");
268         }
269     }
270 }