we're not a disk drive manufacturer, don't use halfass base-10 megs/gigs
[freeside.git] / FS / FS / UI / bytecount.pm
1 package FS::UI::bytecount;
2
3 use strict;
4 use vars qw($DEBUG $me);
5 use FS::Conf;
6 use Number::Format 1.50;
7
8 $DEBUG = 0;
9 $me = '[FS::UID::bytecount]';
10
11 =head1 NAME
12
13 FS::UI::bytecount - Subroutines for parsing and displaying byte counters
14
15 =head1 SYNOPSIS
16
17   use FS::UI::bytecount;
18
19 =head1 SUBROUTINES
20
21 =over 4
22
23 =item bytecount_unexact COUNT
24
25 Returns a two decimal place value for COUNT followed by bytes, Kbytes, Mbytes,
26 or GBytes as appropriate.
27
28 =cut
29
30 sub bytecount_unexact {
31   my $bc = shift;
32   return("$bc bytes")
33     if ($bc < 1000);
34   return(sprintf("%.2f Kbytes", $bc/1024))
35     if ($bc < 1048576);
36   return(sprintf("%.2f Mbytes", $bc/1048576))
37     if ($bc < 1073741824);
38   return(sprintf("%.2f Gbytes", $bc/1073741824));
39 }
40
41 =item parse_bytecount AMOUNT
42
43 Accepts a number (digits and a decimal point) possibly followed by k, m, g, or
44 t (and an optional 'b') in either case.  Returns a pure number representing
45 the input or the input itself if unparsable.  Discards commas as noise.
46
47 =cut
48
49 sub parse_bytecount {
50   my $bc = shift;
51   return $bc if (($bc =~ tr/.//) > 1);
52   $bc =~ /^\s*([,\d.]*)\s*([kKmMgGtT]?)[bB]?\s*$/ or return $bc;
53   my $base = $1;
54   $base =~ tr/,//d;
55   return $bc unless length $base;
56   my $exponent = index ' kmgt', lc($2);
57   return $bc if ($exponent < 0 && $2);
58   $exponent = 0 if ($exponent < 0);
59   return int($base * 1024 ** $exponent);  #bytecounts are integer values
60 }
61
62 =item display_bytecount AMOUNT
63
64 Converts a pure number to a value followed possibly followed by k, m, g, or
65 t via Number::Format
66
67 =cut
68
69 sub display_bytecount {
70   my $bc = shift;
71   return $bc unless ($bc =~ /^(\d+)$/);
72   my $conf = new FS::Conf;
73   my $f = new Number::Format;
74   my $precision = ( $conf->exists('datavolume-significantdigits') &&
75                     $conf->config('datavolume-significantdigits') =~ /^\s*\d+\s*$/ )
76                 ? $conf->config('datavolume-significantdigits')
77                 : 3;
78   my $unit = $conf->exists('datavolume-forcemegabytes') ? 'M' : 'A';
79
80   return $f->format_bytes($bc, precision => $precision, unit => $unit);
81 }
82
83 =back
84
85 =head1 BUGS
86
87 Fly
88
89 =head1 SEE ALSO
90
91 L<Number::Format>
92
93 =cut
94
95 1;
96