⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmerl_xsd_type.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 3 页
字号:
       T==nonPositiveInteger;T==long;T==unsignedLong;T==int;T==unsignedInt;       T==short;T==unsignedShort;T==byte;T==unsignedByte;T==decimal ->    fun(Val) ->		    Len =		case string:tokens(Val,".") of		    [_I,Frc] when T==decimal ->			Pred = fun($0)-> true;				  (_) -> false			       end,			length(lists:dropwhile(Pred,lists:reverse(Frc)));		    _ ->			0		end,	    if 		Len =< V ->		    {ok,Val};		true ->		    {error,{fractionDigits,Len,to_many_digits_in,Val}}	    end    end;fractionDigits_fun(T,_V) ->    fun(_) -> {error,{fractionDigits,not_applicable,T}} end.    %% The relation between F1 and F2 may be eq,lt or gt.%% lt: F1 < F2%% gt: F1 > F2compare_floats(F1,F2) when F1=="NaN";F2=="NaN" ->    {error,{not_comparable}};compare_floats(F1,F1) ->    eq;compare_floats(F1,F2) when F1=="INF";F2=="-INF" ->    gt;compare_floats(F1,F2) when F1=="-INF";F2=="INF" ->    lt;compare_floats(Str1,Str2) ->    F1={S1,_B1,_D1,_E1} = str_to_float(Str1),    F2={S2,_B2,_D2,_E2} = str_to_float(Str2),%    io:format("F1: ~p~nF2: ~p~n",[F1,F2]),    if	S1=='-',S2=='+' -> lt;	S1=='+',S2=='-' -> gt;%	B1<0 -> compare_floats2(F2,F1);	true -> compare_floats2(F1,F2)    end.compare_floats2({S1,B1,D1,E1},{_S2,B2,D2,E2}) when B1==0;B2==0 ->    I1 = pow(B1,D1,E1),    I2 = pow(B2,D2,E2),    if I1 > I2 ->	    sign(S1,gt);       I1 < I2 ->	    sign(S1,lt);       true ->	    eq    end;compare_floats2({S1,B1,D1,E1},{_S2,B2,D2,E2}) ->    %% S1 and S2 have same sign.    I1 = pow(B1,E1),% B1 * round(math:pow(10,E1)),    I2 = pow(B2,E2),%B2 * round(math:pow(10,E2)),    if	I1 > I2 -> sign(S1,gt);	I1 < I2 -> sign(S1,lt);	true ->	    %% fractions are compared in lexicographic order	    if 		D1 == D2 -> eq;		D1 < D2 -> sign(S1,lt);		D1 > D2 -> sign(S1,gt)	    end    end.    str_to_float(String) ->    {Sign,Str} =	case String of	    "-"++Str1 -> {'-',Str1};	    _ -> {'+',String}	end,    case string:tokens(Str,".") of	[B,DE] ->	    case string:tokens(DE,"Ee") of		[D,E] ->		    %% round(math:pow(10,list_to_integer(E)))		    {Sign,list_to_integer(B),		     remove_trailing_zeros(D),		     list_to_integer(E)};		[D] ->		    {Sign,list_to_integer(B),		     remove_trailing_zeros(D),0}	    end;	[B] -> %% could also be 1E4, but no fraction	    case string:tokens(Str,"Ee") of		[I,E] ->		    {Sign,list_to_integer(I),"0",list_to_integer(E)};		_ ->		    {Sign,list_to_integer(B),"0",0}	    end    end.pow(Mantissa,Exponent) ->    case (Mantissa * math:pow(10,Exponent)) of	I when I<1 ->	    I;	I -> round(I)    end.pow(Mantissa,Fraction,Exponent) ->    (Mantissa * math:pow(10,Exponent)) + 	(list_to_integer(Fraction) * math:pow(10,Exponent-length(Fraction))).sign('-',gt) ->    lt;sign('-',lt) ->    gt;sign(_,Rel) ->    Rel.remove_trailing_zeros(Str) ->    Pred = fun($0) ->true;(_) ->false end,    case lists:reverse(lists:dropwhile(Pred,lists:reverse(Str))) of	[] ->	    "0";	Fr -> Fr    end.%%   when T==duration;T==dateTime;T==date;T==time;T==gYear;T==gYearMonth;%%        T==gMonth;T==gMonthDay;T==gDay ->%% compare_duration(V1,V2) compares V1 to V2%% returns gt | lt | eq | indefinite %% ex: V1 > V2 -> gt%%%% V1, V2 on format PnYnMnDTnHnMnS%% P is always present%% T is absent iff all time items are absent%% compare_duration(V1,V2) ->%%     {Y1,M1,D1,H1,M1,S1} = duration_atoms(V1),%%     {Y2,M2,D2,H2,M2,S2} = duration_atoms(V2),%%     YearDiff = Y1 - Y2,%%     MonthsDiff = M1 - M2,%%     DaysDiff = D1 - D2,compare_durations(V1,V2) ->    %% Four reference dateTimes are used, see XMLSchema part 2,    %% 3.2.6.2.    %% "The order-relation of two duration values x and y is x < y iff    %% s+x < s+y for each qualified dateTime s in the list below."    Ref1_dateTime = {1696,9,1,0,0,0,{pos,0,0}},%1696-09-01T00:00:00Z    Ref2_dateTime = {1697,2,1,0,0,0,{pos,0,0}},%1697-02-01T00:00:00Z    Ref3_dateTime = {1903,3,1,0,0,0,{pos,0,0}},%1903-03-01T00:00:00Z    Ref4_dateTime = {1903,7,1,0,0,0,{pos,0,0}},%1903-07-01T00:00:00Z    CmpRes1=compare_dateTime(normalize_dateTime(add_duration2dateTime(Ref1_dateTime,V1)),			     normalize_dateTime(add_duration2dateTime(Ref1_dateTime,V2))),    CmpRes2=compare_dateTime(normalize_dateTime(add_duration2dateTime(Ref2_dateTime,V1)),			     normalize_dateTime(add_duration2dateTime(Ref2_dateTime,V2))),    CmpRes3=compare_dateTime(normalize_dateTime(add_duration2dateTime(Ref3_dateTime,V1)),			     normalize_dateTime(add_duration2dateTime(Ref3_dateTime,V2))),    CmpRes4=compare_dateTime(normalize_dateTime(add_duration2dateTime(Ref4_dateTime,V1)),			     normalize_dateTime(add_duration2dateTime(Ref4_dateTime,V2))),    if	CmpRes1==CmpRes2,	CmpRes1==CmpRes3,	CmpRes1==CmpRes4 ->	    CmpRes1;	true ->  indefinite    end.compare_dateTime(DT1={_,_,_,_,_,_,Z},DT2={_,_,_,_,_,_,Z}) ->    case DT1<DT2 of	true -> lt;	_ ->	    case DT1>DT2 of		true ->		    gt;		_ -> eq	    end    end;%% If P contains a time zone and Q does not, compare as follows:%%    1. P < Q if P < (Q with time zone +14:00)%%    2. P > Q if P > (Q with time zone -14:00)%%    3. P <> Q otherwise, that is, if (Q with time zone +14:00) < P <%%    (Q with time zone -14:00)compare_dateTime(P={_,_,_,_,_,_,{_,_,_}},_Q={Y,M,D,H,Min,S,none}) ->    case compare_dateTime(P,normalize_dateTime({Y,M,D,H,Min,S,{pos,14,0}})) of	lt ->	    lt;	_ ->	    case compare_dateTime(P,normalize_dateTime({Y,M,D,H,Min,S,{neg,14,0}})) of		gt ->		    gt;		_ ->		    indefinite	    end    end;%% If P does not contain a time zone and Q does, compare as follows:%%    1. P < Q if (P with time zone -14:00) < Q.%%    2. P > Q if (P with time zone +14:00) > Q.%%    3. P <> Q otherwise, that is, if (P with time zone +14:00) < Q <%%    (P with time zone -14:00)compare_dateTime(_P={Y,M,D,H,Min,S,none},Q={_,_,_,_,_,_,{_,_,_}}) ->    case compare_dateTime(normalize_dateTime({Y,M,D,H,Min,S,{neg,14,0}}),Q) of	lt ->	    lt;	_ ->	    case compare_dateTime(normalize_dateTime({Y,M,D,H,Min,S,{pos,14,0}}),Q) of		gt ->		    gt;		_ ->		    indefinite	    end    end;compare_dateTime(P,Q) when is_list(P) ->    compare_dateTime(normalize_dateTime(dateTime_atoms(P)),Q);compare_dateTime(P,Q) when is_list(Q) ->    compare_dateTime(P,normalize_dateTime(dateTime_atoms(Q)));compare_dateTime(_P,_Q) ->    indefinite.    fQuotient(A,B) when is_float(A) ->    fQuotient(floor(A),B);fQuotient(A,B) when is_float(B) ->    fQuotient(A,floor(B));fQuotient(A,B) when A >= 0, B >= 0 ->    A div B;fQuotient(A,B) when A < 0, B < 0 ->    A div B;fQuotient(A,B) ->    case A rem B of	0 ->	    A div B;	_ ->	    (A div B) -1    end.fQuotient(A, Low, High) ->    fQuotient(A - Low, High - Low).floor(A) ->    case round(A) of	I when I > A ->	    I - 1;	I -> I    end.modulo(A,B) ->    A - (fQuotient(A,B) * B).modulo(A, Low, High) ->    modulo(A - Low, High - Low) + Low.    maximumDayInMonthFor(YearValue, MonthValue) ->    M = modulo(MonthValue, 1, 13),    Y = YearValue + fQuotient(MonthValue, 1, 13),    monthValue(M,Y).monthValue(M,_Y) when M==1;M==3;M==5;M==7;M==8;M==10;M==12 ->    31;monthValue(M,_Y) when M==4;M==6;M==9;M==11 ->    30;monthValue(_M,Y) ->    case modulo(Y,400) of	0 ->	    29;	_ ->	    case {modulo(Y,100) /= 0,modulo(Y,4)} of		{true,0} ->		    29;		_ ->		    28	    end    end.		%% S dateTime, D duration%% result is E dateTime, end of time period with start S and duration%% D. E = S + D.add_duration2dateTime(S,D) when is_list(S),is_list(D) ->    Satoms = dateTime_atoms(S),    case duration_atoms(D) of	Datoms = {_,_,_,_,_,_} ->	    add_duration2dateTime2(Satoms,Datoms);	Err ->	    {error,Err}    end;add_duration2dateTime(S={_,_,_,_,_,_,_},D) ->    case duration_atoms(D) of	Datoms = {_,_,_,_,_,_} ->	    add_duration2dateTime2(S,Datoms);	Err ->	    {error,Err}    end.add_duration2dateTime2({Syear,Smonth,Sday,Shour,Sminute,Ssec,Szone},		       {Dyears,Dmonths,Ddays,Dhours,Dminutes,Dsecs}) ->    %% months    Temp1 = Smonth + Dmonths,    Emonth = modulo(Temp1,1,13),    Carry1 = fQuotient(Temp1,1,13),        %% years    Eyear = Syear + Dyears + Carry1,        %% seconds    Temp2 = Ssec + Dsecs,    Esecs = modulo(Temp2,60),    Carry2 = fQuotient(Temp2,60),        %% minutes    Temp3 = Sminute + Dminutes + Carry2,    Eminute = modulo(Temp3,60),    Carry3 = fQuotient(Temp3,60),        %% hours    Temp4 = Shour + Dhours + Carry3,    Ehour = modulo(Temp4,24),    Carry4 = fQuotient(Temp4,24),        %% days    TempDays =	case maximumDayInMonthFor(Eyear,Emonth) of	    MaxDay when Sday > MaxDay ->		MaxDay;	    _ ->		case Sday < 1 of		    true ->			1;		    _ ->			Sday		end	end,    {Eyear2,Emonth2,Eday} =	carry_loop(TempDays+Ddays+Carry4,Emonth,Eyear),    {Eyear2,Emonth2,Eday,Ehour,Eminute,Esecs,Szone}.carry_loop(Eday,Emonth,Eyear) when Eday < 1 ->    carry_loop(Eday + maximumDayInMonthFor(Eyear,Emonth - 1),	       modulo(Emonth - 1,1,13),	       Eyear + fQuotient(Emonth - 1,1,13));carry_loop(Eday,Emonth,Eyear) ->    case maximumDayInMonthFor(Eyear,Emonth) of	MaxD when Eday > MaxD ->	    carry_loop(Eday - maximumDayInMonthFor(Eyear,Emonth),		       modulo(Emonth + 1,1,13),		       Eyear + fQuotient(Emonth+1,1,13));	_ ->	    {Eyear,Emonth,Eday}    end.%% Format: '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?dateTime_atoms("-" ++ DT) ->    dateTime_atoms(DT,neg);dateTime_atoms(DT) ->    dateTime_atoms(DT,pos).dateTime_atoms(S,Sign) ->    [Date,TimeZone] = string:tokens(S,"T"),    [YY,MM,DD] = string:tokens(Date,"-"),    {Zone,ZoneSign,[Hour,Min,Sec]} =	case lists:reverse(TimeZone) of	    "Z"++_ ->		{"Z",pos,string:tokens(TimeZone,"Z:")};	    _ ->		ZS = zone_sign(TimeZone),		case string:tokens(TimeZone,"-+") of		    [Time,Z] ->			{Z,ZS,string:tokens(Time,":")};		    [Time] ->			{none,ZS,string:tokens(Time,":")}		end	end,    {set_sign(Sign,YY),list_to_integer(MM),list_to_integer(DD),     list_to_integer(Hour),list_to_integer(Min),sign_sec(pos,Sec),     zone_atoms(ZoneSign,Zone)}.zone_sign(TimeZone) ->    case lists:member($-,TimeZone) of	true ->	    neg;	_ ->	    pos    end.zone_atoms(_Sign,"Z") ->    {pos,0,0};zone_atoms(Sign,Zone) when is_list(Zone) ->    case string:tokens(Zone,":") of	[H,M] ->	    {Sign,list_to_integer(H),list_to_integer(M)};	_ -> none    end;zone_atoms(_Sign,Zone) ->    Zone.    %% Format: '-'? PnYnMnDTnHnMnSduration_atoms("-P"++Dur) ->    duration_atoms2(Dur,neg);duration_atoms("P"++Dur) ->    duration_atoms2(Dur,pos);duration_atoms(Dur) ->    {illegal_duration,Dur}.duration_atoms2(Dur,Sign) ->    case lists:member($T,Dur) of	true -> %% time atoms exists	    case string:tokens(Dur,"T") of		[Date,Time] ->		    case duration_atoms_date(Date) of			{Y,M,D} ->			    case duration_atoms_time(Time) of				{Hour,Min,Sec} ->				    {set_sign(Sign,Y),set_sign(Sign,M),				     set_sign(Sign,D),set_sign(Sign,Hour),				     set_sign(Sign,Min),sign_sec(Sign,Sec)};				Err ->				    Err			    end;			Err ->			    Err		    end;		[Time] ->		    case duration_atoms_time(Time) of			{Hour,Min,Sec} ->			    {0,0,0,set_sign(Sign,Hour),set_sign(Sign,Min),			     sign_sec(Sign,Sec)};			Err ->			    Err		    end;		Err ->		    {illegal_duration,Err}	    end;	_ -> %% only date coomponents	    {Y,M,D} = duration_atoms_date(Dur),	    {set_sign(Sign,Y),set_sign(Sign,M),set_sign(Sign,D),0,0,0}    end.duration_atoms_date(Date) ->    {Y,Date2} = get_digit(Date,$Y),    {M,Date3} = get_digit(Date2,$M),    {D,Rest}  = get_digit(Date3,$D),    case Rest of	"" -> {Y,M,D};	Err -> {illegal_duration,Err}    end.duration_atoms_time(Time) ->    {H,Time2} = get_digit(Time,$H),    {M,Time3} = get_digit(Time2,$M),    {S,Rest} = get_sec(Time3),    case Rest of	"" ->	    {H,M,S};	Err ->	    {illegal_duration,Err}    end.get_digit(Str,Delim) ->    get_digit(Str,Delim,[],Str).get_digit([Delim|T],Delim,Acc,_Str) ->    {lists:reverse(Acc),T};get_digit([H|T],Delim,Acc,Str) when H>=$0,H=<$9 ->    get_digit(T,Delim,[H|Acc],Str);get_digit([],_,[],_Str) ->    {"0",[]};get_digit([],_,_,Str) ->    {"0",Str};get_digit(_,_,_,Str) ->    %% this matches both the case when reaching another delimeter and    %% when the string already are emptied.    {"0",Str}.get_sec([]) ->    {"0",[]};get_sec(Str) ->    get_sec(Str,[],Str).get_sec([H|T],Acc,Str) when H>=$0,H=<$9 ->    get_sec(T,[H|Acc],Str);get_sec([$.|T],Acc,Str) ->    get_sec(T,[$.|Acc],Str);get_sec([$S|T],Acc,_) ->    {lists:reverse(Acc),T};get_sec(_,_,Str) ->    {"0",Str}.    	    set_sign(pos,Istr) ->    list_to_integer(Istr);set_sign(_,Istr) ->    list_to_integer("-"++Istr).sign_sec(pos,Sec) ->    case lists:member($.,Sec) of	true ->	    list_to_float(Sec);	_ ->	    list_to_integer(Sec)    end;sign_sec(_,Sec) ->    sign_sec(pos,"-"++Sec).invert_sign(pos) ->    neg;invert_sign(neg) ->    pos;invert_sign(S) ->    S.normalize_dateTime({Y,M,D,Hour,Min,Sec,{Sign,ZH,ZM}}) ->    %% minutes    TmpMin = Min + set_sign(invert_sign(Sign),integer_to_list(ZM)),    NMin = modulo(TmpMin,60),    Carry1 = fQuotient(TmpMin,60),    %% hours    TmpHour = Hour + set_sign(invert_sign(Sign),integer_to_list(ZH)) + Carry1,    NHour = modulo(TmpHour,24),    Carry2 = fQuotient(TmpHour,24),        {NY,NM,ND} =	carry_loop(D+Carry2,M,Y),    {NY,NM,ND,NHour,NMin,Sec,{pos,0,0}};normalize_dateTime(DT) ->    DT.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -