element.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package ini
  2. import (
  3. "fmt"
  4. )
  5. type elementType int
  6. type elementByte []byte
  7. const (
  8. section elementType = 1 << iota
  9. variable elementType = 1 << iota
  10. )
  11. type element struct {
  12. t elementType
  13. key elementByte
  14. val elementByte
  15. quoted bool
  16. }
  17. func newElement() *element {
  18. return &element{quoted: false}
  19. }
  20. func (e *element) setType(t elementType) {
  21. e.t = t
  22. }
  23. func (e *element) trim() {
  24. e.key.trim()
  25. e.quoted = e.val.trim()
  26. }
  27. func (e *element) String() string {
  28. switch e.t {
  29. case section:
  30. return fmt.Sprintf(
  31. "section: %s", e.key,
  32. )
  33. case variable:
  34. if e.val.len() == 0 {
  35. return fmt.Sprintf(
  36. "variable: %s -> true", e.val,
  37. )
  38. }
  39. if e.quoted {
  40. return fmt.Sprintf(
  41. "variable: %s -> '\"%s\"'", e.key, e.val,
  42. )
  43. }
  44. return fmt.Sprintf(
  45. "variable: %s -> '%s'", e.key, e.val,
  46. )
  47. default:
  48. return "unknown element"
  49. }
  50. }
  51. func (e *elementByte) add(v ...interface{}) bool {
  52. b := i2byte(v)
  53. if len(b) == 0 {
  54. return false
  55. }
  56. *e = append(*e, b...)
  57. return true
  58. }
  59. func (e *elementByte) len() int {
  60. return len(*e)
  61. }
  62. func (e *elementByte) lastByteMatching(c byte) int {
  63. if n := e.len(); n != 0 && (*e)[n-1] == c {
  64. return n - 1
  65. }
  66. return -1
  67. }
  68. func (e *elementByte) firstByteMatching(c byte) int {
  69. if n := e.len(); n != 0 && (*e)[0] == c {
  70. return 0
  71. }
  72. return -1
  73. }
  74. func (e *elementByte) removeFirstByteMatching(c byte) bool {
  75. if n := e.firstByteMatching(c); n == 0 {
  76. *e = (*e)[1:]
  77. return true
  78. }
  79. return false
  80. }
  81. func (e *elementByte) removeLastByteMatching(c byte) bool {
  82. if n := e.lastByteMatching(c); n >= 0 {
  83. *e = (*e)[0:n]
  84. return true
  85. }
  86. return false
  87. }
  88. func (e *elementByte) trim() (quoted bool) {
  89. for b := e.removeFirstByteMatching(' '); b == true; b = e.removeFirstByteMatching(' ') {
  90. // remove leading whitespaces
  91. }
  92. for b := e.removeLastByteMatching(' '); b == true; b = e.removeLastByteMatching(' ') {
  93. // remove trailing whitespaces
  94. }
  95. if f := e.firstByteMatching('"'); f == 0 {
  96. if l := e.lastByteMatching('"'); l >= 0 {
  97. *e = (*e)[1:]
  98. *e = (*e)[0 : l-1]
  99. return true
  100. }
  101. }
  102. return false
  103. }
  104. func i2byte(v ...interface{}) []byte {
  105. var b []byte
  106. for _, i := range v {
  107. switch i.(type) {
  108. case byte, int8:
  109. b = append(b, i.(byte))
  110. case int:
  111. if i.(int) < 256 {
  112. b = append(b, byte(i.(int)))
  113. }
  114. case int16:
  115. if i.(int16) < 256 {
  116. b = append(b, byte(i.(int16)))
  117. }
  118. case int32:
  119. if i.(int32) < 256 {
  120. b = append(b, byte(i.(int32)))
  121. }
  122. case int64:
  123. if i.(int64) < 256 {
  124. b = append(b, byte(i.(int64)))
  125. }
  126. case []byte:
  127. b = append(b, i.([]byte)...)
  128. case string:
  129. b = append(b, i2byte([]byte(i.(string)))...)
  130. case []interface{}:
  131. for _, ii := range i.([]interface{}) {
  132. b = append(b, i2byte(ii)...)
  133. }
  134. }
  135. }
  136. return b
  137. }