]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/units/internal/library/UnitLibrary.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / units / internal / library / UnitLibrary.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.units.internal.library;
13
14 import gnu.trove.map.hash.THashMap;
15 import gnu.trove.map.hash.TObjectIntHashMap;
16 import gnu.trove.procedure.TObjectIntProcedure;
17 import gnu.trove.procedure.TObjectObjectProcedure;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.io.Reader;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.Set;
27
28 import org.simantics.databoard.Units;
29 import org.simantics.databoard.file.RuntimeIOException;
30 import org.simantics.databoard.units.internal.UnitParseException;
31 import org.simantics.databoard.units.internal.parser.UnitParser;
32
33 public class UnitLibrary {
34
35         final THashMap<String, UnitConversion> conversions = 
36                 new THashMap<String, UnitConversion>();
37
38         public Set<String> getUnits() {
39                 return conversions.keySet();
40         }
41
42         public UnitConversion getConversion(String unit) {
43                 return conversions.get(unit);
44         }
45         
46         private static final String[] PREFIXES = new String[] {
47                 "y", "z", "a", "f", "p", "n", "ยต", "m", "c", "d", "da", "h", "k", "M", "G", "T", "P", "E", "Z", "Y"
48         };
49         
50         private static final int[] PREFIX_MAGNITUDES = new int[] {
51                 -24, -21, -18, -15, -12, -9, -6, -3, -2, -1, 1, 2, 3, 6, 9, 12, 15, 18, 21, 24
52         };
53         
54         
55         public static List<String> readTokens(InputStream stream) throws IOException {
56             Reader reader = new InputStreamReader(stream);
57             StringBuilder b = new StringBuilder();
58             ArrayList<String> strings = new ArrayList<String>();
59             while(true) {
60                 int c = reader.read();
61                 if(c == -1) {
62                     if(b.length() > 0)
63                     strings.add(b.toString());
64                     break;
65                 }
66                 if(c == ' ' || c == '\t' || c == '\n' || c == '\r') {
67                     if(b.length() > 0) {
68                         strings.add(b.toString());
69                         b.setLength(0);
70                     }
71                 }
72                 else
73                     b.append((char)c);
74             }
75             reader.close();
76             return strings;
77         }
78                 
79         private UnitConversion parseUnit(String unit) throws UnitParseException {           
80             final TObjectIntHashMap<String> exponents = new TObjectIntHashMap<String>(4);
81         final double[] scale = new double[] { 1.0 };
82         final int[] magnitude = new int[] { 0 };
83         new UnitParser() {
84             public void visit(String baseUnit, int exponent) {
85                 UnitConversion conversion = conversions.get(baseUnit);
86                 if(conversion == null) {
87                     if(exponents.adjustOrPutValue(baseUnit, exponent, exponent) == 0)
88                         exponents.remove(baseUnit);
89                 }
90                 else {
91                     scale[0] *= Math.pow(conversion.scale, exponent);
92                     magnitude[0] += conversion.magnitude * exponent;
93                     for(int i=0;i<conversion.baseUnits.length;++i) {
94                         String u = conversion.baseUnits[i];
95                         int exp = conversion.exponents[i]; 
96                         if(exponents.adjustOrPutValue(u, exp, exp) == 0)
97                             exponents.remove(u);
98                     }
99                 }
100             }
101         }.unit(unit, 1);
102         final String[] unitArray = new String[exponents.size()];
103         final int[] exponentArray = new int[exponents.size()];
104         exponents.forEachEntry(new TObjectIntProcedure<String>() {
105             int i = 0;
106
107             @Override
108             public boolean execute(String arg0, int arg1) {
109                 unitArray[i] = arg0;
110                 exponentArray[i] = arg1;
111                 ++i;
112                 return true;
113             }
114         });
115         return new UnitConversion(
116             scale[0],
117             magnitude[0],
118             unitArray,
119             exponentArray
120             );
121         }
122         
123         public static UnitLibrary createDefault() {
124                 UnitLibrary result = new UnitLibrary();
125                 
126             try {
127             for(String unit : readTokens( Units.class.getResourceAsStream("baseUnits.txt") ))
128                 for(int i=0;i<PREFIXES.length;++i)
129                     result.conversions.put(PREFIXES[i] + unit, 
130                         new UnitConversion(1.0, PREFIX_MAGNITUDES[i], unit));
131             
132             {
133                 List<String> units = readTokens( Units.class.getResourceAsStream("scalableDerivedUnits.txt") );              
134                 for(int i=0;i<units.size();i+=3) {
135                     UnitConversion conversion = result.parseUnit(units.get(i+2));
136                     conversion.scale *= Double.parseDouble(units.get(i+1));
137                     String unit = units.get(i);
138                     result.conversions.put(unit, conversion);
139                     
140                     for(int j=0;j<PREFIXES.length;++j) {
141                         UnitConversion scaledConversion = 
142                             new UnitConversion(conversion.scale, 
143                                 conversion.magnitude + PREFIX_MAGNITUDES[j],
144                                 conversion.baseUnits, conversion.exponents);
145                         result.conversions.put(PREFIXES[j] + unit, scaledConversion);
146                     }
147                 }
148             }    
149             
150             {
151                 List<String> units = readTokens( Units.class.getResourceAsStream("nonscalableDerivedUnits.txt") );               
152                 for(int i=0;i<units.size();i+=3) {
153                     UnitConversion conversion = result.parseUnit(units.get(i+2));
154                     conversion.scale *= Double.parseDouble(units.get(i+1));
155                     result.conversions.put(units.get(i), conversion);
156                 }
157             }
158             return result;
159                                     
160             } catch (UnitParseException e) {
161                 throw new RuntimeException( e );
162         } catch (IOException e) {
163                 throw new RuntimeIOException( e );
164                 }
165             
166         }
167         
168         public static void main(String[] args) {
169                 UnitLibrary lib = UnitLibrary.createDefault();
170             lib.conversions.forEachEntry(new TObjectObjectProcedure<String, UnitConversion>() {
171
172             @Override
173             public boolean execute(String unit, UnitConversion conversion) {
174                 System.out.println(unit + " = " + conversion.scale + 
175                     " * 10^" + conversion.magnitude + ", base=" + Arrays.toString(conversion.baseUnits));
176                 return true;
177             }
178              
179             });
180     }
181         
182 }