📄 fmt.java
字号:
// Fmt - some simple single-arg sprintf-like routines
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
/// Some simple single-arg sprintf-like routines.
// <P>
// It is apparently impossible to declare a Java method that accepts
// variable numbers of any type of argument. You can declare it to take
// Objects, but numeric variables and constants are not in fact Objects.
// <P>
// However, using the built-in string concatenation, it's almost as
// convenient to make a series of single-argument formatting routines.
// <P>
// Fmt can format the following types:
// <BLOCKQUOTE><CODE>
// byte short int long float double char String Object
// </CODE></BLOCKQUOTE>
// For each type there is a set of overloaded methods, each returning
// a formatted String. There's the plain formatting version:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( x )
// </PRE></BLOCKQUOTE>
// There's a version specifying a minimum field width:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( x, minWidth )
// </PRE></BLOCKQUOTE>
// And there's a version that takes flags:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( x, minWidth, flags )
// </PRE></BLOCKQUOTE>
// Currently available flags are:
// <BLOCKQUOTE><PRE>
// Fmt.ZF - zero-fill
// Fmt.LJ - left justify
// Fmt.HX - hexadecimal
// Fmt.OC - octal
// </PRE></BLOCKQUOTE>
// The HX and OC flags imply unsigned output.
// <P>
// For doubles and floats, there's a significant-figures parameter before
// the flags:
// <BLOCKQUOTE><PRE>
// Fmt.fmt( d )
// Fmt.fmt( d, minWidth )
// Fmt.fmt( d, minWidth, sigFigs )
// Fmt.fmt( d, minWidth, sigFigs, flags )
// </PRE></BLOCKQUOTE>
// <P>
// <A HREF="/resources/classes/Acme/Fmt.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <HR>
// Similar classes:
// <UL>
// <LI> Andrew Scherpbier's <A HREF="http://www.sdsu.edu/doc/java-SDSU/sdsu.FormatString.html">FormatString</A>
// Tries to allow variable numbers of arguments by
// supplying overloaded routines with different combinations of parameters,
// but doesn't actually supply that many. The floating point conversion
// is described as "very incomplete".
// <LI> Core Java's <A HREF="http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html">Format</A>.
// The design seems a little weird. They want you to create an instance,
// passing the format string to the constructor, and then call an instance
// method with your data to do the actual formatting. The extra steps are
// pointless; better to just use static methods.
// </UL>
public class Fmt
{
// Flags.
/// Zero-fill.
public static final int ZF = 1;
/// Left justify.
public static final int LJ = 2;
/// Hexadecimal.
public static final int HX = 4;
/// Octal.
public static final int OC = 8;
// Was a number - internal use.
private static final int WN = 16;
// byte
public static String fmt( byte b )
{
return fmt( b, 0, 0 );
}
public static String fmt( byte b, int minWidth )
{
return fmt( b, minWidth, 0 );
}
public static String fmt( byte b, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
return fmt( Integer.toString( b & 0xff, 16 ), minWidth, flags|WN );
else if ( octal )
return fmt( Integer.toString( b & 0xff, 8 ), minWidth, flags|WN );
else
return fmt( Integer.toString( b & 0xff ), minWidth, flags|WN );
}
// short
public static String fmt( short s )
{
return fmt( s, 0, 0 );
}
public static String fmt( short s, int minWidth )
{
return fmt( s, minWidth, 0 );
}
public static String fmt( short s, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
return fmt(
Integer.toString( s & 0xffff, 16 ), minWidth, flags|WN );
else if ( octal )
return fmt(
Integer.toString( s & 0xffff, 8 ), minWidth, flags|WN );
else
return fmt( Integer.toString( s ), minWidth, flags|WN );
}
// int
public static String fmt( int i )
{
return fmt( i, 0, 0 );
}
public static String fmt( int i, int minWidth )
{
return fmt( i, minWidth, 0 );
}
public static String fmt( int i, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
return fmt(
Long.toString( i & 0xffffffffL, 16 ), minWidth, flags|WN );
else if ( octal )
return fmt(
Long.toString( i & 0xffffffffL, 8 ), minWidth, flags|WN );
else
return fmt( Integer.toString( i ), minWidth, flags|WN );
}
// long
public static String fmt( long l )
{
return fmt( l, 0, 0 );
}
public static String fmt( long l, int minWidth )
{
return fmt( l, minWidth, 0 );
}
public static String fmt( long l, int minWidth, int flags )
{
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
if ( hexadecimal )
{
if ( ( l & 0xf000000000000000L ) != 0 )
return fmt(
Long.toString( l >>> 60, 16 ) +
fmt( l & 0x0fffffffffffffffL, 15, HX|ZF ),
minWidth, flags|WN );
else
return fmt( Long.toString( l, 16 ), minWidth, flags|WN );
}
else if ( octal )
{
if ( ( l & 0x8000000000000000L ) != 0 )
return fmt(
Long.toString( l >>> 63, 8 ) +
fmt( l & 0x7fffffffffffffffL, 21, OC|ZF ),
minWidth, flags|WN );
else
return fmt( Long.toString( l, 8 ), minWidth, flags|WN );
}
else
return fmt( Long.toString( l ), minWidth, flags|WN );
}
// float
public static String fmt( float f )
{
return fmt( f, 0, 0, 0 );
}
public static String fmt( float f, int minWidth )
{
return fmt( f, minWidth, 0, 0 );
}
public static String fmt( float f, int minWidth, int sigFigs )
{
return fmt( f, minWidth, sigFigs, 0 );
}
public static String fmt( float f, int minWidth, int sigFigs, int flags )
{
if ( sigFigs != 0 )
return fmt(
sigFigFix( Float.toString( f ), sigFigs ), minWidth,
flags|WN );
else
return fmt( Float.toString( f ), minWidth, flags|WN );
}
// double
public static String fmt( double d )
{
return fmt( d, 0, 0, 0 );
}
public static String fmt( double d, int minWidth )
{
return fmt( d, minWidth, 0, 0 );
}
public static String fmt( double d, int minWidth, int sigFigs )
{
return fmt( d, minWidth, sigFigs, 0 );
}
public static String fmt( double d, int minWidth, int sigFigs, int flags )
{
if ( sigFigs != 0 )
return fmt(
sigFigFix( doubleToString( d ), sigFigs ), minWidth,
flags|WN );
else
return fmt( doubleToString( d ), minWidth, flags|WN );
}
// char
public static String fmt( char c )
{
return fmt( c, 0, 0 );
}
public static String fmt( char c, int minWidth )
{
return fmt( c, minWidth, 0 );
}
public static String fmt( char c, int minWidth, int flags )
{
// return fmt( Character.toString( c ), minWidth, flags );
// Character currently lacks a static toString method. Workaround
// is to make a temporary instance and use the instance toString.
return fmt( new Character( c ).toString(), minWidth, flags );
}
// Object
public static String fmt( Object o )
{
return fmt( o, 0, 0 );
}
public static String fmt( Object o, int minWidth )
{
return fmt( o, minWidth, 0 );
}
public static String fmt( Object o, int minWidth, int flags )
{
return fmt( o.toString(), minWidth, flags );
}
// String
public static String fmt( String s )
{
return fmt( s, 0, 0 );
}
public static String fmt( String s, int minWidth )
{
return fmt( s, minWidth, 0 );
}
public static String fmt( String s, int minWidth, int flags )
{
int len = s.length();
boolean zeroFill = ( ( flags & ZF ) != 0 );
boolean leftJustify = ( ( flags & LJ ) != 0 );
boolean hexadecimal = ( ( flags & HX ) != 0 );
boolean octal = ( ( flags & OC ) != 0 );
boolean wasNumber = ( ( flags & WN ) != 0 );
if ( ( hexadecimal || octal || zeroFill ) && ! wasNumber )
throw new InternalError( "Acme.Fmt: number flag on a non-number" );
if ( zeroFill && leftJustify )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -