001    /* MBEL: The Microsoft Bytecode Engineering Library
002     * Copyright (C) 2003 The University of Arizona
003     * http://www.cs.arizona.edu/mbel/license.html
004     *
005     * This library is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU Lesser General Public
007     * License as published by the Free Software Foundation; either
008     * version 2.1 of the License, or (at your option) any later version.
009     * 
010     * This library is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013     * Lesser General Public License for more details.
014     * 
015     * You should have received a copy of the GNU Lesser General Public
016     * License along with this library; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018     */
019    
020    package edu.arizona.cs.mbel.metadata;
021    
022    /** This class represents the user string stream in module metadata.
023      * User strings are UNICODE-16 strings, little-endian. They are single-null terminated.
024      * @author Michael Stepp
025      */
026    public class USStream{
027       // should be 4-byte aligned
028       private byte[] rawbytes;
029    
030       /** Parses a USStream from an input stream, of the given size
031         * @param in the input stream
032         * @param size the size in bytes of this USStream
033         */
034       public USStream(edu.arizona.cs.mbel.MSILInputStream in, long size) throws java.io.IOException{
035          rawbytes = new byte[(int)size];
036          in.read(rawbytes);
037       }
038    
039       /*
040       public void output(){
041          System.out.print("#USStream = {}");
042       }
043       */
044    
045       /** Returns a string from the user string stream, indexed by byte offset
046         * @param off the byte offset within the stream of the start of the string
047         * @return the string at the given offset
048         */
049       public String getStringByOffset(long off){
050          int length;
051          int offset = (int)off;
052          if ((rawbytes[offset] & 0xC0) == 0xC0){
053             // 4byte length
054             length = ((rawbytes[offset] << 24) & 0x1F000000)
055                    | ((rawbytes[offset+1] << 16) & 0x00FF0000)
056                    | ((rawbytes[offset+2] << 8) & 0x0000FF00)
057                    | (rawbytes[offset+3] & 0xFF);
058             offset+=4;
059          }else if ((rawbytes[offset] & 0x80) == 0x80){
060             length = ((rawbytes[offset]<<8) & 0x3F00) | (rawbytes[offset+1] & 0xFF);
061             offset+=2;
062          }else{
063             length = rawbytes[offset];
064             offset++;
065          }
066    
067          String result = "";
068          for (int i=0;(i+i)<length-1;i++)
069             result += (char)(rawbytes[offset+i+i] | (rawbytes[offset+i+i+1]<<8));
070          return result;
071       }
072    }
073