gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

util.go (2740B)


      1 package format
      2 
      3 import (
      4 	"strings"
      5 	"unsafe"
      6 )
      7 
      8 const (
      9 	// SingleTermLine: beyond a certain length of string, all of the
     10 	// extra checks to handle quoting/not-quoting add a significant
     11 	// amount of extra processing time. Quoting in this manner only really
     12 	// effects readability on a single line, so a max string length that
     13 	// encompasses the maximum number of columns on *most* terminals was
     14 	// selected. This was chosen using the metric that 1080p is one of the
     15 	// most common display resolutions, and that a relatively small font size
     16 	// of 7 requires 223 columns. So 256 should be >= $COLUMNS (fullscreen)
     17 	// in 99% of usecases (these figures all pulled out of my ass).
     18 	SingleTermLine = 256
     19 )
     20 
     21 // IsSafeASCII checks whether string is printable (i.e. non-control char) ASCII text.
     22 func IsSafeASCII(str string) bool {
     23 	for _, r := range str {
     24 		if (r < ' ' && r != '\t') ||
     25 			r >= 0x7f {
     26 			return false
     27 		}
     28 	}
     29 	return true
     30 }
     31 
     32 // ContainsSpaceOrTab checks if "s" contains space or tabs.
     33 func ContainsSpaceOrTab(s string) bool {
     34 	if i := strings.IndexByte(s, ' '); i >= 0 {
     35 		return true // note using indexbyte as it is ASM.
     36 	} else if i := strings.IndexByte(s, '\t'); i >= 0 {
     37 		return true
     38 	}
     39 	return false
     40 }
     41 
     42 // ContainsDoubleQuote checks if "s" contains a double quote.
     43 func ContainsDoubleQuote(s string) bool {
     44 	return (strings.IndexByte(s, '"') >= 0)
     45 }
     46 
     47 // AppendEscape will append 's' to 'dst' and escape any double quotes.
     48 func AppendEscape(dst []byte, str string) []byte {
     49 	var delim bool
     50 	for i := range str {
     51 		if str[i] == '\\' && !delim {
     52 			// Set delim flag
     53 			delim = true
     54 			continue
     55 		} else if str[i] == '"' && !delim {
     56 			// Append escaped double quote
     57 			dst = append(dst, `\"`...)
     58 			continue
     59 		} else if delim {
     60 			// Append skipped slash
     61 			dst = append(dst, `\`...)
     62 			delim = false
     63 		}
     64 
     65 		// Append char as-is
     66 		dst = append(dst, str[i])
     67 	}
     68 	return dst
     69 }
     70 
     71 // Byte2Str returns 'c' as a string, escaping if necessary.
     72 func Byte2Str(c byte) string {
     73 	switch c {
     74 	case '\a':
     75 		return `\a`
     76 	case '\b':
     77 		return `\b`
     78 	case '\f':
     79 		return `\f`
     80 	case '\n':
     81 		return `\n`
     82 	case '\r':
     83 		return `\r`
     84 	case '\t':
     85 		return `\t`
     86 	case '\v':
     87 		return `\v`
     88 	case '\'':
     89 		return `\\`
     90 	default:
     91 		if c < ' ' {
     92 			const hex = "0123456789abcdef"
     93 			return `\x` +
     94 				string(hex[c>>4]) +
     95 				string(hex[c&0xF])
     96 		}
     97 		return string(c)
     98 	}
     99 }
    100 
    101 // isNil will safely check if 'v' is nil without dealing with weird Go interface nil bullshit.
    102 func isNil(i interface{}) bool {
    103 	type eface struct{ _type, data unsafe.Pointer }    //nolint
    104 	return (*(*eface)(unsafe.Pointer(&i))).data == nil //nolint
    105 }
    106 
    107 // b2s converts a byteslice to string without allocation.
    108 func b2s(b []byte) string {
    109 	return *(*string)(unsafe.Pointer(&b))
    110 }