123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package ini
- import (
- "fmt"
- )
- type elementType int
- type elementByte []byte
- const (
- section elementType = 1 << iota
- variable elementType = 1 << iota
- )
- type element struct {
- t elementType
- key elementByte
- val elementByte
- quoted bool
- }
- func newElement() *element {
- return &element{quoted: false}
- }
- func (e *element) setType(t elementType) {
- e.t = t
- }
- func (e *element) trim() {
- e.key.trim()
- e.quoted = e.val.trim()
- }
- func (e *element) String() string {
- switch e.t {
- case section:
- return fmt.Sprintf(
- "section: %s", e.key,
- )
- case variable:
- if e.val.len() == 0 {
- return fmt.Sprintf(
- "variable: %s -> true", e.val,
- )
- }
- if e.quoted {
- return fmt.Sprintf(
- "variable: %s -> '\"%s\"'", e.key, e.val,
- )
- }
- return fmt.Sprintf(
- "variable: %s -> '%s'", e.key, e.val,
- )
- default:
- return "unknown element"
- }
- }
- func (e *elementByte) add(v ...interface{}) bool {
- b := i2byte(v)
- if len(b) == 0 {
- return false
- }
- *e = append(*e, b...)
- return true
- }
- func (e *elementByte) len() int {
- return len(*e)
- }
- func (e *elementByte) lastByteMatching(c byte) int {
- if n := e.len(); n != 0 && (*e)[n-1] == c {
- return n - 1
- }
- return -1
- }
- func (e *elementByte) firstByteMatching(c byte) int {
- if n := e.len(); n != 0 && (*e)[0] == c {
- return 0
- }
- return -1
- }
- func (e *elementByte) removeFirstByteMatching(c byte) bool {
- if n := e.firstByteMatching(c); n == 0 {
- *e = (*e)[1:]
- return true
- }
- return false
- }
- func (e *elementByte) removeLastByteMatching(c byte) bool {
- if n := e.lastByteMatching(c); n >= 0 {
- *e = (*e)[0:n]
- return true
- }
- return false
- }
- func (e *elementByte) trim() (quoted bool) {
- for b := e.removeFirstByteMatching(' '); b == true; b = e.removeFirstByteMatching(' ') {
- // remove leading whitespaces
- }
- for b := e.removeLastByteMatching(' '); b == true; b = e.removeLastByteMatching(' ') {
- // remove trailing whitespaces
- }
- if f := e.firstByteMatching('"'); f == 0 {
- if l := e.lastByteMatching('"'); l >= 0 {
- *e = (*e)[1:]
- *e = (*e)[0 : l-1]
- return true
- }
- }
- return false
- }
- func i2byte(v ...interface{}) []byte {
- var b []byte
- for _, i := range v {
- switch i.(type) {
- case byte, int8:
- b = append(b, i.(byte))
- case int:
- if i.(int) < 256 {
- b = append(b, byte(i.(int)))
- }
- case int16:
- if i.(int16) < 256 {
- b = append(b, byte(i.(int16)))
- }
- case int32:
- if i.(int32) < 256 {
- b = append(b, byte(i.(int32)))
- }
- case int64:
- if i.(int64) < 256 {
- b = append(b, byte(i.(int64)))
- }
- case []byte:
- b = append(b, i.([]byte)...)
- case string:
- b = append(b, i2byte([]byte(i.(string)))...)
- case []interface{}:
- for _, ii := range i.([]interface{}) {
- b = append(b, i2byte(ii)...)
- }
- }
- }
- return b
- }
|