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

Quick Search    Search Deep

Source code: com/flexstor/flexdbserver/services/asset/iptc/IPTCParser.java


1   /*
2    * IPTCParser.java
3    *
4    * Copyright $Date: 2003/08/11 02:22:34 $ FLEXSTOR.net Inc.
5    *
6    * This work is licensed for use and distribution under license terms found at
7    * http://www.flexstor.org/license.html
8    *
9    */
10  
11  package com.flexstor.flexdbserver.services.asset.iptc;
12  
13  import java.util.Hashtable;
14  
15  /**
16   *
17   * @author  bparks
18   * @version initial
19   */
20  public class IPTCParser extends Object {
21  
22      protected Hashtable hDataSets = null;
23     
24     
25     /** Creates new IPTCParser */
26     public IPTCParser() {
27        hDataSets = new Hashtable();
28     }
29     
30     
31     protected boolean parseIPTCdata( byte [] abIPTCrecord ) {
32        // loop through the byte array and get the data out of it
33        int nArrayIndex = 0;
34        byte bTagMarker = -1;
35        int nByteCount = -1;
36        String sDataSetID = null;
37        String sDataSetValue = null;
38        
39        while ( nArrayIndex < abIPTCrecord.length ) {
40           
41           bTagMarker = abIPTCrecord[nArrayIndex];
42           // increment the array index after reading the tag marker
43           nArrayIndex++;
44  
45           // The end of the buffer may contain padded 0's which will give a tag marker
46           // error when there really isn't one.  Just ignore them.
47           if ( bTagMarker == 0)
48           {
49              continue;
50           }
51           
52           // If the tag marker is not 0x1c, this is not valid IPTC-NAA record data
53           if( bTagMarker != 0x1c ) {
54              BGPError( "IPTC tag marker not valid" );
55              return false;
56  
57           } else {
58              
59              // convert the next two bytes (the Record Number and DataSet Number) to
60              // the format "RR:DDD"  The document titled "IPTC-NAA Information
61              // Interchange Model Version 4" document has these numbers in decimal so
62              // it will be easier to read if we use decimal here too.
63              sDataSetID = new String( Integer.toString( abIPTCrecord[nArrayIndex] ) + ":" +
64                                       Integer.toString( abIPTCrecord[nArrayIndex+1] ) );
65              // increment the array index after reading those two bytes
66              nArrayIndex+=2;
67              
68              // Obtain the length of the data field.  TODO: There is some special handling
69              // that needs to happen if the length of the data field is greater than
70              // 32767 octets.  This is documented on page 15 of the IPTC-NAA IIMV4 doc.
71              nByteCount = hexBytesToInt( abIPTCrecord, nArrayIndex, 2 );
72              // increment the array index after reading those two bytes
73              nArrayIndex+=2;
74              
75              // The next nByteCount bytes are what make up our data field value.
76              sDataSetValue = new String( abIPTCrecord, nArrayIndex, nByteCount );
77              //BGPDebug( "DataSetValue is [" + sDataSetValue + "]" );
78              // Increment the array index after reading the data set's data field
79              nArrayIndex+=nByteCount;
80              
81              // Place the sDataSetID key and the sDataSetValue into our hashtable.
82              // There are some DataSets which can be repeated throughout our data.
83              // For those cases, just append a comma and the additional value
84              if ( hDataSets.get( sDataSetID ) == null ) {
85                 // If it doesn't exist in our hashtable, create it.
86                 hDataSets.put( sDataSetID, sDataSetValue );
87              } else {
88                 // If it does exist, append a comma and the additional value
89                 String sNewValue = null;
90                 sNewValue = new String( ((String)hDataSets.get( sDataSetID )) +
91                                         ", " + sDataSetValue );
92                 // and store it back in the hashtable
93                 hDataSets.put( sDataSetID, sNewValue );
94              }
95              
96           }
97           
98        } // end of while loop
99        return true;
100       
101    } // end of parseIPTCdata method
102       
103    /** This method converts part of an array of bytes into an integer value.
104     * (For our purposes, we will not exceed four bytes.)
105     * @param abHexBytes The array of bytes.  Some of which we will convert to an int.
106     * @param nStartPos The start of our byte value that will be converted.
107     * @param nLength The number of bytes that will be converted
108     * @return Returns an int value of the specifiec portion of our byte array.
109     * (i.e. {0x1C, 0x2B} would be converted to 7211)
110     */
111    protected int hexBytesToInt (byte abHexBytes[], int nStartPos, int nLength) {
112 
113       // The soon-to-be-computed value of the byte array.
114       int nBytesValue = 0;
115       
116       // The number of bits that need to get shifted is equal to one less than the
117       // number of bytes times eight.  (i.e. 0x01, 0xC2 : the first byte 0x01 needs
118       // to be shifted 8 bits to the left before it is added to the second byte 0xC2.
119       int nBitShifter = ( (nLength - 1) * 8 );
120 
121       // process each of the bytes in turn.
122       for ( int i=0; i < nLength; i++ ) {
123                  //BGPDebug( "byte " + i + " is " + abHexBytes[ nStartPos+i ] + 
124                  //            ", and nBitShifter is " + nBitShifter);
125          // arithmatic is always performed at least at 32-bit precision.  This has the
126          // side effect of un-signing our signed byte before we bitshift.
127          nBytesValue |= (( abHexBytes[ nStartPos+i ] & 0x000000ff ) << nBitShifter );
128          // Each byte we process, we need to adjust the distance the bits are shifted.
129          nBitShifter = nBitShifter - 8;
130       }
131       return nBytesValue;
132    }
133 
134   
135    /** Quick (and easily changeable) way of printing an error.
136     * @param sErrorMsg The error string to print
137     */
138    protected void BGPError (String sErrorMsg) {
139       System.out.println (sErrorMsg);
140    }
141 
142 
143    /** Quick (and easily changeable) way of printing a debug statement.
144     * @param sDebugMsg The debug string to print.
145     */
146    protected void BGPDebug (String sDebugMsg) {
147       System.out.println ("{DEBUG: " + sDebugMsg + "}");
148    }
149    
150 }