source: trunk/src/fortran/RpUnitsFInterface.cc @ 829

Last change on this file since 829 was 568, checked in by dkearney, 14 years ago

reworking of the Rappture Units code.
Rappture Units no longer creates an object for each metric extension of every
metric unit. Now the metric prefixes are kept in the dictionary as unit objects,
and when a unit is parsed out of the string received from the user, the unit
is checked to see if it acccepts metric prefixes, if so, a search is done for
the prefix. This allows Rappture Units code to more easily tackle case insensitive
unit name searches. Eventually the prefixes will be removed as direct Rappture Units objects and be turned into (possibly a derived object) rappture units prefix objects.

The find function of the core Rappture Units code now accepts
a "hints" function pointer. The function pointer is executed by the dictionary when
the dictionary thinks it found a matching object. This allows the user of the
dictionary to insert different objects with the same key. For Rappture Units,
multiple units objects with the same key can be inserted into the dictionary.
This is important for units like "A" which could stand for angstroms or amperes.

Additionally, the "make metric" functions were removed because the idea of being a
metric unit has been reduced to a flag inside the Rappture Units object and some
newly added logic. The role of setting the metric flag has been added to the define()
function as an additional function input. The fortran and c code has been updated to
reflect the removal of the function. No updates were made to the define function in
the fortran and c code.

The units.test file was also updated with new tests. Old tests were updated, removing
derived units from the list of compatible units. When searching for micro-meters (um),
compatible units of (A,in,m) will be provided instead of (A,in,m,um).

