1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
package parser
import "math"
// Shift and masks for sequence parameters and intermediates.
const (
MarkerShift = 8
IntermedShift = 16
CommandMask = 0xff
HasMoreFlag = math.MinInt32
ParamMask = ^HasMoreFlag
MissingParam = ParamMask
MissingCommand = MissingParam
MaxParam = math.MaxUint16 // the maximum value a parameter can have
)
const (
// MaxParamsSize is the maximum number of parameters a sequence can have.
MaxParamsSize = 32
// DefaultParamValue is the default value used for missing parameters.
DefaultParamValue = 0
)
// Marker returns the marker byte of the sequence.
// This is always gonna be one of the following '<' '=' '>' '?' and in the
// range of 0x3C-0x3F.
// Zero is returned if the sequence does not have a marker.
func Marker(cmd int) int {
return (cmd >> MarkerShift) & CommandMask
}
// Intermediate returns the intermediate byte of the sequence.
// An intermediate byte is in the range of 0x20-0x2F. This includes these
// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+',
// ',', '-', '.', '/'.
// Zero is returned if the sequence does not have an intermediate byte.
func Intermediate(cmd int) int {
return (cmd >> IntermedShift) & CommandMask
}
// Command returns the command byte of the CSI sequence.
func Command(cmd int) int {
return cmd & CommandMask
}
// Param returns the parameter at the given index.
// It returns -1 if the parameter does not exist.
func Param(params []int, i int) int {
if len(params) == 0 || i < 0 || i >= len(params) {
return -1
}
p := params[i] & ParamMask
if p == MissingParam {
return -1
}
return p
}
// HasMore returns true if the parameter has more sub-parameters.
func HasMore(params []int, i int) bool {
if len(params) == 0 || i >= len(params) {
return false
}
return params[i]&HasMoreFlag != 0
}
// Subparams returns the sub-parameters of the given parameter.
// It returns nil if the parameter does not exist.
func Subparams(params []int, i int) []int {
if len(params) == 0 || i < 0 || i >= len(params) {
return nil
}
// Count the number of parameters before the given parameter index.
var count int
var j int
for j = 0; j < len(params); j++ {
if count == i {
break
}
if !HasMore(params, j) {
count++
}
}
if count > i || j >= len(params) {
return nil
}
var subs []int
for ; j < len(params); j++ {
if !HasMore(params, j) {
break
}
p := Param(params, j)
if p == -1 {
p = DefaultParamValue
}
subs = append(subs, p)
}
p := Param(params, j)
if p == -1 {
p = DefaultParamValue
}
return append(subs, p)
}
// Len returns the number of parameters in the sequence.
// This will return the number of parameters in the sequence, excluding any
// sub-parameters.
func Len(params []int) int {
var n int
for i := 0; i < len(params); i++ {
if !HasMore(params, i) {
n++
}
}
return n
}
// Range iterates over the parameters of the sequence and calls the given
// function for each parameter.
// The function should return false to stop the iteration.
func Range(params []int, fn func(i int, param int, hasMore bool) bool) {
for i := 0; i < len(params); i++ {
if !fn(i, Param(params, i), HasMore(params, i)) {
break
}
}
}
|