bytesize 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +165 -0
- data/lib/bytesize.rb +1277 -0
- data/lib/bytesize/activerecord.rb +50 -0
- data/lib/bytesize/units.rb +227 -0
- data/lib/bytesize/version.rb +18 -0
- data/spec/bytesize_spec.rb +30 -0
- data/spec/iecbytesize_spec.rb +30 -0
- data/spec/shared_examples.rb +408 -0
- data/spec/test_enum.rb +86 -0
- data/spec/value_class_helper.rb +363 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3aa26ab3dee5c630d19eda1edc877cc12d251ed719347b1af722cbb8b66d387b
|
4
|
+
data.tar.gz: 2a5f2ff76d9e7c1bf2dbcca25cec46cf77b642f4e3c4ea4e7189bd520f7a8aa9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '0096603896d44f87d44c048c6b8da3b89469103f73e0336ce113f4f2025cf7664ec986706ce8129bb89b454d70c959bf6d2190be11a7ee6c8d4f60a092caf221'
|
7
|
+
data.tar.gz: 9b8a3fdf9331eff6158efa41b40bab085a3ebc0968309a1d8e25d2e867a0bd629d73f6c24fd87f7f4159fe367231044a0d9d77f8b166672c9b77cd175423619f
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright © 2018 Adam Hunt
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# ByteSize
|
2
|
+
|
3
|
+
ByteSize is a simple Ruby object that stores a size in bytes, while providing human-readable string output and ample convenience methods.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'bytesize'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install bytesize
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### New
|
24
|
+
|
25
|
+
An instance of ByteSize can be created from an [Integer](https://ruby-doc.org/core/Integer.html) representing a number of bytes:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'bytesize'
|
29
|
+
|
30
|
+
ByteSize.new(1210000000) #=> (1.21 GB)
|
31
|
+
```
|
32
|
+
|
33
|
+
Or a [String](https://ruby-doc.org/core/String.html) containing a human-readable representation:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
ByteSize.new("1.21 GB") #=> (1.21 GB)
|
37
|
+
```
|
38
|
+
|
39
|
+
Appropriate conversions are made between different unit symbols:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
ByteSize.new("1.1269 GiB") #=> (1.21 GB)
|
43
|
+
```
|
44
|
+
|
45
|
+
ByteSize has a number of convenience methods for all SI and IEC unit symbols:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
ByteSize.bytes(42) #=> (42 bytes)
|
49
|
+
|
50
|
+
ByteSize.kb(42) #=> (42 kB)
|
51
|
+
ByteSize.mb(42) #=> (42 MB)
|
52
|
+
ByteSize.gb(42) #=> (42 GB)
|
53
|
+
ByteSize.tb(42) #=> (42 TB)
|
54
|
+
ByteSize.pb(42) #=> (42 PB)
|
55
|
+
ByteSize.eb(42) #=> (42 EB)
|
56
|
+
ByteSize.zb(42) #=> (42 ZB)
|
57
|
+
ByteSize.yb(42) #=> (42 YB)
|
58
|
+
|
59
|
+
ByteSize.kib(42) #=> (43.01 kB)
|
60
|
+
ByteSize.mib(42) #=> (44.04 MB)
|
61
|
+
ByteSize.gib(42) #=> (45.1 GB)
|
62
|
+
ByteSize.tib(42) #=> (46.18 TB)
|
63
|
+
ByteSize.pib(42) #=> (47.29 PB)
|
64
|
+
ByteSize.eib(42) #=> (48.42 EB)
|
65
|
+
ByteSize.zib(42) #=> (49.58 ZB)
|
66
|
+
ByteSize.yib(42) #=> (50.77 YB)
|
67
|
+
```
|
68
|
+
|
69
|
+
### String Output
|
70
|
+
|
71
|
+
ByteSize formats all [String](https://ruby-doc.org/core/String.html) output using SI standard unit symbols:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
ByteSize.zb(42).to_s #=> "42 ZB"
|
75
|
+
```
|
76
|
+
|
77
|
+
If you wish to display sizes using IEC standard unit symbols instead, you can use the sister-class [IECByteSize](../classes/IECByteSize.html):
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
IECByteSize.zib(42).to_s #=> "42 ZiB"
|
81
|
+
IECByteSize.kib(64).to_s #=> "64 KiB"
|
82
|
+
```
|
83
|
+
|
84
|
+
An optional [Integer](https://ruby-doc.org/core/Integer.html) can be provided to define a fixed number of decimal places:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
ByteSize.tb(3).to_s(4) #=> "3.0000 TB"
|
88
|
+
ByteSize.mb(1.14159).to_s(4) #=> "1.1416 MB"
|
89
|
+
```
|
90
|
+
|
91
|
+
### Conversion
|
92
|
+
|
93
|
+
ByteSize includes conversion methods for all SI and IEC unit symbols:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
ByteSize.gb(1.21).to_bytes #=> 1210000000
|
97
|
+
|
98
|
+
ByteSize.gb(1.21).to_kb #=> 1210000.0
|
99
|
+
ByteSize.gb(1.21).to_mb #=> 1210.0
|
100
|
+
ByteSize.gb(1.21).to_gb #=> 1.21
|
101
|
+
ByteSize.gb(1.21).to_tb #=> 0.00121
|
102
|
+
ByteSize.gb(1.21).to_pb #=> 1.21e-06
|
103
|
+
ByteSize.gb(1.21).to_eb #=> 1.21e-09
|
104
|
+
ByteSize.gb(1.21).to_zb #=> 1.21e-12
|
105
|
+
ByteSize.gb(1.21).to_yb #=> 1.21e-15
|
106
|
+
|
107
|
+
ByteSize.gb(1.21).to_kib #=> 1181640.625
|
108
|
+
ByteSize.gb(1.21).to_mib #=> 1153.9459228515625
|
109
|
+
ByteSize.gb(1.21).to_gib #=> 1.126900315284729
|
110
|
+
ByteSize.gb(1.21).to_tib #=> 0.0011004885891452432
|
111
|
+
ByteSize.gb(1.21).to_pib #=> 1.0746958878371515e-06
|
112
|
+
ByteSize.gb(1.21).to_eib #=> 1.0495077029659683e-09
|
113
|
+
ByteSize.gb(1.21).to_zib #=> 1.0249098661777034e-12
|
114
|
+
ByteSize.gb(1.21).to_yib #=> 1.0008885411891635e-15
|
115
|
+
```
|
116
|
+
|
117
|
+
### Numeric Unit Symbols
|
118
|
+
|
119
|
+
If <code>bytesize-unit</code> is required, convenience methods for all SI and IEC unit symbols are added to the [Numeric](https://ruby-doc.org/core/Numeric.html) class, simplifying the syntax:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
require 'bytesize-unit'
|
123
|
+
|
124
|
+
1.21.gb #=> (1.21 GB)
|
125
|
+
42.zb #=> (42 ZB)
|
126
|
+
|
127
|
+
55.mb * 4 #=> (220 MB)
|
128
|
+
|
129
|
+
6.2.tb.to_kb #=> 6200000000.0
|
130
|
+
```
|
131
|
+
|
132
|
+
### Math Operations
|
133
|
+
|
134
|
+
Standard mathematical operations work with ByteSize:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
ByteSize.mb(55) + ByteSize.kb(64) #=> (55.06 MB)
|
138
|
+
|
139
|
+
ByteSize.mb(22) * 5 #=> (110 MB)
|
140
|
+
|
141
|
+
2 * ByteSize.tb(3) #=> (6 TB)
|
142
|
+
|
143
|
+
ByteSize.mb(100) / 16 #=> (6.25 MB)
|
144
|
+
|
145
|
+
[ 55.mb, 64.kb, 22.mb, 100.mb ].inject( ByteSize.new(0) ){|t,sz| t += sz } #=> (177.06 MB)
|
146
|
+
```
|
147
|
+
|
148
|
+
### Integration with File and Pathname
|
149
|
+
|
150
|
+
ByteSize adds additional methods to File and Pathname that can be used to retrieve a file's size in ByteSize format:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
File.bytesize('VoyageDansLaLune.384400.dpx') #=> (12.75 MB)
|
154
|
+
|
155
|
+
# Get the total size of all JPEGs in a folder
|
156
|
+
Pathname.glob('pictures/*.jpg').inject( ByteSize.new(0) ){|t,f| t += f.bytesize } #=> (26.24 MB)
|
157
|
+
```
|
158
|
+
|
159
|
+
## Contributing
|
160
|
+
|
161
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ajmihunt/bytesize.
|
162
|
+
|
163
|
+
## License
|
164
|
+
|
165
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/bytesize.rb
ADDED
@@ -0,0 +1,1277 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
#
|
3
|
+
# ByteSize
|
4
|
+
#
|
5
|
+
# bytesize.rb
|
6
|
+
#
|
7
|
+
# © 2018 Adam Hunt
|
8
|
+
# Created: 2018-01-17
|
9
|
+
# Modified: 2018-04-08
|
10
|
+
#
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
# :title: ByteSize Documentation
|
16
|
+
#
|
17
|
+
# :include: ../README.md
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bytesize/version'
|
23
|
+
|
24
|
+
require 'pathname'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
# This class is used to represent a size in bytes.
|
29
|
+
#
|
30
|
+
# It uses the {SI}[https://en.wikipedia.org/wiki/International_System_of_Units] standard unit symbols: kB, MB, GB, TB, PB, EB, ZB, YB.
|
31
|
+
#
|
32
|
+
# For a version that uses the {IEC}[https://en.wikipedia.org/wiki/ISO/IEC_80000] standard unit symbols, see <i>{IECByteSize}[IECByteSize.html]</i>.
|
33
|
+
#
|
34
|
+
# === Examples of use
|
35
|
+
#
|
36
|
+
# ByteSize.new( 4127 ) #=> (4.13 kB)
|
37
|
+
# ByteSize.new( "22 GB" ) #=> (22 GB)
|
38
|
+
# ByteSize.new( "22 GiB" ) #=> (23.62 GB)
|
39
|
+
#
|
40
|
+
# ByteSize.bytes( 42 ) #=> (42 bytes)
|
41
|
+
#
|
42
|
+
# ByteSize.kb( 42 ) #=> (42 kB)
|
43
|
+
# ByteSize.mb( 42 ) #=> (42 MB)
|
44
|
+
# ByteSize.gb( 42 ) #=> (42 GB)
|
45
|
+
# ByteSize.tb( 42 ) #=> (42 TB)
|
46
|
+
# ByteSize.pb( 42 ) #=> (42 PB)
|
47
|
+
# ByteSize.eb( 42 ) #=> (42 EB)
|
48
|
+
# ByteSize.zb( 42 ) #=> (42 ZB)
|
49
|
+
# ByteSize.yb( 42 ) #=> (42 YB)
|
50
|
+
#
|
51
|
+
# === Conversion of values:
|
52
|
+
#
|
53
|
+
# ByteSize.gb( 100 ).to_gib #=> 93.13225746154785
|
54
|
+
#
|
55
|
+
# ByteSize.gib( 2.42 ).to_mib #=> 2478.079999923706
|
56
|
+
#
|
57
|
+
# === With numeric convenience methods:
|
58
|
+
#
|
59
|
+
# require 'bytesize/unit'
|
60
|
+
#
|
61
|
+
# 100.gb.to_gib #=> 93.13225746154785
|
62
|
+
#
|
63
|
+
# 2.42.gib.to_mib #=> 2478.079999923706
|
64
|
+
#
|
65
|
+
class ByteSize
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
include Comparable
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
# :stopdoc:
|
74
|
+
SI_BASE = 1000
|
75
|
+
SI_ORDERS_OF_MAGNITUDE = {
|
76
|
+
bytes: 1,
|
77
|
+
kB: SI_BASE,
|
78
|
+
MB: SI_BASE**2,
|
79
|
+
GB: SI_BASE**3,
|
80
|
+
TB: SI_BASE**4,
|
81
|
+
PB: SI_BASE**5,
|
82
|
+
EB: SI_BASE**6,
|
83
|
+
ZB: SI_BASE**7,
|
84
|
+
YB: SI_BASE**8
|
85
|
+
}.freeze
|
86
|
+
|
87
|
+
IEC_BASE = 1024
|
88
|
+
IEC_ORDERS_OF_MAGNITUDE = {
|
89
|
+
bytes: 1,
|
90
|
+
KiB: IEC_BASE,
|
91
|
+
MiB: IEC_BASE**2,
|
92
|
+
GiB: IEC_BASE**3,
|
93
|
+
TiB: IEC_BASE**4,
|
94
|
+
PiB: IEC_BASE**5,
|
95
|
+
EiB: IEC_BASE**6,
|
96
|
+
ZiB: IEC_BASE**7,
|
97
|
+
YiB: IEC_BASE**8
|
98
|
+
}.freeze
|
99
|
+
|
100
|
+
UNIT_SYMBOLS = SI_ORDERS_OF_MAGNITUDE.merge(IEC_ORDERS_OF_MAGNITUDE)
|
101
|
+
UNIT_SYMBOLS.delete(:bytes)
|
102
|
+
UNIT_SYMBOLS.freeze
|
103
|
+
|
104
|
+
ORDERS_OF_MAGNITUDE = SI_ORDERS_OF_MAGNITUDE
|
105
|
+
# :startdoc:
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
# :stopdoc:
|
110
|
+
# Creates convenience methods for all unit symbols
|
111
|
+
UNIT_SYMBOLS.each do |k,v|
|
112
|
+
define_singleton_method(k.downcase) do |n|
|
113
|
+
raise( TypeError, "expected #{Numeric}, got #{n.class}" ) unless n.is_a?(Numeric)
|
114
|
+
self.new( (n*v).round )
|
115
|
+
end
|
116
|
+
define_method(:"to_#{k.downcase}") do
|
117
|
+
bytes / Float(v)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
# :startdoc:
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
# :stopdoc:
|
125
|
+
BYTES_REGEX = /\A\s*(\-?[0-9]+)\s*(bytes)?\s*\z/.freeze
|
126
|
+
SI_REGEX = /\A\s*(\-?[0-9]+(\.[0-9]+)?)\s*(#{ SI_ORDERS_OF_MAGNITUDE.keys.reject{|k| k == :bytes }.join('|') })\s*\z/i.freeze
|
127
|
+
IEC_REGEX = /\A\s*(\-?[0-9]+(\.[0-9]+)?)\s*(#{ IEC_ORDERS_OF_MAGNITUDE.keys.reject{|k| k == :bytes }.join('|') })\s*\z/i.freeze
|
128
|
+
# :startdoc:
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
##
|
133
|
+
# :call-seq:
|
134
|
+
# ByteSize.bytes( n ) -> bytesize
|
135
|
+
#
|
136
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> bytes.
|
137
|
+
#
|
138
|
+
def self.bytes( b )
|
139
|
+
raise( TypeError, "expected #{Numeric}, got #{b.class}" ) unless b.is_a?(Numeric)
|
140
|
+
self.new( b.round )
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
##
|
146
|
+
# :call-seq:
|
147
|
+
# ByteSize.kb( n ) -> bytesize
|
148
|
+
#
|
149
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> kilobytes.
|
150
|
+
#
|
151
|
+
# :singleton-method: kb
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
##
|
156
|
+
# :call-seq:
|
157
|
+
# ByteSize.mb( n ) -> bytesize
|
158
|
+
#
|
159
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> megabytes.
|
160
|
+
#
|
161
|
+
# :singleton-method: mb
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
##
|
166
|
+
# :call-seq:
|
167
|
+
# ByteSize.gb( n ) -> bytesize
|
168
|
+
#
|
169
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> gigabytes.
|
170
|
+
#
|
171
|
+
# :singleton-method: gb
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
##
|
176
|
+
# :call-seq:
|
177
|
+
# ByteSize.tb( n ) -> bytesize
|
178
|
+
#
|
179
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> terabytes.
|
180
|
+
#
|
181
|
+
# :singleton-method: tb
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
##
|
186
|
+
# :call-seq:
|
187
|
+
# ByteSize.pb( n ) -> bytesize
|
188
|
+
#
|
189
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> petabytes.
|
190
|
+
#
|
191
|
+
# :singleton-method: pb
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
##
|
196
|
+
# :call-seq:
|
197
|
+
# ByteSize.eb( n ) -> bytesize
|
198
|
+
#
|
199
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> exabytes.
|
200
|
+
#
|
201
|
+
# :singleton-method: eb
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
##
|
206
|
+
# :call-seq:
|
207
|
+
# ByteSize.zb( n ) -> bytesize
|
208
|
+
#
|
209
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> zettabytes.
|
210
|
+
#
|
211
|
+
# :singleton-method: zb
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
##
|
216
|
+
# :call-seq:
|
217
|
+
# ByteSize.yb( n ) -> bytesize
|
218
|
+
#
|
219
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> yottabytes.
|
220
|
+
#
|
221
|
+
# :singleton-method: yb
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
##
|
226
|
+
# :call-seq:
|
227
|
+
# ByteSize.kib( n ) -> bytesize
|
228
|
+
#
|
229
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> kibibytes.
|
230
|
+
#
|
231
|
+
# :singleton-method: kib
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
##
|
236
|
+
# :call-seq:
|
237
|
+
# ByteSize.mib( n ) -> bytesize
|
238
|
+
#
|
239
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> mebibytes.
|
240
|
+
#
|
241
|
+
# :singleton-method: mib
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
##
|
246
|
+
# :call-seq:
|
247
|
+
# ByteSize.gib( n ) -> bytesize
|
248
|
+
#
|
249
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> gibibytes.
|
250
|
+
#
|
251
|
+
# :singleton-method: gib
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
##
|
256
|
+
# :call-seq:
|
257
|
+
# ByteSize.tib( n ) -> bytesize
|
258
|
+
#
|
259
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> tebibytes.
|
260
|
+
#
|
261
|
+
# :singleton-method: tib
|
262
|
+
|
263
|
+
|
264
|
+
|
265
|
+
##
|
266
|
+
# :call-seq:
|
267
|
+
# ByteSize.pib( n ) -> bytesize
|
268
|
+
#
|
269
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> pebibytes.
|
270
|
+
#
|
271
|
+
# :singleton-method: pib
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
##
|
276
|
+
# :call-seq:
|
277
|
+
# ByteSize.eib( n ) -> bytesize
|
278
|
+
#
|
279
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> exbibytes.
|
280
|
+
#
|
281
|
+
# :singleton-method: eib
|
282
|
+
|
283
|
+
|
284
|
+
|
285
|
+
##
|
286
|
+
# :call-seq:
|
287
|
+
# ByteSize.zib( n ) -> bytesize
|
288
|
+
#
|
289
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> zebibytes.
|
290
|
+
#
|
291
|
+
# :singleton-method: zib
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
##
|
296
|
+
# :call-seq:
|
297
|
+
# ByteSize.yib( n ) -> bytesize
|
298
|
+
#
|
299
|
+
# Returns a new instance of {ByteSize}[ByteSize.html] representing <em>n</em> yobibytes.
|
300
|
+
#
|
301
|
+
# :singleton-method: yib
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
##
|
306
|
+
# call-seq:
|
307
|
+
# ByteSize.parse( string ) -> bytesize
|
308
|
+
#
|
309
|
+
# Parses a {String}[https://ruby-doc.org/core/String.html] into either a
|
310
|
+
# {ByteSize}[ByteSize.html] or {IECByteSize}[IECByteSize.html] depending on it's unit symbol.
|
311
|
+
#
|
312
|
+
def self.parse( val )
|
313
|
+
case val
|
314
|
+
when String
|
315
|
+
if m = val.match(BYTES_REGEX)
|
316
|
+
ByteSize.new( m[1].to_i )
|
317
|
+
elsif m = val.match(SI_REGEX)
|
318
|
+
ByteSize.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f )
|
319
|
+
elsif m = val.match(IEC_REGEX)
|
320
|
+
IECByteSize.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f )
|
321
|
+
else
|
322
|
+
raise( ArgumentError, "invalid #{ByteSize} or #{IECByteSize} string: #{val.inspect}" )
|
323
|
+
end
|
324
|
+
else
|
325
|
+
raise( TypeError, "expected #{String}, got #{str.class}" )
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
# :stopdoc:
|
332
|
+
def self.new( val )
|
333
|
+
if val.class == self
|
334
|
+
super( val.bytes )
|
335
|
+
else
|
336
|
+
case val
|
337
|
+
|
338
|
+
when Integer
|
339
|
+
super( val )
|
340
|
+
|
341
|
+
when ByteSize
|
342
|
+
super( val.bytes )
|
343
|
+
|
344
|
+
when String
|
345
|
+
if m = val.match(BYTES_REGEX)
|
346
|
+
super( m[1].to_i )
|
347
|
+
elsif m = val.match(SI_REGEX)
|
348
|
+
self.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f )
|
349
|
+
elsif m = val.match(IEC_REGEX)
|
350
|
+
self.send( m[3].downcase.to_sym, m[2].nil? ? m[1].to_i : m[1].to_f )
|
351
|
+
else
|
352
|
+
raise( ArgumentError, "invalid #{self} string: #{val.inspect}" )
|
353
|
+
end
|
354
|
+
|
355
|
+
else
|
356
|
+
raise( TypeError, "no implicit conversion of #{val.class} into #{self}" )
|
357
|
+
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
# :startdoc:
|
362
|
+
|
363
|
+
|
364
|
+
|
365
|
+
##
|
366
|
+
# call-seq:
|
367
|
+
# new( integer )
|
368
|
+
# new( string )
|
369
|
+
#
|
370
|
+
# Create a new instance of {ByteSize}[ByteSize.html] from an {Integer}[https://ruby-doc.org/core/Integer.html]
|
371
|
+
# or {String}[https://ruby-doc.org/core/String.html].
|
372
|
+
#
|
373
|
+
def initialize( bytes )
|
374
|
+
raise( TypeError, "expected #{Integer}, got #{bytes.class}" ) unless bytes.is_a?(Integer)
|
375
|
+
@bytes = bytes
|
376
|
+
freeze
|
377
|
+
end
|
378
|
+
|
379
|
+
|
380
|
+
|
381
|
+
##
|
382
|
+
# :call-seq:
|
383
|
+
# to_kb -> float
|
384
|
+
#
|
385
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of kilobytes.
|
386
|
+
#
|
387
|
+
# :method: to_kb
|
388
|
+
|
389
|
+
|
390
|
+
|
391
|
+
##
|
392
|
+
# :call-seq:
|
393
|
+
# to_mb -> float
|
394
|
+
#
|
395
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of megabytes.
|
396
|
+
#
|
397
|
+
# :method: to_mb
|
398
|
+
|
399
|
+
|
400
|
+
|
401
|
+
##
|
402
|
+
# :call-seq:
|
403
|
+
# to_gb -> float
|
404
|
+
#
|
405
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of gigabytes.
|
406
|
+
#
|
407
|
+
# :method: to_gb
|
408
|
+
|
409
|
+
|
410
|
+
|
411
|
+
##
|
412
|
+
# :call-seq:
|
413
|
+
# to_tb -> float
|
414
|
+
#
|
415
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of terabytes.
|
416
|
+
#
|
417
|
+
# :method: to_tb
|
418
|
+
|
419
|
+
|
420
|
+
|
421
|
+
##
|
422
|
+
# :call-seq:
|
423
|
+
# to_pb -> float
|
424
|
+
#
|
425
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of petabytes.
|
426
|
+
#
|
427
|
+
# :method: to_pb
|
428
|
+
|
429
|
+
|
430
|
+
|
431
|
+
##
|
432
|
+
# :call-seq:
|
433
|
+
# to_eb -> float
|
434
|
+
#
|
435
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of exabytes.
|
436
|
+
#
|
437
|
+
# :method: to_eb
|
438
|
+
|
439
|
+
|
440
|
+
|
441
|
+
##
|
442
|
+
# :call-seq:
|
443
|
+
# to_zb -> float
|
444
|
+
#
|
445
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of zettabytes.
|
446
|
+
#
|
447
|
+
# :method: to_zb
|
448
|
+
|
449
|
+
|
450
|
+
|
451
|
+
##
|
452
|
+
# :call-seq:
|
453
|
+
# to_yb -> float
|
454
|
+
#
|
455
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of yottabytes.
|
456
|
+
#
|
457
|
+
# :method: to_yb
|
458
|
+
|
459
|
+
|
460
|
+
|
461
|
+
##
|
462
|
+
# :call-seq:
|
463
|
+
# to_kib -> float
|
464
|
+
#
|
465
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of kibibytes.
|
466
|
+
#
|
467
|
+
# :method: to_kib
|
468
|
+
|
469
|
+
|
470
|
+
|
471
|
+
##
|
472
|
+
# :call-seq:
|
473
|
+
# to_mib -> float
|
474
|
+
#
|
475
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of mebibytes.
|
476
|
+
#
|
477
|
+
# :method: to_mib
|
478
|
+
|
479
|
+
|
480
|
+
|
481
|
+
##
|
482
|
+
# :call-seq:
|
483
|
+
# to_gib -> float
|
484
|
+
#
|
485
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of gibibytes.
|
486
|
+
#
|
487
|
+
# :method: to_gib
|
488
|
+
|
489
|
+
|
490
|
+
|
491
|
+
##
|
492
|
+
# :call-seq:
|
493
|
+
# to_tib -> float
|
494
|
+
#
|
495
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of tebibytes.
|
496
|
+
#
|
497
|
+
# :method: to_tib
|
498
|
+
|
499
|
+
|
500
|
+
|
501
|
+
##
|
502
|
+
# :call-seq:
|
503
|
+
# to_pib -> float
|
504
|
+
#
|
505
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of pebibytes.
|
506
|
+
#
|
507
|
+
# :method: to_pib
|
508
|
+
|
509
|
+
|
510
|
+
|
511
|
+
##
|
512
|
+
# :call-seq:
|
513
|
+
# to_eib -> float
|
514
|
+
#
|
515
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of exbibytes.
|
516
|
+
#
|
517
|
+
# :method: to_eib
|
518
|
+
|
519
|
+
|
520
|
+
|
521
|
+
##
|
522
|
+
# :call-seq:
|
523
|
+
# to_zib -> float
|
524
|
+
#
|
525
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of zebibytes.
|
526
|
+
#
|
527
|
+
# :method: to_zib
|
528
|
+
|
529
|
+
|
530
|
+
|
531
|
+
##
|
532
|
+
# :call-seq:
|
533
|
+
# to_yib -> float
|
534
|
+
#
|
535
|
+
# Returns a {Float}[https://ruby-doc.org/core/Float.html] representing the equivalent number of yobibytes.
|
536
|
+
#
|
537
|
+
# :method: to_yib
|
538
|
+
|
539
|
+
|
540
|
+
|
541
|
+
##
|
542
|
+
# :call-seq:
|
543
|
+
# bytesize < val -> true or false
|
544
|
+
#
|
545
|
+
# Returns <code>true</code> if the value of <em>bytesize</em> is less than that of <em>val</em>.
|
546
|
+
#
|
547
|
+
def <( other )
|
548
|
+
case other
|
549
|
+
|
550
|
+
when Numeric
|
551
|
+
bytes < other
|
552
|
+
|
553
|
+
when ByteSize
|
554
|
+
bytes < other.bytes
|
555
|
+
|
556
|
+
else
|
557
|
+
raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" )
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
|
562
|
+
|
563
|
+
##
|
564
|
+
# :call-seq:
|
565
|
+
# bytesize <= val -> true or false
|
566
|
+
#
|
567
|
+
# Returns <code>true</code> if the value of <em>bytesize</em> is less than or equal to that of <em>val</em>.
|
568
|
+
#
|
569
|
+
def <=( other )
|
570
|
+
case other
|
571
|
+
|
572
|
+
when Numeric
|
573
|
+
bytes <= other
|
574
|
+
|
575
|
+
when ByteSize
|
576
|
+
bytes <= other.bytes
|
577
|
+
|
578
|
+
else
|
579
|
+
raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" )
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
|
584
|
+
|
585
|
+
##
|
586
|
+
# :call-seq:
|
587
|
+
# bytesize > val -> true or false
|
588
|
+
#
|
589
|
+
# Returns <code>true</code> if the value of <em>bytesize</em> is greater than that of <em>val</em>.
|
590
|
+
#
|
591
|
+
def >( other )
|
592
|
+
case other
|
593
|
+
|
594
|
+
when Numeric
|
595
|
+
bytes > other
|
596
|
+
|
597
|
+
when ByteSize
|
598
|
+
bytes > other.bytes
|
599
|
+
|
600
|
+
else
|
601
|
+
raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" )
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
|
606
|
+
|
607
|
+
##
|
608
|
+
# :call-seq:
|
609
|
+
# bytesize >= val -> true or false
|
610
|
+
#
|
611
|
+
# Returns <code>true</code> if the value of <em>bytesize</em> is greater than or equal to that of <em>val</em>.
|
612
|
+
#
|
613
|
+
def >=( other )
|
614
|
+
case other
|
615
|
+
|
616
|
+
when Numeric
|
617
|
+
bytes >= other
|
618
|
+
|
619
|
+
when ByteSize
|
620
|
+
bytes >= other.bytes
|
621
|
+
|
622
|
+
else
|
623
|
+
raise( ArgumentError, "comparison of #{self.class} with #{other.inspect} failed" )
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
|
628
|
+
|
629
|
+
##
|
630
|
+
# :call-seq:
|
631
|
+
# bytesize % val -> bytesize
|
632
|
+
#
|
633
|
+
# Performs a modulo operation with <em>val</em>, returning an instance of {ByteSize}[ByteSize.html].
|
634
|
+
#
|
635
|
+
# <em>val</em> can be another {ByteSize}[ByteSize.html] or a {Numeric}[https://ruby-doc.org/core/Numeric.html].
|
636
|
+
#
|
637
|
+
def %( val )
|
638
|
+
case val
|
639
|
+
|
640
|
+
when Numeric
|
641
|
+
self.class.new(( bytes % val ).round)
|
642
|
+
|
643
|
+
when ByteSize
|
644
|
+
self.class.new( bytes % val.bytes )
|
645
|
+
|
646
|
+
else
|
647
|
+
raise( TypeError, "#{val.class} can't be coerced into #{self.class}" )
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
|
652
|
+
|
653
|
+
##
|
654
|
+
# :call-seq:
|
655
|
+
# bytesize * val -> bytesize
|
656
|
+
#
|
657
|
+
# Performs multiplication, returning an instance of {ByteSize}[ByteSize.html].
|
658
|
+
#
|
659
|
+
# <em>val</em> must be a {Numeric}[https://ruby-doc.org/core/Numeric.html].
|
660
|
+
# Multiplication with another {ByteSize}[ByteSize.html] is disallowed because it does not make symantic sense.
|
661
|
+
#
|
662
|
+
def *( val )
|
663
|
+
case val
|
664
|
+
|
665
|
+
when Numeric
|
666
|
+
self.class.new(( bytes * val ).round)
|
667
|
+
|
668
|
+
when ByteSize
|
669
|
+
raise( TypeError, "cannot multiply #{ByteSize} with #{val.class}" )
|
670
|
+
|
671
|
+
else
|
672
|
+
raise( TypeError, "#{val.class} can't be coerced into #{self.class}" )
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
676
|
+
|
677
|
+
|
678
|
+
##
|
679
|
+
# :call-seq:
|
680
|
+
# bytesize ** pow -> bytesize
|
681
|
+
#
|
682
|
+
# Raises <em>bytesize</em> to the power of <em>pow</em>, returning an instance of {ByteSize}[ByteSize.html].
|
683
|
+
#
|
684
|
+
# <em>pow</em> must be a {Numeric}[https://ruby-doc.org/core/Numeric.html].
|
685
|
+
# Raising to the power of another {ByteSize}[ByteSize.html] is disallowed because it does not make symantic sense.
|
686
|
+
#
|
687
|
+
def **( pow )
|
688
|
+
case pow
|
689
|
+
|
690
|
+
when Numeric
|
691
|
+
self.class.new(( bytes ** pow ).round)
|
692
|
+
|
693
|
+
when ByteSize
|
694
|
+
raise( TypeError, "cannot raise #{ByteSize} to a power of #{pow.class}" )
|
695
|
+
|
696
|
+
else
|
697
|
+
raise( TypeError, "#{pow.class} can't be coerced into #{self.class}" )
|
698
|
+
end
|
699
|
+
end
|
700
|
+
|
701
|
+
|
702
|
+
|
703
|
+
##
|
704
|
+
# :call-seq:
|
705
|
+
# bytesize + val -> bytesize
|
706
|
+
#
|
707
|
+
# Performs addition, returning an instance of {ByteSize}[ByteSize.html].
|
708
|
+
#
|
709
|
+
# <em>val</em> can be another {ByteSize}[ByteSize.html] or a {Numeric}[https://ruby-doc.org/core/Numeric.html].
|
710
|
+
#
|
711
|
+
def +( val )
|
712
|
+
case val
|
713
|
+
|
714
|
+
when Numeric
|
715
|
+
self.class.new(( bytes + val ).round)
|
716
|
+
|
717
|
+
when ByteSize
|
718
|
+
self.class.new( bytes + val.bytes )
|
719
|
+
|
720
|
+
else
|
721
|
+
raise( TypeError, "#{val.class} can't be coerced into #{self.class}" )
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
725
|
+
|
726
|
+
|
727
|
+
##
|
728
|
+
# :call-seq:
|
729
|
+
# +bytesize -> bytesize
|
730
|
+
#
|
731
|
+
# Unary Plus — Returns the receiver’s value.
|
732
|
+
#
|
733
|
+
def +@
|
734
|
+
self
|
735
|
+
end
|
736
|
+
|
737
|
+
|
738
|
+
|
739
|
+
##
|
740
|
+
# :call-seq:
|
741
|
+
# bytesize - val -> bytesize
|
742
|
+
#
|
743
|
+
# Performs subtraction, returning an instance of {ByteSize}[ByteSize.html].
|
744
|
+
#
|
745
|
+
# <em>val</em> can be another {ByteSize}[ByteSize.html] or a {Numeric}[https://ruby-doc.org/core/Numeric.html].
|
746
|
+
#
|
747
|
+
def -( val )
|
748
|
+
case val
|
749
|
+
|
750
|
+
when Numeric
|
751
|
+
self.class.new(( bytes - val ).round)
|
752
|
+
|
753
|
+
when ByteSize
|
754
|
+
self.class.new( bytes - val.bytes )
|
755
|
+
|
756
|
+
else
|
757
|
+
raise( TypeError, "#{val.class} can't be coerced into #{self.class}" )
|
758
|
+
end
|
759
|
+
end
|
760
|
+
|
761
|
+
|
762
|
+
|
763
|
+
##
|
764
|
+
# :call-seq:
|
765
|
+
# -bytesize -> bytesize
|
766
|
+
#
|
767
|
+
# Unary Minus — Returns the receiver’s value, negated.
|
768
|
+
#
|
769
|
+
def -@
|
770
|
+
self.class.new( 0 - bytes )
|
771
|
+
end
|
772
|
+
|
773
|
+
|
774
|
+
|
775
|
+
##
|
776
|
+
# :call-seq:
|
777
|
+
# bytesize / val -> bytesize or float
|
778
|
+
#
|
779
|
+
# Performs division.
|
780
|
+
#
|
781
|
+
# If <em>val</em> is a {Numeric}[https://ruby-doc.org/core/Numeric.html]
|
782
|
+
# it returns an instance of {ByteSize}[ByteSize.html].
|
783
|
+
# If <em>val</em> is an instance of {ByteSize}[ByteSize.html] it returns
|
784
|
+
# a {Float}[https://ruby-doc.org/core/Float.html].
|
785
|
+
#
|
786
|
+
def /( val )
|
787
|
+
case val
|
788
|
+
|
789
|
+
when Numeric
|
790
|
+
self.class.new(( bytes / val ).round)
|
791
|
+
|
792
|
+
when ByteSize
|
793
|
+
bytes.to_f / val.bytes.to_f
|
794
|
+
|
795
|
+
else
|
796
|
+
raise( TypeError, "#{val.class} can't be coerced into #{self.class}" )
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
800
|
+
|
801
|
+
|
802
|
+
##
|
803
|
+
# :call-seq:
|
804
|
+
# bytesize <=> other -> -1, 0, 1, or nil
|
805
|
+
#
|
806
|
+
# Compares <em>bytesize</em> to <em>other</em> and returns <code>0</code> if they are equal,
|
807
|
+
# <code>-1</code> if <em>bytesize</em> is less than <em>other</em>,
|
808
|
+
# or <code>1</code> if <em>bytesize</em> is greater than <em>other</em>.
|
809
|
+
#
|
810
|
+
# Returns <code>nil</code> if the two values are incomparable.
|
811
|
+
#
|
812
|
+
def <=>( other )
|
813
|
+
case other
|
814
|
+
|
815
|
+
when Numeric
|
816
|
+
bytes <=> other
|
817
|
+
|
818
|
+
when ByteSize
|
819
|
+
bytes <=> other.bytes
|
820
|
+
|
821
|
+
else
|
822
|
+
nil
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
826
|
+
|
827
|
+
|
828
|
+
##
|
829
|
+
# :call-seq:
|
830
|
+
# bytesize == other -> true or false
|
831
|
+
#
|
832
|
+
# Returns <code>true</code> if <em>bytesize</em> is equal to <em>other</em>.
|
833
|
+
#
|
834
|
+
# If <em>other</em> is not an instance of {ByteSize}[ByteSize.html] an attempt will be made to convert it to one.
|
835
|
+
#
|
836
|
+
def ==( other )
|
837
|
+
case other
|
838
|
+
|
839
|
+
when Numeric
|
840
|
+
bytes == other
|
841
|
+
|
842
|
+
when ByteSize
|
843
|
+
bytes == other.bytes
|
844
|
+
|
845
|
+
else
|
846
|
+
false
|
847
|
+
end
|
848
|
+
end
|
849
|
+
|
850
|
+
|
851
|
+
|
852
|
+
##
|
853
|
+
# :call-seq:
|
854
|
+
# bytesize === other -> true or false
|
855
|
+
#
|
856
|
+
# Alias for<i> {==}[#method-i-3D-3D]</i>.
|
857
|
+
#
|
858
|
+
# :method: ===
|
859
|
+
|
860
|
+
# :stopdoc:
|
861
|
+
alias_method :===, :==
|
862
|
+
# :startdoc:
|
863
|
+
|
864
|
+
|
865
|
+
|
866
|
+
##
|
867
|
+
# :call-seq:
|
868
|
+
# bytes -> integer
|
869
|
+
#
|
870
|
+
# Returns the number of bytes as an {Integer}[https://ruby-doc.org/core/Integer.html].
|
871
|
+
#
|
872
|
+
# :method: bytes
|
873
|
+
|
874
|
+
# :stopdoc:
|
875
|
+
attr_accessor :bytes
|
876
|
+
# :startdoc:
|
877
|
+
|
878
|
+
|
879
|
+
|
880
|
+
# :stopdoc:
|
881
|
+
def coerce( other )
|
882
|
+
if Numeric
|
883
|
+
[ other, self.to_i ]
|
884
|
+
else
|
885
|
+
begin
|
886
|
+
[ self.class.new(other), self ]
|
887
|
+
rescue
|
888
|
+
raise( TypeError, "#{other.class} can't be coerced into #{self.class}" )
|
889
|
+
end
|
890
|
+
end
|
891
|
+
end
|
892
|
+
# :startdoc:
|
893
|
+
|
894
|
+
|
895
|
+
|
896
|
+
##
|
897
|
+
# :call-seq:
|
898
|
+
# eql?( other_bytesize ) -> true or false
|
899
|
+
#
|
900
|
+
# Returns <code>true</code> if the {ByteSize}[ByteSize.html] is equal to <em>other_bytesize</em>.
|
901
|
+
#
|
902
|
+
def eql?( other )
|
903
|
+
other.class == self.class && other.bytes == bytes
|
904
|
+
end
|
905
|
+
|
906
|
+
|
907
|
+
|
908
|
+
# :stopdoc:
|
909
|
+
def hash
|
910
|
+
bytes.hash
|
911
|
+
end
|
912
|
+
# :startdoc:
|
913
|
+
|
914
|
+
|
915
|
+
|
916
|
+
##
|
917
|
+
# :call-seq:
|
918
|
+
# inspect -> string
|
919
|
+
#
|
920
|
+
# Return a {String}[https://ruby-doc.org/core/String.html] describing this object.
|
921
|
+
#
|
922
|
+
# ====== Example:
|
923
|
+
#
|
924
|
+
# ByteSize.bytes(3000000000000) #=> (3 TB)
|
925
|
+
#
|
926
|
+
def inspect
|
927
|
+
sprintf( '(%s)', to_s )
|
928
|
+
end
|
929
|
+
|
930
|
+
|
931
|
+
|
932
|
+
##
|
933
|
+
# :call-seq:
|
934
|
+
# negative? -> true or false
|
935
|
+
#
|
936
|
+
# Returns <code>true</code> if the {ByteSize}[ByteSize.html] is less than <code>0</code>.
|
937
|
+
#
|
938
|
+
def negative?
|
939
|
+
bytes < 0
|
940
|
+
end
|
941
|
+
|
942
|
+
|
943
|
+
|
944
|
+
##
|
945
|
+
# :call-seq:
|
946
|
+
# positive? -> true or false
|
947
|
+
#
|
948
|
+
# Returns <code>true</code> if the {ByteSize}[ByteSize.html] is greater than <code>0</code>.
|
949
|
+
#
|
950
|
+
def positive?
|
951
|
+
bytes > 0
|
952
|
+
end
|
953
|
+
|
954
|
+
|
955
|
+
|
956
|
+
##
|
957
|
+
# :call-seq:
|
958
|
+
# to_bytes -> integer
|
959
|
+
#
|
960
|
+
# Alias for<i> #bytes</i>.
|
961
|
+
#
|
962
|
+
# :method: to_bytes
|
963
|
+
|
964
|
+
# :stopdoc:
|
965
|
+
alias_method :to_bytes, :bytes
|
966
|
+
# :startdoc:
|
967
|
+
|
968
|
+
|
969
|
+
|
970
|
+
##
|
971
|
+
# :call-seq:
|
972
|
+
# to_i -> integer
|
973
|
+
#
|
974
|
+
# Returns the number of bytes as an {Integer}[https://ruby-doc.org/core/Integer.html].
|
975
|
+
#
|
976
|
+
def to_i
|
977
|
+
bytes.to_i
|
978
|
+
end
|
979
|
+
|
980
|
+
|
981
|
+
|
982
|
+
##
|
983
|
+
# :call-seq:
|
984
|
+
# to_iec -> iecbytesize
|
985
|
+
#
|
986
|
+
# Returns the size as an instance of {IECByteSize}[IECByteSize.html].
|
987
|
+
#
|
988
|
+
# If called on an instance of {IECByteSize}[IECByteSize.html] it returns <code>self</code>.
|
989
|
+
#
|
990
|
+
def to_iec
|
991
|
+
self.class == IECByteSize ? self : IECByteSize.new(self.to_i)
|
992
|
+
end
|
993
|
+
|
994
|
+
|
995
|
+
|
996
|
+
##
|
997
|
+
# :call-seq:
|
998
|
+
# to_s -> string
|
999
|
+
# to_s( decimal_places ) -> string
|
1000
|
+
#
|
1001
|
+
# Format this {ByteSize}[ByteSize.html] as a {String}[https://ruby-doc.org/core/String.html].
|
1002
|
+
#
|
1003
|
+
# The second form formats it with exactly <em>decimal_places</em> decimal places.
|
1004
|
+
#
|
1005
|
+
# ====== Example:
|
1006
|
+
#
|
1007
|
+
# ByteSize.bytes(3000000000000).to_s #=> "3 TB"
|
1008
|
+
# ByteSize.bytes(2460000000000).to_s #=> "2.46 TB"
|
1009
|
+
#
|
1010
|
+
# ByteSize.bytes(3000000000000).to_s(2) #=> "3.00 TB"
|
1011
|
+
# ByteSize.bytes(1234567890000).to_s(2) #=> "1.23 TB"
|
1012
|
+
# ByteSize.bytes(1234567890000).to_s(4) #=> "1.2346 TB"
|
1013
|
+
#
|
1014
|
+
def to_s( decimal_places=nil )
|
1015
|
+
unless decimal_places.nil?
|
1016
|
+
raise( TypeError, "expected #{Integer}, got #{decimal_places.class}" ) unless decimal_places.is_a?(Integer)
|
1017
|
+
raise( RangeError, "decimal places cannot be negative" ) unless decimal_places >= 0
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
b = bytes.abs
|
1021
|
+
|
1022
|
+
scale = self.class::ORDERS_OF_MAGNITUDE.sort{|(ak,av),(bk,bv)| av <=> bv }
|
1023
|
+
|
1024
|
+
if b == 0
|
1025
|
+
unit = scale.first
|
1026
|
+
else
|
1027
|
+
unit = scale.find_index{|k,v| v > b }
|
1028
|
+
if unit.nil?
|
1029
|
+
unit = scale.last
|
1030
|
+
else
|
1031
|
+
unit = scale[unit-1]
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
if decimal_places.nil?
|
1036
|
+
sprintf( negative? ? '-%g %s' : '%g %s', ((b/Float(unit.last))*100).round/100.0, unit.first.to_s )
|
1037
|
+
else
|
1038
|
+
sprintf( negative? ? "-%.0#{decimal_places}f %s" : "%.0#{decimal_places}f %s", b / Float(unit.last), unit.first.to_s )
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
|
1043
|
+
|
1044
|
+
##
|
1045
|
+
# :call-seq:
|
1046
|
+
# to_si -> bytesize
|
1047
|
+
#
|
1048
|
+
# Returns the size as an instance of {ByteSize}[ByteSize.html].
|
1049
|
+
#
|
1050
|
+
# If called on an instance of {ByteSize}[ByteSize.html] it returns <code>self</code>.
|
1051
|
+
#
|
1052
|
+
def to_si
|
1053
|
+
self.class == ByteSize ? self : ByteSize.new(self.to_i)
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
|
1057
|
+
|
1058
|
+
##
|
1059
|
+
# :call-seq:
|
1060
|
+
# zero? -> true or false
|
1061
|
+
#
|
1062
|
+
# Returns <code>true</code> if the {ByteSize}[ByteSize.html] has a zero value.
|
1063
|
+
#
|
1064
|
+
def zero?
|
1065
|
+
bytes == 0
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
|
1069
|
+
|
1070
|
+
|
1071
|
+
|
1072
|
+
|
1073
|
+
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
|
1077
|
+
|
1078
|
+
# This class is identical to <i>{ByteSize}[ByteSize.html]</i> except that all formatted output uses
|
1079
|
+
# the {IEC}[https://en.wikipedia.org/wiki/ISO/IEC_80000] standard unit symbols:
|
1080
|
+
# KiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB.
|
1081
|
+
#
|
1082
|
+
# === Examples of use:
|
1083
|
+
#
|
1084
|
+
# IECByteSize.new( 4127 ) #=> (4.03 KiB)
|
1085
|
+
# IECByteSize.new( "22 GB" ) #=> (20.49 GiB)
|
1086
|
+
# IECByteSize.new( "22 GiB" ) #=> (22 GiB)
|
1087
|
+
#
|
1088
|
+
# IECByteSize.bytes( 42 ) #=> (42 bytes)
|
1089
|
+
#
|
1090
|
+
# IECByteSize.kib( 42 ) #=> (42 KiB)
|
1091
|
+
# IECByteSize.mib( 42 ) #=> (42 MiB)
|
1092
|
+
# IECByteSize.gib( 42 ) #=> (42 GiB)
|
1093
|
+
# IECByteSize.tib( 42 ) #=> (42 TiB)
|
1094
|
+
# IECByteSize.pib( 42 ) #=> (42 PiB)
|
1095
|
+
# IECByteSize.eib( 42 ) #=> (42 EiB)
|
1096
|
+
# IECByteSize.zib( 42 ) #=> (42 ZiB)
|
1097
|
+
# IECByteSize.yib( 42 ) #=> (42 YiB)
|
1098
|
+
#
|
1099
|
+
class IECByteSize < ByteSize
|
1100
|
+
|
1101
|
+
# :stopdoc:
|
1102
|
+
ORDERS_OF_MAGNITUDE = IEC_ORDERS_OF_MAGNITUDE
|
1103
|
+
# :startdoc:
|
1104
|
+
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
|
1108
|
+
|
1109
|
+
# {ByteSize}[ByteSize.html] adds three new methods to the {File}[http://ruby-doc.org/core/File.html] class:
|
1110
|
+
#
|
1111
|
+
# * <i> ::bytesize</i>
|
1112
|
+
# * <i> ::bytesize?</i>
|
1113
|
+
# * <i> #bytesize</i>
|
1114
|
+
#
|
1115
|
+
# Plus the equivalent methods for {IECByteSize}[IECByteSize.html]:
|
1116
|
+
#
|
1117
|
+
# * <i> ::iecbytesize</i>
|
1118
|
+
# * <i> ::iecbytesize?</i>
|
1119
|
+
# * <i> #iecbytesize</i>
|
1120
|
+
#
|
1121
|
+
class File
|
1122
|
+
|
1123
|
+
|
1124
|
+
|
1125
|
+
##
|
1126
|
+
# :call-seq:
|
1127
|
+
# File.bytesize( file_name ) -> bytesize
|
1128
|
+
#
|
1129
|
+
# Identical to<i> {File.size}[http://ruby-doc.org/core/File.html#method-c-size]</i>
|
1130
|
+
# except that the value is returned as an instance of {ByteSize}[ByteSize.html].
|
1131
|
+
#
|
1132
|
+
def self.bytesize( file_name )
|
1133
|
+
ByteSize.new( self.size(file_name) )
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
|
1137
|
+
|
1138
|
+
##
|
1139
|
+
# :call-seq:
|
1140
|
+
# File.bytesize?( file_name ) -> bytesize or nil
|
1141
|
+
#
|
1142
|
+
# Identical to<i> {File.size?}[http://ruby-doc.org/core/File.html#method-c-size-3F]</i>
|
1143
|
+
# except that the value is returned as an instance of {ByteSize}[ByteSize.html].
|
1144
|
+
#
|
1145
|
+
def self.bytesize?( file_name )
|
1146
|
+
sz = self.size?(file_name)
|
1147
|
+
sz.nil? ? nil : ByteSize.new(sz)
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
|
1151
|
+
|
1152
|
+
##
|
1153
|
+
# :call-seq:
|
1154
|
+
# bytesize -> bytesize
|
1155
|
+
#
|
1156
|
+
# Identical to<i> {File#size}[http://ruby-doc.org/core/File.html#method-i-size]</i>
|
1157
|
+
# except that the value is returned as an instance of {ByteSize}[ByteSize.html].
|
1158
|
+
#
|
1159
|
+
def bytesize
|
1160
|
+
ByteSize.new(size)
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
|
1164
|
+
|
1165
|
+
##
|
1166
|
+
# :call-seq:
|
1167
|
+
# File.iecbytesize( file_name ) -> bytesize
|
1168
|
+
#
|
1169
|
+
# Identical to<i> {File.size}[http://ruby-doc.org/core/File.html#method-c-size]</i>
|
1170
|
+
# except that the value is returned as an instance of {IECByteSize}[IECByteSize.html].
|
1171
|
+
#
|
1172
|
+
def self.iecbytesize( file_name )
|
1173
|
+
IECByteSize.new( self.size(file_name) )
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
|
1177
|
+
|
1178
|
+
##
|
1179
|
+
# :call-seq:
|
1180
|
+
# File.iecbytesize?( file_name ) -> bytesize or nil
|
1181
|
+
#
|
1182
|
+
# Identical to<i> {File.size?}[http://ruby-doc.org/core/File.html#method-c-size-3F]</i>
|
1183
|
+
# except that the value is returned as an instance of {IECByteSize}[IECByteSize.html].
|
1184
|
+
#
|
1185
|
+
def self.iecbytesize?( file_name )
|
1186
|
+
sz = self.size?(file_name)
|
1187
|
+
sz.nil? ? nil : IECByteSize.new(sz)
|
1188
|
+
end
|
1189
|
+
|
1190
|
+
|
1191
|
+
|
1192
|
+
##
|
1193
|
+
# :call-seq:
|
1194
|
+
# iecbytesize -> bytesize
|
1195
|
+
#
|
1196
|
+
# Identical to<i> {File#size}[http://ruby-doc.org/core/File.html#method-i-size]</i>
|
1197
|
+
# except that the value is returned as an instance of {IECByteSize}[IECByteSize.html].
|
1198
|
+
#
|
1199
|
+
def iecbytesize
|
1200
|
+
IECByteSize.new(size)
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
|
1204
|
+
|
1205
|
+
end
|
1206
|
+
|
1207
|
+
|
1208
|
+
|
1209
|
+
# ByteSize adds two new methods to the {Pathname}[https://ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html] class:
|
1210
|
+
#
|
1211
|
+
# * <i> #bytesize</i>
|
1212
|
+
# * <i> #bytesize?</i>
|
1213
|
+
#
|
1214
|
+
# Plus the equivalent methods for {IECByteSize}[IECByteSize.html]:
|
1215
|
+
#
|
1216
|
+
# * <i> #iecbytesize</i>
|
1217
|
+
# * <i> #iecbytesize?</i>
|
1218
|
+
#
|
1219
|
+
class Pathname
|
1220
|
+
|
1221
|
+
|
1222
|
+
|
1223
|
+
##
|
1224
|
+
# :call-seq:
|
1225
|
+
# bytesize -> bytesize
|
1226
|
+
#
|
1227
|
+
# Identical to<i> {Pathname#size}[https://ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html#method-i-size]</i>
|
1228
|
+
# except that the value is returned as an instance of {ByteSize}[ByteSize.html].
|
1229
|
+
#
|
1230
|
+
def bytesize
|
1231
|
+
ByteSize.new(size)
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
|
1235
|
+
|
1236
|
+
##
|
1237
|
+
# :call-seq:
|
1238
|
+
# bytesize? -> bytesize or nil
|
1239
|
+
#
|
1240
|
+
# Identical to<i> {Pathname#size?}[https://ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html#method-i-size-3F]</i>
|
1241
|
+
# except that the value is returned as an instance of {ByteSize}[ByteSize.html].
|
1242
|
+
#
|
1243
|
+
def bytesize?
|
1244
|
+
sz = size?
|
1245
|
+
sz.nil? ? nil : ByteSize.new(sz)
|
1246
|
+
end
|
1247
|
+
|
1248
|
+
|
1249
|
+
|
1250
|
+
##
|
1251
|
+
# :call-seq:
|
1252
|
+
# iecbytesize -> bytesize
|
1253
|
+
#
|
1254
|
+
# Identical to<i> {Pathname#size}[https://ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html#method-i-size]</i>
|
1255
|
+
# except that the value is returned as an instance of {IECByteSize}[IECByteSize.html].
|
1256
|
+
#
|
1257
|
+
def iecbytesize
|
1258
|
+
IECByteSize.new(size)
|
1259
|
+
end
|
1260
|
+
|
1261
|
+
|
1262
|
+
|
1263
|
+
##
|
1264
|
+
# :call-seq:
|
1265
|
+
# iecbytesize? -> bytesize or nil
|
1266
|
+
#
|
1267
|
+
# Identical to<i> {Pathname#size?}[https://ruby-doc.org/stdlib/libdoc/pathname/rdoc/Pathname.html#method-i-size-3F]</i>
|
1268
|
+
# except that the value is returned as an instance of {IECByteSize}[IECByteSize.html].
|
1269
|
+
#
|
1270
|
+
def iecbytesize?
|
1271
|
+
sz = size?
|
1272
|
+
sz.nil? ? nil : IECByteSize.new(sz)
|
1273
|
+
end
|
1274
|
+
|
1275
|
+
|
1276
|
+
|
1277
|
+
end
|