blob: 6ae2054e6518ec40b056d1f568759e48596dd1ff [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.cli.transfer;
import java.util.Locale;
/**
* Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix
* (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10
* and <code>###0</code> for numbers between 10 and 1000+ by default.
*
* @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a>
* @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a>
* @see <a
* href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a>
*/
public class FileSizeFormat {
public enum ScaleUnit {
BYTE {
@Override
public long bytes() {
return 1L;
}
@Override
public String symbol() {
return "B";
}
},
KILOBYTE {
@Override
public long bytes() {
return 1000L;
}
@Override
public String symbol() {
return "kB";
}
},
MEGABYTE {
@Override
public long bytes() {
return KILOBYTE.bytes() * KILOBYTE.bytes();
}
@Override
public String symbol() {
return "MB";
}
},
GIGABYTE {
@Override
public long bytes() {
return MEGABYTE.bytes() * KILOBYTE.bytes();
}
;
@Override
public String symbol() {
return "GB";
}
};
public abstract long bytes();
public abstract String symbol();
public static ScaleUnit getScaleUnit(long size) {
if (size < 0L) {
throw new IllegalArgumentException("file size cannot be negative: " + size);
}
if (size >= GIGABYTE.bytes()) {
return GIGABYTE;
} else if (size >= MEGABYTE.bytes()) {
return MEGABYTE;
} else if (size >= KILOBYTE.bytes()) {
return KILOBYTE;
} else {
return BYTE;
}
}
}
public FileSizeFormat(Locale locale) {}
public String format(long size) {
return format(size, null);
}
public String format(long size, ScaleUnit unit) {
return format(size, unit, false);
}
public String format(long size, ScaleUnit unit, boolean omitSymbol) {
StringBuilder sb = new StringBuilder();
format(sb, size, unit, omitSymbol);
return sb.toString();
}
public void format(StringBuilder builder, long size) {
format(builder, size, null, false);
}
public void format(StringBuilder builder, long size, ScaleUnit unit) {
format(builder, size, unit, false);
}
@SuppressWarnings("checkstyle:magicnumber")
private void format(StringBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) {
if (size < 0L) {
throw new IllegalArgumentException("file size cannot be negative: " + size);
}
if (unit == null) {
unit = ScaleUnit.getScaleUnit(size);
}
double scaledSize = (double) size / unit.bytes();
if (unit == ScaleUnit.BYTE) {
builder.append(size);
} else if (scaledSize < 0.05d || scaledSize >= 10.0d) {
builder.append(Math.round(scaledSize));
} else {
builder.append(Math.round(scaledSize * 10d) / 10d);
}
if (!omitSymbol) {
builder.append(" ").append(unit.symbol());
}
}
public String formatProgress(long progressedSize, long size) {
StringBuilder sb = new StringBuilder();
formatProgress(sb, progressedSize, size);
return sb.toString();
}
public void formatProgress(StringBuilder builder, long progressedSize, long size) {
if (progressedSize < 0L) {
throw new IllegalArgumentException("progressed file size cannot be negative: " + size);
}
if (size >= 0 && progressedSize > size) {
throw new IllegalArgumentException(
"progressed file size cannot be greater than size: " + progressedSize + " > " + size);
}
if (size >= 0L && progressedSize != size) {
ScaleUnit unit = ScaleUnit.getScaleUnit(size);
format(builder, progressedSize, unit, true);
builder.append("/");
format(builder, size, unit, false);
} else {
ScaleUnit unit = ScaleUnit.getScaleUnit(progressedSize);
format(builder, progressedSize, unit, false);
}
}
}