github.com/aavshr/aws-sdk-go@v1.41.3/internal/ini/value_util.go (about)

     1  package ini
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // getStringValue will return a quoted string and the amount
     8  // of bytes read
     9  //
    10  // an error will be returned if the string is not properly formatted
    11  func getStringValue(b []rune) (int, error) {
    12  	if b[0] != '"' {
    13  		return 0, NewParseError("strings must start with '\"'")
    14  	}
    15  
    16  	endQuote := false
    17  	i := 1
    18  
    19  	for ; i < len(b) && !endQuote; i++ {
    20  		if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
    21  			endQuote = true
    22  			break
    23  		} else if escaped {
    24  			/*c, err := getEscapedByte(b[i])
    25  			if err != nil {
    26  				return 0, err
    27  			}
    28  
    29  			b[i-1] = c
    30  			b = append(b[:i], b[i+1:]...)
    31  			i--*/
    32  
    33  			continue
    34  		}
    35  	}
    36  
    37  	if !endQuote {
    38  		return 0, NewParseError("missing '\"' in string value")
    39  	}
    40  
    41  	return i + 1, nil
    42  }
    43  
    44  // getBoolValue will return a boolean and the amount
    45  // of bytes read
    46  //
    47  // an error will be returned if the boolean is not of a correct
    48  // value
    49  func getBoolValue(b []rune) (int, error) {
    50  	if len(b) < 4 {
    51  		return 0, NewParseError("invalid boolean value")
    52  	}
    53  
    54  	n := 0
    55  	for _, lv := range literalValues {
    56  		if len(lv) > len(b) {
    57  			continue
    58  		}
    59  
    60  		if isLitValue(lv, b) {
    61  			n = len(lv)
    62  		}
    63  	}
    64  
    65  	if n == 0 {
    66  		return 0, NewParseError("invalid boolean value")
    67  	}
    68  
    69  	return n, nil
    70  }
    71  
    72  // getNumericalValue will return a numerical string, the amount
    73  // of bytes read, and the base of the number
    74  //
    75  // an error will be returned if the number is not of a correct
    76  // value
    77  func getNumericalValue(b []rune) (int, int, error) {
    78  	if !isDigit(b[0]) {
    79  		return 0, 0, NewParseError("invalid digit value")
    80  	}
    81  
    82  	i := 0
    83  	helper := numberHelper{}
    84  
    85  loop:
    86  	for negativeIndex := 0; i < len(b); i++ {
    87  		negativeIndex++
    88  
    89  		if !isDigit(b[i]) {
    90  			switch b[i] {
    91  			case '-':
    92  				if helper.IsNegative() || negativeIndex != 1 {
    93  					return 0, 0, NewParseError("parse error '-'")
    94  				}
    95  
    96  				n := getNegativeNumber(b[i:])
    97  				i += (n - 1)
    98  				helper.Determine(b[i])
    99  				continue
   100  			case '.':
   101  				if err := helper.Determine(b[i]); err != nil {
   102  					return 0, 0, err
   103  				}
   104  			case 'e', 'E':
   105  				if err := helper.Determine(b[i]); err != nil {
   106  					return 0, 0, err
   107  				}
   108  
   109  				negativeIndex = 0
   110  			case 'b':
   111  				if helper.numberFormat == hex {
   112  					break
   113  				}
   114  				fallthrough
   115  			case 'o', 'x':
   116  				if i == 0 && b[i] != '0' {
   117  					return 0, 0, NewParseError("incorrect base format, expected leading '0'")
   118  				}
   119  
   120  				if i != 1 {
   121  					return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i))
   122  				}
   123  
   124  				if err := helper.Determine(b[i]); err != nil {
   125  					return 0, 0, err
   126  				}
   127  			default:
   128  				if isWhitespace(b[i]) {
   129  					break loop
   130  				}
   131  
   132  				if isNewline(b[i:]) {
   133  					break loop
   134  				}
   135  
   136  				if !(helper.numberFormat == hex && isHexByte(b[i])) {
   137  					if i+2 < len(b) && !isNewline(b[i:i+2]) {
   138  						return 0, 0, NewParseError("invalid numerical character")
   139  					} else if !isNewline([]rune{b[i]}) {
   140  						return 0, 0, NewParseError("invalid numerical character")
   141  					}
   142  
   143  					break loop
   144  				}
   145  			}
   146  		}
   147  	}
   148  
   149  	return helper.Base(), i, nil
   150  }
   151  
   152  // isDigit will return whether or not something is an integer
   153  func isDigit(b rune) bool {
   154  	return b >= '0' && b <= '9'
   155  }
   156  
   157  func hasExponent(v []rune) bool {
   158  	return contains(v, 'e') || contains(v, 'E')
   159  }
   160  
   161  func isBinaryByte(b rune) bool {
   162  	switch b {
   163  	case '0', '1':
   164  		return true
   165  	default:
   166  		return false
   167  	}
   168  }
   169  
   170  func isOctalByte(b rune) bool {
   171  	switch b {
   172  	case '0', '1', '2', '3', '4', '5', '6', '7':
   173  		return true
   174  	default:
   175  		return false
   176  	}
   177  }
   178  
   179  func isHexByte(b rune) bool {
   180  	if isDigit(b) {
   181  		return true
   182  	}
   183  	return (b >= 'A' && b <= 'F') ||
   184  		(b >= 'a' && b <= 'f')
   185  }
   186  
   187  func getValue(b []rune) (int, error) {
   188  	i := 0
   189  
   190  	for i < len(b) {
   191  		if isNewline(b[i:]) {
   192  			break
   193  		}
   194  
   195  		if isOp(b[i:]) {
   196  			break
   197  		}
   198  
   199  		valid, n, err := isValid(b[i:])
   200  		if err != nil {
   201  			return 0, err
   202  		}
   203  
   204  		if !valid {
   205  			break
   206  		}
   207  
   208  		i += n
   209  	}
   210  
   211  	return i, nil
   212  }
   213  
   214  // getNegativeNumber will return a negative number from a
   215  // byte slice. This will iterate through all characters until
   216  // a non-digit has been found.
   217  func getNegativeNumber(b []rune) int {
   218  	if b[0] != '-' {
   219  		return 0
   220  	}
   221  
   222  	i := 1
   223  	for ; i < len(b); i++ {
   224  		if !isDigit(b[i]) {
   225  			return i
   226  		}
   227  	}
   228  
   229  	return i
   230  }
   231  
   232  // isEscaped will return whether or not the character is an escaped
   233  // character.
   234  func isEscaped(value []rune, b rune) bool {
   235  	if len(value) == 0 {
   236  		return false
   237  	}
   238  
   239  	switch b {
   240  	case '\'': // single quote
   241  	case '"': // quote
   242  	case 'n': // newline
   243  	case 't': // tab
   244  	case '\\': // backslash
   245  	default:
   246  		return false
   247  	}
   248  
   249  	return value[len(value)-1] == '\\'
   250  }
   251  
   252  func getEscapedByte(b rune) (rune, error) {
   253  	switch b {
   254  	case '\'': // single quote
   255  		return '\'', nil
   256  	case '"': // quote
   257  		return '"', nil
   258  	case 'n': // newline
   259  		return '\n', nil
   260  	case 't': // table
   261  		return '\t', nil
   262  	case '\\': // backslash
   263  		return '\\', nil
   264  	default:
   265  		return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
   266  	}
   267  }
   268  
   269  func removeEscapedCharacters(b []rune) []rune {
   270  	for i := 0; i < len(b); i++ {
   271  		if isEscaped(b[:i], b[i]) {
   272  			c, err := getEscapedByte(b[i])
   273  			if err != nil {
   274  				return b
   275  			}
   276  
   277  			b[i-1] = c
   278  			b = append(b[:i], b[i+1:]...)
   279  			i--
   280  		}
   281  	}
   282  
   283  	return b
   284  }