@@ -3,9 +3,11 @@ package ui
33import (
44 "bufio"
55 "encoding/hex"
6+ "errors"
67 "fmt"
78 "math/big"
89 "os"
10+ "regexp"
911 "strconv"
1012 "strings"
1113
@@ -78,26 +80,19 @@ func InputBytes(item *Item, bytecount int) error {
7880}
7981
8082func InputBigInt (item * Item ) error {
81- res := new (big. Int )
83+
8284 prompt := promptui.Prompt {
8385 Label : item .Label ,
8486 }
8587 a , err := prompt .Run ()
8688 if err != nil {
8789 return err
8890 }
89- base := 10
90- if strings .HasPrefix (a , "0x" ) {
91- base = 16
92- a = a [2 :]
93- }
94- res , ok := res .SetString (a , base )
95- if ! ok {
96- return fmt .Errorf ("error parsing big int: %s" , a )
91+ res , err := ParseBigInt (a )
92+ if err != nil {
93+ return fmt .Errorf ("error parsing big int: %w" , err )
9794 }
9895 item .Value = res
99- //item.DisplayValue = res.String()
100-
10196 return nil
10297}
10398
@@ -219,3 +214,67 @@ func InputBool(item *Item) error {
219214 //item.DisplayValue() = sel
220215 return nil
221216}
217+
218+ var bigIntParserDec = regexp .MustCompile (`(\d*)(\.\d+)?([KMGTPE]?)$` )
219+ var two = big .NewInt (2 )
220+ var kilo = big .NewInt (1000 )
221+ var mega = big .NewInt (1000000 )
222+ var giga = big .NewInt (1000000000 )
223+ var tera = big .NewInt (1000000000000 )
224+ var peta = big .NewInt (1000000000000000 )
225+ var exa = big .NewInt (1000000000000000000 )
226+ var ten = big .NewInt (10 )
227+ var sixteen = big .NewInt (16 )
228+
229+ // Decimal Parsing
230+ func ParseBigInt (input string ) (* big.Int , error ) {
231+ input = strings .TrimSpace (input )
232+ res := new (big.Int )
233+ if strings .HasPrefix (input , "0x" ) {
234+ input = input [2 :]
235+ _ , ok := res .SetString (input , 16 )
236+ if ! ok {
237+ return nil , errors .New ("invalid hex number" )
238+ }
239+ return res , nil
240+ }
241+ match := bigIntParserDec .FindStringSubmatch (input )
242+ if match == nil {
243+ return nil , errors .New ("invalid number" )
244+ }
245+ multiplier := big .NewInt (1 )
246+ divisor := big .NewInt (1 )
247+ alldigits := match [1 ]
248+ divpower := 0
249+ if len (match [2 ]) > 0 {
250+ alldigits += match [2 ][1 :]
251+ divpower = len (match [2 ]) - 1
252+ }
253+ _ , ok := res .SetString (alldigits , 10 )
254+ if ! ok {
255+ return nil , errors .New ("invalid decimal number" )
256+ }
257+ switch match [3 ] {
258+ case "K" :
259+ multiplier = kilo
260+ case "M" :
261+ multiplier = mega
262+ case "G" :
263+ multiplier = giga
264+ case "T" :
265+ multiplier = tera
266+ case "P" :
267+ multiplier = peta
268+ case "E" :
269+ multiplier = exa
270+ }
271+ if divpower > 0 {
272+ divisor .Exp (ten , big .NewInt (int64 (divpower )), nil )
273+ }
274+ if divisor .Cmp (multiplier ) > 0 {
275+ return nil , errors .New ("invalid number" )
276+ }
277+ res .Mul (res , multiplier )
278+ res .Div (res , divisor )
279+ return res , nil
280+ }
0 commit comments