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