github.com/nikandfor/hacked@v0.0.0-20231207014854-3b383967fdf4/hfmt/low.go (about)

     1  package hfmt
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"reflect"
     7  	"strconv"
     8  	"unsafe"
     9  )
    10  
    11  //nolint
    12  type (
    13  	iface struct {
    14  		typ, word unsafe.Pointer
    15  	}
    16  
    17  	// pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
    18  	pp struct {
    19  		buf []byte
    20  
    21  		// arg holds the current item, as an interface{}.
    22  		arg interface{}
    23  
    24  		// value is used instead of arg for reflect values.
    25  		value reflect.Value
    26  
    27  		// fmt is used to format basic items such as integers or strings.
    28  		fmt fmtt
    29  
    30  		// reordered records whether the format string used argument reordering.
    31  		reordered bool
    32  		// goodArgNum records whether the most recent reordering directive was valid.
    33  		goodArgNum bool
    34  		// panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
    35  		panicking bool
    36  		// erroring is set when printing an error string to guard against calling handleMethods.
    37  		erroring bool
    38  		// wrapErrs is set when the format string may contain a %w verb.
    39  		wrapErrs bool
    40  		// wrappedErr records the target of the %w verb.
    41  		wrappedErr error
    42  	}
    43  
    44  	// A fmt is the raw formatter used by Printf etc.
    45  	// It prints into a buffer that must be set up separately.
    46  	fmtt struct {
    47  		buf *[]byte
    48  
    49  		fmtFlags
    50  
    51  		wid  int // width
    52  		prec int // precision
    53  
    54  		// intbuf is large enough to store %b of an int64 with a sign and
    55  		// avoids padding at the end of the struct on 32 bit architectures.
    56  		intbuf [68]byte
    57  	}
    58  
    59  	// flags placed in a separate struct for easy clearing.
    60  	fmtFlags struct {
    61  		widPresent  bool
    62  		precPresent bool
    63  		minus       bool
    64  		plus        bool
    65  		sharp       bool
    66  		space       bool
    67  		zero        bool
    68  
    69  		// For the formats %+v %#v, we set the plusV/sharpV flags
    70  		// and clear the plus/sharp flags since %+v and %#v are in effect
    71  		// different, flagless formats set at the top level.
    72  		plusV  bool
    73  		sharpV bool
    74  	}
    75  
    76  	formatter struct{}
    77  )
    78  
    79  var ppType unsafe.Pointer
    80  
    81  func init() {
    82  	fmt.Fprintf(io.Discard, "%v", formatter{})
    83  }
    84  
    85  // Appendf is similar to fmt.Fprintf but a little bit hacked.
    86  //
    87  // There is no sync.Pool.Get and Put. There is no copying buffer to io.Writer or conversion to string. There is no io.Writer interface dereference.
    88  // All that gives advantage about 30-50 ns per call. Yes, I know :).
    89  func Appendf(b []byte, format string, a ...interface{}) []byte {
    90  	var p pp
    91  	p.buf = b
    92  	p.fmt.buf = &p.buf
    93  	doPrintf(&p, format, a)
    94  	b = *(*[]byte)(noescape(unsafe.Pointer(&p.buf)))
    95  	return b
    96  }
    97  
    98  // Appendln is similar to fmt.Sprintln but faster. See doc for Appendf for more details.
    99  func Appendln(b []byte, a ...interface{}) []byte {
   100  	var p pp
   101  	p.buf = b
   102  	p.fmt.buf = &p.buf
   103  	doPrintln(&p, a)
   104  	b = *(*[]byte)(noescape(unsafe.Pointer(&p.buf)))
   105  	return b
   106  }
   107  
   108  // Append is similar to fmt.Sprint but faster. See doc for Appendf for more details.
   109  func Append(b []byte, a ...interface{}) []byte {
   110  	var p pp
   111  	p.buf = b
   112  	p.fmt.buf = &p.buf
   113  	doPrint(&p, a)
   114  	b = *(*[]byte)(noescape(unsafe.Pointer(&p.buf)))
   115  	return b
   116  }
   117  
   118  func PrintArg(s fmt.State, arg interface{}, verb rune) {
   119  	i := *(*iface)(unsafe.Pointer(&s))
   120  	if i.typ != ppType {
   121  		var buf [64]byte
   122  
   123  		i := 0
   124  
   125  		buf[i] = '%'
   126  		i++
   127  
   128  		for _, f := range "-+# 0" {
   129  			if s.Flag(int(f)) {
   130  				buf[i] = byte(f)
   131  				i++
   132  			}
   133  		}
   134  
   135  		if w, ok := s.Width(); ok {
   136  			q := strconv.AppendInt(buf[:i], int64(w), 10)
   137  			i = len(q)
   138  		}
   139  
   140  		if p, ok := s.Precision(); ok {
   141  			buf[i] = '.'
   142  			i++
   143  
   144  			q := strconv.AppendInt(buf[:i], int64(p), 10)
   145  			i = len(q)
   146  		}
   147  
   148  		buf[i] = byte(verb)
   149  		i++
   150  
   151  		fmt.Fprintf(s, bytesToString(buf[:i]), arg)
   152  
   153  		return
   154  	}
   155  
   156  	printArg(i.word, arg, verb)
   157  }
   158  
   159  //go:linkname doPrintf fmt.(*pp).doPrintf
   160  //go:noescape
   161  func doPrintf(p *pp, format string, a []interface{})
   162  
   163  //go:linkname doPrintln fmt.(*pp).doPrintln
   164  //go:noescape
   165  func doPrintln(p *pp, a []interface{})
   166  
   167  //go:linkname doPrint fmt.(*pp).doPrint
   168  //go:noescape
   169  func doPrint(p *pp, a []interface{})
   170  
   171  //go:linkname newPrinter fmt.newPrinter
   172  //go:noescape
   173  func newPrinter() unsafe.Pointer
   174  
   175  //go:linkname ppFree fmt.(*pp).free
   176  //go:noescape
   177  func ppFree(unsafe.Pointer)
   178  
   179  //go:linkname printArg fmt.(*pp).printArg
   180  //go:noescape
   181  func printArg(p unsafe.Pointer, arg interface{}, verb rune)
   182  
   183  func (formatter) Format(s fmt.State, c rune) {
   184  	i := *(*iface)(unsafe.Pointer(&s))
   185  
   186  	ppType = i.typ
   187  }
   188  
   189  // noescape hides a pointer from escape analysis.  noescape is
   190  // the identity function but escape analysis doesn't think the
   191  // output depends on the input.  noescape is inlined and currently
   192  // compiles down to zero instructions.
   193  // USE CAREFULLY!
   194  //go:nosplit
   195  func noescape(p unsafe.Pointer) unsafe.Pointer {
   196  	x := uintptr(p)
   197  	return unsafe.Pointer(x ^ 0) //nolint:staticcheck
   198  }
   199  
   200  func bytesToString(b []byte) string {
   201  	return *(*string)(unsafe.Pointer(&b))
   202  }