Ver código fonte

ft: eFmtFormat.erl 修改为二进制

master
SisMaker 4 anos atrás
pai
commit
473bf136d8
1 arquivos alterados com 129 adições e 146 exclusões
  1. +129
    -146
      src/eFmtFormat.erl

+ 129
- 146
src/eFmtFormat.erl Ver arquivo

@ -222,33 +222,29 @@ ctlSmall($s, Args, Width, Adjust, Precision, PadChar, Encoding) when is_atom(Arg
end,
string(AtomBinStr, Width, Adjust, Precision, PadChar, Encoding);
ctlSmall($e, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_float(Args) ->
fwriteE(Args, Width, Adjust, Precision, PadChar);
floatE(Args, Width, Adjust, Precision, PadChar);
ctlSmall($f, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_float(Args) ->
fwrite_f(Args, Width, Adjust, Precision, PadChar);
floatF(Args, Width, Adjust, Precision, PadChar);
ctlSmall($g, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_float(Args) ->
fwrite_g(Args, Width, Adjust, Precision, PadChar);
floatG(Args, Width, Adjust, Precision, PadChar);
ctlSmall($b, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
unprefixed_integer(Args, Width, Adjust, ?base(Precision), PadChar, true);
unPrefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, true);
ctlSmall($B, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
unprefixed_integer(Args, Width, Adjust, ?base(Precision), PadChar, false);
unPrefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, false);
ctlSmall($x, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args), is_atom(Prefix) ->
prefixed_integer(Args, Width, Adjust, ?base(Precision), PadChar, atom_to_list(Prefix), true);
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, atom_to_binary(Prefix, utf8), true);
ctlSmall($x, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
true = eFmt:deep_char_list(Prefix), %Check if Prefix a character list
prefixed_integer(Args, Width, Adjust, ?base(Precision), PadChar, Prefix, true);
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, Prefix, true);
ctlSmall($X, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args), is_atom(Prefix) ->
prefixed_integer(Args, Width, Adjust, ?base(Precision), PadChar, atom_to_list(Prefix), false);
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, atom_to_binary(Prefix, utf8), false);
ctlSmall($X, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
true = eFmt:deep_char_list(Prefix), %Check if Prefix a character list
prefixed_integer(Args, Width, Adjust, ?base(Precision), PadChar, Prefix, false);
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, Prefix, false);
ctlSmall($+, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
Base = ?base(Precision),
Prefix = [integer_to_list(Base), $#],
prefixed_integer(Args, Width, Adjust, Base, PadChar, Prefix, true);
prefixedInt(Args, Width, Adjust, Base, PadChar, integer_to_binary(Base), $#, true);
ctlSmall($#, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
Base = ?base(Precision),
Prefix = [integer_to_list(Base), $#],
prefixed_integer(Args, Width, Adjust, Base, PadChar, Prefix, false);
prefixedInt(Args, Width, Adjust, Base, PadChar, integer_to_binary(Base), $#, false);
ctlSmall($c,Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
char(Args, Width, Adjust, Precision, PadChar);
ctlSmall($c, Args, Width, Adjust, Precision, PadChar, _Enc) when is_integer(Args) ->
@ -256,7 +252,7 @@ ctlSmall($c, Args, Width, Adjust, Precision, PadChar, _Enc) when is_integer(Args
ctlSmall($~, _Args, Width, Adjust, Precision, PadChar, _Encoding) -> char($~, Width, Adjust, Precision, PadChar);
ctlSmall($n, _Args, Width, Adjust, Precision, PadChar, _Encoding) -> newline(Width, Adjust, Precision, PadChar);
ctlSmall($i, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> [];
ctlSmall(_C, _Args, Width, _Adjust, _Precision, _PadChar, _Encoding) -> not_small.
ctlSmall(_C, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> not_small.
%% count_small[ControlC]->pPwWsS
count_small([#{control_char := $p} | Cs], P, S, W, Other) ->
@ -360,16 +356,28 @@ uniconv(C) ->
%% Adjust the characters within the field if length less than Max padding
%% with PadChar.
term(T, none, _Adj, none, _Pad) -> T;
term(T, none, Adj, P, Pad) -> term(T, P, Adj, P, Pad);
term(T, F, Adjust, P0, Pad) ->
L = eFmt:charsLen(T),
P = erlang:min(L, case P0 of none -> F; _ -> min(P0, F) end),
term(BinStrOrIoList, Width, Adjust, Precision, PadChar) ->
if
L > P ->
adjust(Adjust, makePadChars($*, P, <<>>), makePadChars(Pad, F - P, <<>>));
F >= P ->
adjust(Adjust, T, makePadChars(Pad, F - L, <<>>))
Width == none andalso Precision == none ->
BinStrOrIoList;
Width == none ->
StrLen = eFmt:charsLen(BinStrOrIoList),
NewPrecision = erlang:min(StrLen, Precision),
if
StrLen > NewPrecision ->
adjust(Adjust, makePadChars($*, NewPrecision, <<>>), <<>>);
true ->
adjust(Adjust, BinStrOrIoList, makePadChars(PadChar, Precision - StrLen, <<>>))
end;
true ->
StrLen = eFmt:charsLen(BinStrOrIoList),
NewPrecision = erlang:min(StrLen, case Precision of none -> Width; _ -> min(Precision, Width) end),
if
StrLen > NewPrecision ->
adjust(Adjust, makePadChars($*, NewPrecision, <<>>), makePadChars(PadChar, Width - NewPrecision, <<>>));
true ->
adjust(Adjust, BinStrOrIoList, makePadChars(PadChar, Width - StrLen, <<>>))
end
end.
%% print(Term, Depth, Field, Adjust, Precision, PadChar, Encoding,
@ -390,9 +398,7 @@ print(T, D, F, right, P, _Pad, Enc, Str, ChLim, _I) ->
{strings, Str}],
eFmt_pretty:print(T, Options).
%% fwrite_e(Float, Field, Adjust, Precision, PadChar)
fwriteE(Float, Width, Adjust, Precision, PadChar) ->
floatE(Float, Width, Adjust, Precision, PadChar) ->
case Precision of
none ->
NewPrecision = 6;
@ -401,85 +407,38 @@ fwriteE(Float, Width, Adjust, Precision, PadChar) ->
end,
case Width of
none ->
floatE(Float, floatData(Float), NewPrecision);
float_to_binary(Float, [{scientific, NewPrecision}]);
_ ->
term(floatE(Float, floatData(Float), NewPrecision), Width, Adjust, Adjust, PadChar)
term(float_to_binary(Float, [{scientific, NewPrecision}]), Width, Adjust, Width, PadChar)
end.
floatE(Fl, Fd, P) when Fl < 0.0 -> %Negative numbers
[$- | floatE(-Fl, Fd, P)];
floatE(_Fl, {Ds, E}, P) ->
case float_man(Ds, 1, P - 1) of
{[$0 | Fs], true} -> [[$1 | Fs] | float_exp(E)];
{Fs, false} -> [Fs | float_exp(E - 1)]
end.
%% float_man([Digit], Icount, Dcount) -> {[Char],CarryFlag}.
%% Generate the characters in the mantissa from the digits with Icount
%% characters before the '.' and Dcount decimals. Handle carry and let
%% caller decide what to do at top.
float_man(Ds, 0, Dc) ->
{Cs, C} = float_man(Ds, Dc),
{[$. | Cs], C};
float_man([D | Ds], I, Dc) ->
case float_man(Ds, I - 1, Dc) of
{Cs, true} when D =:= $9 -> {[$0 | Cs], true};
{Cs, true} -> {[D + 1 | Cs], false};
{Cs, false} -> {[D | Cs], false}
end;
float_man([], I, Dc) -> %Pad with 0's
{lists:duplicate(I, $0) ++ [$. | lists:duplicate(Dc, $0)], false}.
float_man([D | _], 0) when D >= $5 -> {[], true};
float_man([_ | _], 0) -> {[], false};
float_man([D | Ds], Dc) ->
case float_man(Ds, Dc - 1) of
{Cs, true} when D =:= $9 -> {[$0 | Cs], true};
{Cs, true} -> {[D + 1 | Cs], false};
{Cs, false} -> {[D | Cs], false}
end;
float_man([], Dc) -> {lists:duplicate(Dc, $0), false}. %Pad with 0's
%% float_exp(Exponent) -> [Char].
%% Generate the exponent of a floating point number. Always include sign.
float_exp(E) when E >= 0 ->
[$e, $+ | integer_to_list(E)];
float_exp(E) ->
[$e | integer_to_list(E)].
%% fwrite_f(FloatData, Field, Adjust, Precision, PadChar)
fwrite_f(Fl, none, Adj, none, Pad) -> %Default values
fwrite_f(Fl, none, Adj, 6, Pad);
fwrite_f(Fl, none, _Adj, P, _Pad) when P >= 1 ->
float_f(Fl, floatData(Fl), P);
fwrite_f(Fl, F, Adj, none, Pad) ->
fwrite_f(Fl, F, Adj, 6, Pad);
fwrite_f(Fl, F, Adj, P, Pad) when P >= 1 ->
term(float_f(Fl, floatData(Fl), P), F, Adj, F, Pad).
float_f(Fl, Fd, P) when Fl < 0.0 ->
[$- | float_f(-Fl, Fd, P)];
float_f(Fl, {Ds, E}, P) when E =< 0 ->
float_f(Fl, {lists:duplicate(-E + 1, $0) ++ Ds, 1}, P); %Prepend enough 0's
float_f(_Fl, {Ds, E}, P) ->
case float_man(Ds, E, P) of
{Fs, true} -> "1" ++ Fs; %Handle carry
{Fs, false} -> Fs
floatF(Float, Width, Adjust, Precision, PadChar) ->
case Precision of
none ->
NewPrecision = 6;
_ ->
NewPrecision = Precision
end,
case Width of
none ->
float_to_binary(Float, [{decimals, NewPrecision}]);
_ ->
term(float_to_binary(Float, [{decimals, NewPrecision}]), Width, Adjust, Width, PadChar)
end.
%% float_data([FloatChar]) -> {[Digit],Exponent}
floatData(Float) ->
FloatBin = float_to_binary(Float),
case binary:split(FloatBin, <<"e">>) of
[DigitBin, ExponentBin] ->
{DigitBin, binary_to_integer(ExponentBin) + 1};
%% fwrite_g(Float, Field, Adjust, Precision, PadChar)
%% Use the f form if Float is >= 0.1 and < 1.0e4,
%% and the prints correctly in the f form, else the e form.
%% Precision always means the # of significant digits.
floatG(Float, Width, Adjust, Precision, PadChar) ->
case Float > -10000.0 andalso Float < 10000.0 of
true ->
floatF(Float, Width, Adjust, Precision, PadChar);
_ ->
{FloatBin, 0}
floatE(Float, Width, Adjust, Precision, PadChar)
end.
%% Writes the shortest, correctly rounded string that converts
%% to Float when read back with list_to_float/1.
%%
@ -646,31 +605,7 @@ log2floor(0, N) ->
log2floor(Int, N) ->
log2floor(Int bsr 1, 1 + N).
%% fwrite_g(Float, Field, Adjust, Precision, PadChar)
%% Use the f form if Float is >= 0.1 and < 1.0e4,
%% and the prints correctly in the f form, else the e form.
%% Precision always means the # of significant digits.
fwrite_g(Fl, F, Adj, none, Pad) ->
fwrite_g(Fl, F, Adj, 6, Pad);
fwrite_g(Fl, F, Adj, P, Pad) when P >= 1 ->
A = abs(Fl),
E = if A < 1.0e-1 -> -2;
A < 1.0e0 -> -1;
A < 1.0e1 -> 0;
A < 1.0e2 -> 1;
A < 1.0e3 -> 2;
A < 1.0e4 -> 3;
true -> fwrite_f
end,
if P =< 1, E =:= -1;
P - 1 > E, E >= -1 ->
fwrite_f(Fl, F, Adj, P - 1 - E, Pad);
P =< 1 ->
fwriteE(Fl, F, Adj, 2, Pad);
true ->
fwriteE(Fl, F, Adj, P, Pad)
end.
iolist_to_chars(Cs, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F ->
@ -799,35 +734,51 @@ makePadChars(Char, Cnt, BinStr) ->
BinStr
end.
adjust(left, Data, Pad) -> [Data | Pad];
adjust(right, Data, Pad) -> [Pad | Data].
adjust(left, Data, Pad) -> [Data, Pad];
adjust(right, Data, Pad) -> [Pad, Data].
%% unprefixed_integer(Int, Field, Adjust, Base, PadChar, Lowercase)
%% -> [Char].
unprefixed_integer(Int, F, Adj, Base, Pad, Lowercase)
when Base >= 2, Base =< 1 + $Z - $A + 10 ->
if Int < 0 ->
S = cond_lowercase(erlang:integer_to_list(-Int, Base), Lowercase),
term([$- | S], F, Adj, none, Pad);
unPrefixedInt(Int, Width, Adjust, Base, PadChar, Lowercase) ->
case Lowercase of
true ->
S = cond_lowercase(erlang:integer_to_list(Int, Base), Lowercase),
term(S, F, Adj, none, Pad)
term(toLowerStr(integer_to_binary(Int, Base)), Width, Adjust, none, PadChar);
_ ->
term(integer_to_binary(Int, Base), Width, Adjust, none, PadChar)
end.
%% prefixed_integer(Int, Field, Adjust, Base, PadChar, Prefix, Lowercase)
%% -> [Char].
prefixedInt(Int, Width, Adjust, Base, PadChar, Prefix, Lowercase) ->
case Int < 0 of
true ->
case Lowercase of
true ->
term(<<"-", (toBinary(Prefix))/binary, (toLowerStr(integer_to_binary(-Int, Base)))/binary>>, Width, Adjust, none, PadChar);
_ ->
term(<<"-", (toBinary(Prefix))/binary, (integer_to_binary(-Int, Base))/binary>>, Width, Adjust, none, PadChar)
end;
_ ->
case Lowercase of
true ->
term(<<(toBinary(Prefix))/binary, (toLowerStr(integer_to_binary(Int, Base)))/binary>>, Width, Adjust, none, PadChar);
_ ->
term(<<(toBinary(Prefix))/binary, (integer_to_binary(Int, Base))/binary>>, Width, Adjust, none, PadChar)
end
end.
prefixed_integer(Int, F, Adj, Base, Pad, Prefix, Lowercase)
when Base >= 2, Base =< 1 + $Z - $A + 10 ->
if Int < 0 ->
S = cond_lowercase(erlang:integer_to_list(-Int, Base), Lowercase),
term([$-, Prefix | S], F, Adj, none, Pad);
prefixedInt(Int, Width, Adjust, Base, PadChar, Prefix, Prefix2, Lowercase) ->
case Int < 0 of
true ->
S = cond_lowercase(erlang:integer_to_list(Int, Base), Lowercase),
term([Prefix | S], F, Adj, none, Pad)
case Lowercase of
true ->
term(<<"-", (toBinary(Prefix))/binary, Prefix2:8, (toLowerStr(integer_to_binary(-Int, Base)))/binary>>, Width, Adjust, none, PadChar);
_ ->
term(<<"-", (toBinary(Prefix))/binary, Prefix2:8, (integer_to_binary(-Int, Base))/binary>>, Width, Adjust, none, PadChar)
end;
_ ->
case Lowercase of
true ->
term(<<(toBinary(Prefix))/binary, Prefix2:8, (toLowerStr(integer_to_binary(Int, Base)))/binary>>, Width, Adjust, none, PadChar);
_ ->
term(<<(toBinary(Prefix))/binary, Prefix2:8, (integer_to_binary(Int, Base))/binary>>, Width, Adjust, none, PadChar)
end
end.
%% char(Char, Field, Adjust, Precision, PadChar) -> chars().
@ -921,3 +872,35 @@ print_encoding(latin1) -> "".
print_strings(false) -> "l";
print_strings(true) -> "".
toLowerStr(BinStr) ->
<< begin
case C >= $A andalso C =< $Z of
true ->
<<(C + 32)>>;
_ ->
<<C>>
end
end || <<C:8>> <= BinStr
>>.
toUpperStr(BinStr) ->
<< begin
case C >= $a andalso C =< $z of
true ->
<<(C - 32)>>;
_ ->
<<C>>
end
end || <<C:8>> <= BinStr
>>.
toBinary(Value) when is_integer(Value) -> integer_to_binary(Value);
toBinary(Value) when is_list(Value) -> list_to_binary(Value);
toBinary(Value) when is_float(Value) -> float_to_binary(Value, [{decimals, 6}, compact]);
toBinary(Value) when is_atom(Value) -> atom_to_binary(Value, utf8);
toBinary(Value) when is_binary(Value) -> Value;
toBinary([Tuple | PropList] = Value) when is_list(PropList) and is_tuple(Tuple) ->
lists:map(fun({K, V}) -> {toBinary(K), toBinary(V)} end, Value);
toBinary(Value) -> term_to_binary(Value).

Carregando…
Cancelar
Salvar