File size: 5.5 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  INTERFACE: Fortran Rappture Units Source
4 *
5 * ======================================================================
6 *  AUTHOR:  Derrick Kearney, Purdue University
7 *  Copyright (c) 2004-2005  Purdue Research Foundation
8 *
9 *  See the file "license.terms" for information on usage and
10 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 * ======================================================================
12 */
13
14#include "RpUnits.h"
15#include "string.h"
16#include "RpUnitsFInterface.h"
17#include "RpUnitsFStubs.c"
18#include "RpBindingsDict.h"
19
20int
21rp_define_unit( char* unitName,
22                    int* basisName,
23                    int unitName_len    ) {
24
25    int result = -1;
26    const RpUnits* newUnit = NULL;
27    const RpUnits* basis = NULL;
28    std::string basisStrName = "";
29    std::string newUnitName = "";
30    char* inText = NULL;
31
32    inText = null_terminate(unitName,unitName_len);
33
34    if (basisName && *basisName) {
35        basisStrName = ObjDictUnits.find(*basisName);
36
37        if (basisStrName != "") {
38            basis = RpUnits::find(basisStrName);
39        }
40    }
41
42    newUnit = RpUnits::define(inText, basis);
43
44    if (newUnit) {
45        result = storeObject_UnitsStr(newUnit->getUnitsName());
46    }
47
48    if (inText) {
49        free(inText);
50    }
51
52    return result;
53}
54
55
56int
57rp_find(char* searchName, int searchName_len)
58{
59
60    int result = -1;
61    char* inText = NULL;
62
63    inText = null_terminate(searchName,searchName_len);
64
65    const RpUnits* searchUnit = RpUnits::find(inText);
66
67    if (searchUnit) {
68        result = storeObject_UnitsStr(searchUnit->getUnitsName());
69    }
70
71    if (inText) {
72        free(inText);
73    }
74
75    return result;
76}
77
78int
79rp_get_units(int* unitRefVal, char* retText, int retText_len)
80{
81    const RpUnits* unitObj = NULL;
82    std::string unitNameText = "";
83    int result = 1;
84
85    if (unitRefVal && *unitRefVal) {
86        unitObj = getObject_UnitsStr(*unitRefVal);
87        if (unitObj) {
88            unitNameText = unitObj->getUnits();
89            fortranify(unitNameText.c_str(), retText, retText_len);
90            result = 0;
91        }
92    }
93
94    return result;
95}
96
97int
98rp_get_units_name(int* unitRefVal, char* retText, int retText_len)
99{
100    const RpUnits* unitObj = NULL;
101    std::string unitNameText = "";
102    int result = 1;
103
104    if (unitRefVal && *unitRefVal) {
105        unitObj = getObject_UnitsStr(*unitRefVal);
106        if (unitObj) {
107            unitNameText = unitObj->getUnitsName();
108            fortranify(unitNameText.c_str(), retText, retText_len);
109            result = 0;
110        }
111    }
112
113    return result;
114}
115
116int
117rp_get_exponent(int* unitRefVal, double* retExponent)
118{
119    const RpUnits* unitObj = NULL;
120    int result = 1;
121
122    if (unitRefVal && *unitRefVal) {
123        unitObj = getObject_UnitsStr(*unitRefVal);
124        if (unitObj) {
125            *retExponent = unitObj->getExponent();
126            result = 0;
127        }
128    }
129
130    return result;
131}
132
133int
134rp_get_basis(int* unitRefVal)
135{
136    const RpUnits* unitObj = NULL;
137    const RpUnits* basisObj = NULL;
138    int result = -1;
139
140    if (unitRefVal && *unitRefVal) {
141        unitObj = getObject_UnitsStr(*unitRefVal);
142
143        if (unitObj) {
144            basisObj = unitObj->getBasis();
145
146            if (basisObj) {
147                result = storeObject_UnitsStr(basisObj->getUnitsName());
148            }
149        }
150    }
151
152    return result;
153}
154
155int
156rp_units_convert_dbl (  char* fromVal,
157                        char* toUnitsName,
158                        double* convResult,
159                        int fromVal_len,
160                        int toUnitsName_len ) {
161
162    char* inFromVal = NULL;
163    char* inToUnitsName = NULL;
164    int result = -1;
165    int showUnits = 0;
166    std::string convStr = "";
167
168    // prepare string for c
169    inFromVal = null_terminate(fromVal,fromVal_len);
170    inToUnitsName = null_terminate(toUnitsName,toUnitsName_len);
171
172    if (inFromVal && inToUnitsName) {
173        // the call to RpUnits::convert() populates the result flag
174        convStr = RpUnits::convert(inFromVal,inToUnitsName,showUnits,&result);
175
176        if (!convStr.empty()) {
177            *convResult = atof(convStr.c_str());
178        }
179    }
180
181    // clean up memory
182    if (inFromVal) {
183        free(inFromVal);
184        inFromVal = NULL;
185    }
186
187    if (inToUnitsName) {
188        free(inToUnitsName);
189        inToUnitsName = NULL;
190    }
191
192    return result;
193}
194
195int
196rp_units_convert_str (      char* fromVal,
197                            char* toUnitsName,
198                            char* retText,
199                            int fromVal_len,
200                            int toUnitsName_len,
201                            int retText_len     ) {
202
203    char* inFromVal = NULL;
204    char* inToUnitsName = NULL;
205    std::string convStr = "";
206    int showUnits = 1;
207    int result = -1;
208
209    // prepare string for c
210    inFromVal = null_terminate(fromVal,fromVal_len);
211    inToUnitsName = null_terminate(toUnitsName,toUnitsName_len);
212
213    if (inFromVal && inToUnitsName) {
214
215        // do the conversion
216        convStr = RpUnits::convert(inFromVal,inToUnitsName,showUnits,&result);
217
218        if (!convStr.empty()) {
219            // prepare string for fortran
220            fortranify(convStr.c_str(), retText, retText_len);
221        }
222    }
223
224    // clean up out memory
225    if (inFromVal) {
226        free(inFromVal);
227        inFromVal = NULL;
228    }
229
230    if (inToUnitsName) {
231        free(inToUnitsName);
232        inToUnitsName = NULL;
233    }
234
235    // return the same result from the RpUnits::convert call.
236    return result;
237}
Note: See TracBrowser for help on using the repository browser.