1 cananian 1.12.2.9  // Util.java, created Mon Aug  3  2:42:35 1998 by cananian
  2 cananian 1.10      // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
  3 cananian 1.10      // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 cananian 1.1       package harpoon.Util;
  5 cananian 1.1       
  6 salcianu 1.20      import harpoon.ClassFile.HCodeElement;
  7 salcianu 1.20      
  8 salcianu 1.12.2.18 import java.util.Collection;
  9 salcianu 1.12.2.18 import java.util.Iterator;
 10 salcianu 1.12.2.18 import java.util.Set;
 11 salcianu 1.12.2.18 import java.util.HashSet;
 12 cananian 1.18      import java.util.List;
 13 salcianu 1.17      import java.util.Map;
 14 salcianu 1.12.2.18 
 15 salcianu 1.12.2.18 import java.io.PrintWriter;
 16 salcianu 1.12.2.18 
 17 cananian 1.1       import java.lang.reflect.Array;
 18 salcianu 1.12.2.20 
 19 salcianu 1.12.2.20 
 20 cananian 1.1       /** 
 21 cananian 1.1        * Miscellaneous static utility functions.
 22 cananian 1.1        * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 23 cananian 1.21       * @version $Id: Util.java,v 1.21 2004/02/08 01:56:15 cananian Exp $
 24 cananian 1.1        */
 25 cananian 1.9       public abstract class Util {
 26 cananian 1.12.2.1    // Util contains only static fields and methods.
 27 cananian 1.12.2.2  
 28 cananian 1.12.2.2    /** If <code>debug</code> is false, we make some efficiency optimizations
 29 cananian 1.12.2.2     *  which are only safe for correct code. */
 30 cananian 1.12.2.1    private static final boolean debug = true;
 31 cananian 1.9       
 32 cananian 1.12.2.2    /** Returns an ArrayFactory which makes an array of the same type as the
 33 cananian 1.12.2.2     *  <code>src</code> parameter (which should be an array of some
 34 cananian 1.12.2.2     *  object type).  This method uses run-time type information and
 35 cananian 1.12.2.2     *  thus <b>should not be used</b>.
 36 cananian 1.12.2.6     *  @deprecated requires java language reflection.
 37 cananian 1.12.2.2     */
 38 cananian 1.12.2.1    public static final ArrayFactory genericFactory(final Object[] src) {
 39 cananian 1.12.2.1      final Class type = src.getClass().getComponentType();
 40 cananian 1.12.2.1      return new ArrayFactory() {
 41 cananian 1.12.2.1        public Object[] newArray(int len) {
 42 cananian 1.12.2.1          return (Object[])Array.newInstance(type, len);
 43 cananian 1.12.2.1        }
 44 cananian 1.12.2.1      };
 45 cananian 1.12.2.1    }
 46 cananian 1.9       
 47 cananian 1.1         /**
 48 cananian 1.1          * Copy an array type to prevent modification.  Does not bother
 49 cananian 1.1          * to copy array types of length 0, because they're already immutable.
 50 cananian 1.12.2.1     * After code has been debugged, this method can skip the copy for
 51 cananian 1.12.2.1     * efficiency.
 52 cananian 1.1          */
 53 cananian 1.14.2.2    public static final <T> T[] safeCopy(ArrayFactory<T> factory, T[] src) {
 54 cananian 1.12.2.1      if (!debug) return src;
 55 cananian 1.1           if (src.length==0) return src;
 56 cananian 1.14.2.2      T[] dst = factory.newArray(src.length);
 57 cananian 1.12.2.3      System.arraycopy(src,0,dst,0,src.length);
 58 cananian 1.12.2.3      return dst;
 59 cananian 1.12.2.1    }
 60 cananian 1.12.2.1      
 61 cananian 1.1         /**
 62 cananian 1.12.2.3     * Copy an array type to prevent modification.
 63 cananian 1.12.2.3     * @deprecated The <code>clone()</code> method on arrays works 
 64 cananian 1.12.2.3     * much better, and should be used instead of this method.
 65 cananian 1.1          */
 66 cananian 1.14.2.2    public static final <T> T[] copy(ArrayFactory<T> factory, T[] src) {
 67 cananian 1.14.2.2      T[] dst = factory.newArray(src.length);
 68 cananian 1.1           System.arraycopy(src,0,dst,0,src.length);
 69 cananian 1.1           return dst;
 70 cananian 1.1         }
 71 cananian 1.7         /** Remove element 'n' from array 'src'. */
 72 cananian 1.14.2.2    public static final <T> T[] shrink(ArrayFactory<T> factory, 
 73 cananian 1.14.2.2                                        T[] src, int n) {
 74 cananian 1.14.2.1      assert src.length>0;
 75 cananian 1.14.2.1      assert n<src.length;
 76 cananian 1.14.2.2      T[] dst = factory.newArray(src.length-1);
 77 cananian 1.7           System.arraycopy(src,   0, dst, 0, n);
 78 cananian 1.7           System.arraycopy(src, n+1, dst, n, src.length-(n+1));
 79 cananian 1.7           return dst;
 80 cananian 1.7         }
 81 cananian 1.7         /** Insert element <code>o</code> before <code>src[n]</code>. <p>
 82 cananian 1.7          *  After return, <code>src[n]==o</code>.  */
 83 cananian 1.14.2.2    public static final <T> T[] grow(ArrayFactory<T> factory,
 84 cananian 1.14.2.2                                      T[] src, T o, int n) {
 85 cananian 1.14.2.1      assert n>=0;
 86 cananian 1.14.2.2      T[] dst = factory.newArray(src.length+1);
 87 cananian 1.7           System.arraycopy(src, 0, dst, 0, n);
 88 cananian 1.7           System.arraycopy(src, n, dst, n+1, src.length-n);
 89 cananian 1.7           dst[n] = o;
 90 cananian 1.7           return dst;
 91 cananian 1.7         }
 92 cananian 1.7       
 93 cananian 1.3         /** Escape the contents of a String so they are safe to print. */
 94 cananian 1.3         public static final String escape(String str) {
 95 cananian 1.3           StringBuffer sb = new StringBuffer();
 96 cananian 1.3           for (int i=0; i<str.length(); i++) {
 97 cananian 1.3             char c = str.charAt(i);
 98 cananian 1.12.2.4        if (!isSafelyPrintable(c)) {
 99 cananian 1.12.2.7          if (c < 256) {
100 cananian 1.12.2.7            String octval=Integer.toOctalString((int)c);
101 cananian 1.12.2.7            while(octval.length()<3) octval="0"+octval;
102 cananian 1.12.2.7            sb.append('\\'); sb.append(octval);
103 cananian 1.12.2.7          } else {
104 cananian 1.12.2.7            String hexval=Integer.toHexString((int)c);
105 cananian 1.12.2.7            while(hexval.length()<4) hexval="0"+hexval;
106 cananian 1.12.2.7            sb.append('\\'); sb.append('u'); sb.append(hexval);
107 cananian 1.12.2.7          }
108 cananian 1.3             }
109 cananian 1.3             else sb.append(c);
110 cananian 1.3           }
111 cananian 1.3           return sb.toString();
112 cananian 1.4         }
113 cananian 1.12.2.4    /** Determine if we should escape this character or print it as-is. */
114 cananian 1.12.2.4    static boolean isSafelyPrintable(char c) {
115 cananian 1.12.2.4      // always escape backslash
116 cananian 1.12.2.4      if (c=='\\') return false;
117 bdemsky  1.12.2.13     // define 'safe' characters.
118 bdemsky  1.12.2.13     if (' ' <= c && c <= '~') return true;
119 bdemsky  1.12.2.13     // all others are 'unsafe'
120 bdemsky  1.12.2.13     return false;
121 bdemsky  1.12.2.13   }
122 bdemsky  1.12.2.13 
123 bdemsky  1.12.2.14   static boolean isJasminKeyWord(String str) {
124 bdemsky  1.12.2.14     if (str.equals("method")) 
125 bdemsky  1.12.2.14       return true;
126 bdemsky  1.12.2.14     if (str.equals("from")) 
127 bdemsky  1.12.2.14       return true;
128 bdemsky  1.12.2.14     if (str.equals("to")) 
129 bdemsky  1.12.2.14       return true;
130 bdemsky  1.12.2.14     if (str.equals("is")) 
131 bdemsky  1.12.2.14       return true;
132 bdemsky  1.12.2.14     if (str.equals("using")) 
133 bdemsky  1.12.2.14       return true;
134 bdemsky  1.12.2.14     if (str.equals("tableswitch")) 
135 bdemsky  1.12.2.14       return true;
136 bdemsky  1.12.2.14     if (str.equals("lookupswitch")) 
137 bdemsky  1.12.2.14       return true;
138 bdemsky  1.12.2.14     return false;
139 bdemsky  1.12.2.14   }
140 bdemsky  1.12.2.14 
141 bdemsky  1.12.2.13   /** Escape the contents of a String so they are safe to print. */
142 bdemsky  1.12.2.13   public static final String jasminEscape(String str) {
143 bdemsky  1.12.2.14     boolean flag;
144 bdemsky  1.12.2.13     StringBuffer sb = new StringBuffer();
145 bdemsky  1.12.2.14     flag=isJasminKeyWord(str);
146 bdemsky  1.12.2.13     for (int i=0; i<str.length(); i++) {
147 bdemsky  1.12.2.13       char c = str.charAt(i);
148 bdemsky  1.12.2.14       if (!jasminIsSafelyPrintable(c)||flag) {
149 bdemsky  1.12.2.14         flag=false;
150 bdemsky  1.12.2.13         if (c < 256) {
151 bdemsky  1.12.2.13           String octval=Integer.toOctalString((int)c);
152 bdemsky  1.12.2.13           while(octval.length()<3) octval="0"+octval;
153 bdemsky  1.12.2.13           sb.append('\\'); sb.append(octval);
154 bdemsky  1.12.2.13         } else {
155 bdemsky  1.12.2.13           String hexval=Integer.toHexString((int)c);
156 bdemsky  1.12.2.13           while(hexval.length()<4) hexval="0"+hexval;
157 bdemsky  1.12.2.13           sb.append('\\'); sb.append('u'); sb.append(hexval);
158 bdemsky  1.12.2.13         }
159 cananian 1.3             }
160 cananian 1.3             else sb.append(c);
161 cananian 1.3           }
162 cananian 1.3           return sb.toString();
163 cananian 1.4         }
164 bdemsky  1.12.2.13   /** Determine if we should escape this character or print it as-is. */
165 bdemsky  1.12.2.13   static boolean jasminIsSafelyPrintable(char c) {
166 bdemsky  1.12.2.13     // always escape backslash
167 bdemsky  1.12.2.13     if (c=='\\') return false;
168 pnkfelix 1.12.2.15     if (c=='\"') return false;
169 cananian 1.12.2.4      // define 'safe' characters.
170 cananian 1.12.2.4      if (' ' <= c && c <= '~') return true;
171 cananian 1.12.2.4      // all others are 'unsafe'
172 cananian 1.12.2.4      return false;
173 cananian 1.12.2.19   }
174 cananian 1.12.2.19 
175 pnkfelix 1.12.2.11   /** Return a <code>String</code> representing the elements of
176 pnkfelix 1.12.2.11       <code>collection</code> in a human readable format.  
177 pnkfelix 1.12.2.11       <BR> <B>effects:</B> Iterates over <code>collection</code>,
178 pnkfelix 1.12.2.11            calling <code>toString()</code> on each element and
179 pnkfelix 1.12.2.11            appending the result to a <code>String</code>.  The format
180 pnkfelix 1.12.2.11            of the returned <code>String</code> is 
181 pnkfelix 1.12.2.11            <NOBR>{ elem1, elem2, ... , elemN }</NOBR>
182 pnkfelix 1.12.2.11       @return A <code>String</code> representing
183 pnkfelix 1.12.2.11               <code>collection</code>. 
184 pnkfelix 1.12.2.11   */
185 pnkfelix 1.12.2.11   public static final String print(java.util.Collection collection) {
186 pnkfelix 1.12.2.11     StringBuffer sb = new StringBuffer("{ ");
187 pnkfelix 1.12.2.11     java.util.Iterator iter = collection.iterator();
188 pnkfelix 1.12.2.11     while(iter.hasNext()) {
189 pnkfelix 1.12.2.11       Object elem = iter.next();
190 pnkfelix 1.12.2.11       sb.append(elem.toString());
191 pnkfelix 1.12.2.11       if (iter.hasNext()) {
192 pnkfelix 1.12.2.11         sb.append(", ");
193 pnkfelix 1.12.2.11       }
194 pnkfelix 1.12.2.11     }
195 pnkfelix 1.12.2.11     sb.append(" }");
196 pnkfelix 1.12.2.11     return sb.toString();
197 salcianu 1.12.2.18   }
198 salcianu 1.12.2.18 
199 salcianu 1.12.2.18   /** Pretty printer for collections.
200 salcianu 1.12.2.18 
201 salcianu 1.12.2.18       @param c The <code>Collection</code> to be printed.
202 salcianu 1.12.2.18       @param c_name The name of the collection.
203 salcianu 1.12.2.18       @param indent String used for indentation (eg &quot;<code>\t</code>&quot;.
204 salcianu 1.12.2.18       @param pw The <code>PrintWriter</code> used to do the printing itself.
205 salcianu 1.12.2.18 
206 salcianu 1.12.2.18       The collection is printed in the following format: the name of
207 salcianu 1.12.2.18   the collection followed by the collection size (in parans) and one
208 salcianu 1.12.2.18   opening curly bracet on the first line, the elements of the
209 salcianu 1.12.2.18   collection, one by one, each on a separate line and indented with a
210 salcianu 1.12.2.18   tab; on the last line, one closing curly bracet. In addition, each
211 salcianu 1.12.2.18   line is prefixed with the string <code>indent</code>. */
212 salcianu 1.12.2.18   public static final void print_collection(Collection c, String c_name,
213 salcianu 1.12.2.18                                             String indent, PrintWriter pw) {
214 salcianu 1.12.2.18     pw.print(indent + c_name + " (" + c.size() + "): {");
215 salcianu 1.12.2.18     if(c.isEmpty()) {
216 salcianu 1.12.2.18       pw.println("}");
217 salcianu 1.12.2.18       return;
218 salcianu 1.12.2.18     }
219 salcianu 1.12.2.18     pw.println();
220 salcianu 1.12.2.18     for(Iterator it = c.iterator(); it.hasNext(); ) {
221 salcianu 1.12.2.18       pw.print(indent);
222 salcianu 1.12.2.18       pw.print("\t");
223 salcianu 1.12.2.18       pw.println(it.next());
224 salcianu 1.12.2.18     }
225 salcianu 1.12.2.18     pw.println(indent + "}");
226 salcianu 1.12.2.18   }
227 salcianu 1.12.2.18 
228 salcianu 1.12.2.18   /** Simplified version of <code>print_collection</code>.
229 salcianu 1.12.2.18       Uses the default value
230 salcianu 1.12.2.18       <code>new java.io.PrintWriter(System.out, true)</code>
231 salcianu 1.12.2.18       for the <code>pw</code> parameter. */
232 salcianu 1.12.2.18   public static final void print_collection(Collection c, String c_name,
233 salcianu 1.12.2.18                                             String indent) {
234 salcianu 1.12.2.18     print_collection(c, c_name, indent,
235 salcianu 1.12.2.18                      new java.io.PrintWriter(System.out, true));
236 salcianu 1.12.2.18   }
237 salcianu 1.12.2.18 
238 salcianu 1.12.2.18 
239 salcianu 1.12.2.18   /** Even more simplified version of <code>print_collection</code>.
240 salcianu 1.12.2.18       Uses the default value <code>&quot;&quot;</code> for <code>indent</code>
241 salcianu 1.12.2.18       and <code>new java.io.PrintWriter(System.out, true)</code>
242 salcianu 1.12.2.18       for the <code>pw</code> parameter. */
243 salcianu 1.12.2.18   public static final void print_collection(Collection c, String c_name) {
244 salcianu 1.12.2.18     print_collection(c, c_name, "");
245 salcianu 1.12.2.18   }
246 salcianu 1.12.2.18 
247 salcianu 1.12.2.18   /** Computes the difference of two sets: <code>a-b</code>. */
248 cananian 1.14.2.3    public static final <A,B> Set<A> set_diff(final Set<A> a, final Set<B> b) {
249 cananian 1.14.2.3      Set<A> diff = new HashSet<A>(a);
250 salcianu 1.12.2.18     diff.removeAll(b);
251 salcianu 1.12.2.18     return diff;
252 salcianu 1.12.2.20   }
253 salcianu 1.12.2.20 
254 salcianu 1.17      
255 salcianu 1.12.2.20   /** Returns a string that is identical to <code>str</code>, except
256 salcianu 1.12.2.20       that every <code>&quot;</code> character has been replaced with
257 salcianu 1.12.2.20       the sequence <code>\&quot;</code>.
258 salcianu 1.12.2.20       This is useful when we generate output for
259 salcianu 1.12.2.20       tools like VCG which expects the value of some attributes to be put
260 salcianu 1.12.2.20       between quotes (and of course any quote inside has to be given using
261 salcianu 1.12.2.20       an escape sequence). */
262 salcianu 1.12.2.20   public static final String adjust_quotes(String str) {
263 salcianu 1.12.2.20     StringBuffer buff = new StringBuffer();
264 salcianu 1.12.2.20     for(int i = 0; i < str.length(); i++) {
265 salcianu 1.12.2.20       char c = str.charAt(i);
266 salcianu 1.12.2.20       if(c == '\"')
267 salcianu 1.12.2.20         buff.append("\\\"");
268 salcianu 1.12.2.20       else
269 salcianu 1.12.2.20         buff.append(c);
270 salcianu 1.12.2.20     }
271 salcianu 1.12.2.20     return buff.toString();
272 salcianu 1.12.2.20   }
273 salcianu 1.17      
274 salcianu 1.17        /** Converts an objects using the reflexive closure of a map.
275 salcianu 1.17            @param obj object to be converted
276 salcianu 1.17            @param map conversion map
277 salcianu 1.17            @return if <code>obj</code> is in the key set of
278 salcianu 1.17            <code>map</code>, returns <code>map.get(obj)</code>. Otherwise,
279 salcianu 1.17            the method simply returns <code>obj</code>. */
280 salcianu 1.17        public static Object convert(Object obj, Map map) {
281 salcianu 1.17          Object image = map.get(obj);
282 salcianu 1.17          return (image == null) ? obj : image;
283 salcianu 1.17        }
284 salcianu 1.17      
285 salcianu 1.20      
286 salcianu 1.20        // the powers of 10!!
287 salcianu 1.20        private static double[] fact = 
288 salcianu 1.20        {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0};
289 salcianu 1.20        
290 salcianu 1.20      
291 salcianu 1.20        /** Returns the string representation of the double d, with a certain
292 salcianu 1.20            number of decimals. Let me know if you know something better. */
293 salcianu 1.20        public static String doubleRep(double d, int decimals) {
294 salcianu 1.20          double dfloor = Math.floor(d); // (double) integer part of d
295 salcianu 1.20          double dfrac = d - dfloor;     // fractional part of d
296 salcianu 1.20          int ifloor = (int) dfloor;     // integer part of d
297 salcianu 1.20          // the last d decimals
298 salcianu 1.20          int fracint = (int) Math.ceil(dfrac * fact[decimals]); 
299 salcianu 1.20          
300 salcianu 1.20          StringBuffer fracstr = new StringBuffer(String.valueOf(fracint));
301 salcianu 1.20          int missing_decs = decimals - fracstr.length();
302 salcianu 1.20          for(int i = 0; i < missing_decs; i++)
303 salcianu 1.20            fracstr.append("0");
304 salcianu 1.20          
305 salcianu 1.20          return String.valueOf(ifloor) + "." + fracstr.toString();
306 salcianu 1.20        }
307 salcianu 1.20        
308 salcianu 1.20        /** Returns the string representation of the double d, with a certain
309 salcianu 1.20            number of decimals. Let me know if you know something better. */
310 salcianu 1.20        public static String doubleRep(double d, int digits, int decimals) {
311 salcianu 1.20          StringBuffer buffer = new StringBuffer(doubleRep(d,decimals));
312 salcianu 1.20          int desired_point = digits - decimals - 1;
313 salcianu 1.20          int current_point = buffer.toString().indexOf(".");
314 salcianu 1.20          int needed_spaces = desired_point - current_point;
315 salcianu 1.20          if(needed_spaces == 0) return buffer.toString();
316 salcianu 1.20          StringBuffer buffer2 = new StringBuffer();
317 salcianu 1.20          for(int i = 0; i < needed_spaces; i++)
318 salcianu 1.20            buffer2.append(" ");
319 salcianu 1.20          return buffer2.toString() + buffer.toString();
320 salcianu 1.20        }
321 salcianu 1.20        
322 salcianu 1.20        /** Returns a string representing the proportion a/total (in percents). */
323 salcianu 1.20        public static String percentage(double a, double total) {
324 salcianu 1.20          double perct = (100.0 * a) / total;
325 salcianu 1.20          return doubleRep(perct, 5, 2) + "%";
326 salcianu 1.20        }
327 salcianu 1.20        
328 salcianu 1.20        /** Returns the line of the instruction q in the format
329 salcianu 1.20            <code>source_file:line_number</code>. */
330 salcianu 1.20        public static String getLine(HCodeElement q) {
331 salcianu 1.20          return
332 salcianu 1.20            q.getSourceFile() + ":" + q.getLineNumber();
333 salcianu 1.20        }
334 salcianu 1.20        
335 salcianu 1.20        /** Returns the string representation of the code instruction q
336 salcianu 1.20            in the formay: <code>source_file:line_number instruction</code>. */
337 salcianu 1.20        public static String code2str(HCodeElement q) {
338 salcianu 1.20          if(q == null) return "(null)";
339 salcianu 1.20          return
340 salcianu 1.20            getLine(q)  + " " + q;
341 salcianu 1.20        }
342 salcianu 1.20        
343 salcianu 1.20        /** Returns the string representation of the proportion a/b.  The
344 salcianu 1.20            proportion is printed as a percentage, with 2 decimals.  Eg,
345 salcianu 1.20            1/2 is presented as 50.00%. */
346 salcianu 1.20        public static String proportion2str(long a, long b) {
347 salcianu 1.20          double frac = (((double) 100) * ((double) a)) / ((double) b);
348 salcianu 1.20          return doubleRep(frac, 5, 2) + "%";
349 salcianu 1.20        }
350 salcianu 1.20      
351 salcianu 1.20      
352 salcianu 1.20        /** Pretty printer for a proportion: &quot; <tt>a</tt> out of
353 salcianu 1.20            <tt>total</tt> = <tt>proportion</tt>&quot; (where
354 salcianu 1.20            <tt>total=a+b</tt>). If <code>memSizeFormat<code> is true,
355 salcianu 1.20            <tt>a</tt> and <tt>total</tt> are displayed as memory size
356 salcianu 1.20            (i.e., 2048 is 2K). <code>digits</code> and
357 salcianu 1.20            <code>decimals</code> indicates the formatting for the
358 salcianu 1.20            proportion. */
359 salcianu 1.20        public static String longProportion
360 salcianu 1.20          (long a, long b, int digits, int decimals, boolean memSizeFormat) {
361 salcianu 1.20          long total = a + b;
362 salcianu 1.20          double frac = (a * 100.0) / (total + 0.0);
363 salcianu 1.20          return 
364 salcianu 1.20            (memSizeFormat ? Util.memSizeFormat(a) : (new Long(a)).toString()) +
365 salcianu 1.20            "\tout of\t" + 
366 salcianu 1.20            (memSizeFormat ? Util.memSizeFormat(total) : 
367 salcianu 1.20             (new Long(total)).toString()) +
368 salcianu 1.20            "\t = " +
369 salcianu 1.20            doubleRep(frac, digits, decimals) + "%";
370 salcianu 1.20        }
371 salcianu 1.20      
372 salcianu 1.20        /** Convenient version of <code>longProportion</code> that uses
373 salcianu 1.20            <code>null</code> for the <code>memSizeFormat</code>. */
374 salcianu 1.20        public static String longProportion
375 salcianu 1.20          (long a, long b, int digits, int decimals) {
376 salcianu 1.20          return longProportion(a, b, digits, decimals, false);
377 salcianu 1.20        }
378 salcianu 1.20        
379 salcianu 1.20      
380 salcianu 1.20        /** Nicely formats the memory size <code>size</code>, using normal
381 salcianu 1.20            units for memory size.  For example, 2048 is printed as 2.00K.
382 salcianu 1.20            The biggest unit we support now is Tera.  */
383 salcianu 1.20        public static String memSizeFormat(long size) {
384 salcianu 1.20          // special case: size < 1K
385 salcianu 1.20          if(size < 1024)
386 salcianu 1.20            return (new Long(size)).toString();
387 salcianu 1.20          
388 salcianu 1.20          double dsize = (double) size;
389 salcianu 1.20          int index = 0;
390 salcianu 1.20          while((dsize > 1024) && (index < msf_units.length)) {
391 salcianu 1.20            dsize = dsize / 1024;
392 salcianu 1.20            index++;
393 salcianu 1.20          }
394 salcianu 1.20          return doubleRep(dsize, 2) + msf_units[index];
395 salcianu 1.20        }
396 salcianu 1.20        private static String msf_units[] = {"", "K", "M", "G", "T"};
397 salcianu 1.12.2.20 
398 cananian 1.1       }
399 cananian 1.3       
400 cananian 1.3       // set emacs indentation style.
401 cananian 1.3       // Local Variables:
402 cananian 1.3       // c-basic-offset:2
403 cananian 1.3       // End: