2
This file is part of the Free Pascal run time library.
3
Copyright (c) 2004 by Marco van de Voort
4
member of the Free Pascal development team.
6
An implementation for unit convutils, which converts between
7
units and simple combinations of them.
9
Based on a guessed interface derived from some programs on the web. (Like
10
Marco Cantu's EuroConv example), so things can be a bit Delphi
11
incompatible. Also part on Delphibasics.co.uk.
13
Quantities are mostly taken from my HP48g/gx or the unix units program
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY;without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
**********************************************************************}
28
Type TConvType = type Integer;
29
TConvFamily = type Integer;
30
TConvFamilyArray = array of TConvFamily;
31
TConvTypeArray = array of TConvType;
32
TConversionProc = function(const AValue: Double): Double;
35
Type TConvUtilFloat = double;
37
Function RegisterConversionFamily(Const S : String):TConvFamily;
38
Function RegisterConversionType(Fam:TConvFamily;Const S:String;Value:TConvUtilFloat):TConvType;
40
function Convert ( const Measurement : Double; const FromType, ToType : TConvType ) :TConvUtilFloat;
41
function Convert ( const Measurement : Double; const FromType1, FromType2, ToType1, ToType2 : TConvType ) :TConvUtilFloat;
43
function ConvFamilyToDescription(const AFamily: TConvFamily): string;
44
function ConvTypeToDescription(const AType: TConvType): string;
45
procedure GetConvFamilies(out AFamilies: TConvFamilyArray);
46
procedure GetConvTypes(const AFamily: TConvFamily; out ATypes: TConvTypeArray);
49
TConvTypeInfo = Class(Tobject)
51
FDescription : String;
52
FConvFamily : TConvFamily;
53
FConvType : TConvType;
55
Constructor Create(Const AConvFamily : TConvFamily;const ADescription:String);
56
function ToCommon(const AValue: Double) : Double; virtual; abstract;
57
function FromCommon(const AValue: Double) : Double; virtual; abstract;
58
property ConvFamily : TConvFamily read FConvFamily;
59
property ConvType : TConvType read FConvType;
60
property Description: String read FDescription;
63
TConvTypeFactor = class(TConvTypeInfo)
67
property Factor: Double read FFactor;
69
constructor Create(const AConvFamily: TConvFamily; const ADescription: string;
70
const AFactor: Double);
71
function ToCommon(const AValue: Double): Double; override;
72
function FromCommon(const AValue: Double): Double; override;
75
TConvTypeProcs = class(TConvTypeInfo)
77
FToProc: TConversionProc;
78
FFromProc: TConversionProc;
80
constructor Create(const AConvFamily: TConvFamily; const ADescription: string;
81
const AToProc, AFromProc: TConversionProc);
82
function ToCommon(const AValue: Double): Double; override;
83
function FromCommon(const AValue: Double): Double; override;
88
Type ResourceData = record
90
Value : TConvUtilFloat;
95
var TheUnits : array of ResourceData =nil;
96
TheFamilies : array of string =nil;
98
function ConvFamilyToDescription(const AFamily: TConvFamily): string;
102
if AFamily<length(TheFamilies) then
103
result:=TheFamilies[AFamily];
106
procedure GetConvFamilies(out AFamilies: TConvFamilyArray);
110
setlength(AFamilies,length(thefamilies));
111
for i:=0 to length(TheFamilies)-1 do
115
procedure GetConvTypes(const AFamily: TConvFamily; out ATypes: TConvTypeArray);
117
var i,j,nrTypes:integer;
121
for i:=0 to length(TheUnits)-1 do
122
if TheUnits[i].fam=AFamily Then
124
setlength(atypes,nrtypes);
126
for i:=0 to length(TheUnits)-1 do
127
if TheUnits[i].fam=AFamily Then
134
function ConvTypeToDescription(const AType: TConvType): string;
138
if AType<length(TheUnits) then
139
result:=TheUnits[AType].Description;
142
Function RegisterConversionFamily(Const S:String):TConvFamily;
147
l:=Length(TheFamilies);
150
SetLength(TheFamilies,1);
157
while (i<l) and (s<>TheFamilies[i]) do inc(i);
160
SetLength(TheFamilies,l+1);
167
Function CheckFamily(i:TConvFamily):Boolean;
170
Result:=i<Length(TheFamilies);
175
Function RegisterConversionType(Fam:TConvFamily;Const S:String;Value:TConvUtilFloat):TConvType;
180
If NOT CheckFamily(Fam) Then exit(-1); // family not registered.
181
if (value+1.0)<macheps then // not properly defined yet.
183
l1:=length(theunits);
184
Setlength(theunits,l1+1);
185
theunits[l1].description:=s;
186
theunits[l1].value:=value;
187
theunits[l1].fam:=fam;
191
function SearchConvert(TheType:TConvType; var r:ResourceData):Boolean;
196
l1:=length(TheUnits);
199
r:=theunits[thetype];
203
function Convert ( const Measurement : Double; const FromType, ToType : TConvType ) :TConvUtilFloat;
206
fromrec,torec : resourcedata;
209
if not SearchConvert(fromtype,fromrec) then
210
exit(-1.0); // raise exception?
211
if not SearchConvert(totype,torec) then
212
exit(-1.0); // raise except?
213
if fromrec.fam<>torec.fam then
215
result:=Measurement*fromrec.value/torec.value;
218
function Convert ( const Measurement : Double; const FromType1, FromType2, ToType1, ToType2 : TConvType ) :TConvUtilFloat;
220
fromrec1,fromrec2,torec1 ,
221
torec2 : resourcedata;
224
if not SearchConvert(fromtype1,fromrec1) then
225
exit(-1.0); // raise exception?
226
if not SearchConvert(totype1,torec1) then
227
exit(-1.0); // raise except?
228
if not SearchConvert(fromtype2,fromrec2) then
229
exit(-1.0); // raise exception?
230
if not SearchConvert(totype2,torec2) then
231
exit(-1.0); // raise except?
232
if (fromrec1.fam<>torec1.fam) or (fromrec1.fam<>torec1.fam) then
234
result:=Measurement*(fromrec1.value/fromrec2.value)/(torec1.value/torec2.value);
237
Constructor TConvTypeInfo.Create(Const AConvFamily : TConvFamily;const ADescription:String);
240
FDescription:=ADescription;
241
FConvFamily :=AConvFamily;
245
constructor TConvTypeFactor.Create(const AConvFamily: TConvFamily; const ADescription: string;const AFactor: Double);
247
inherited create(AConvFamily,ADescription);
251
function TConvTypeFactor.ToCommon(const AValue: Double): Double;
253
result:=AValue * FFactor;
256
function TConvTypeFactor.FromCommon(const AValue: Double): Double;
258
result:=AValue / FFactor;
261
constructor TConvTypeProcs.Create(const AConvFamily: TConvFamily; const ADescription: string; const AToProc, AFromProc: TConversionProc);
263
inherited create(AConvFamily,ADescription);
265
ffromproc:=AFromProc;
268
function TConvTypeProcs.ToCommon(const AValue: Double): Double;
270
result:=FTOProc(Avalue);
273
function TConvTypeProcs.FromCommon(const AValue: Double): Double;
275
result:=FFromProc(Avalue);
279
setlength(theunits,0);
280
setlength(thefamilies,0);