ini.go 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  1. // Copyright 2014 Unknwon
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. // License for the specific language governing permissions and limitations
  13. // under the License.
  14. // Package ini provides INI file read and write functionality in Go.
  15. package ini
  16. import (
  17. "bufio"
  18. "bytes"
  19. "errors"
  20. "fmt"
  21. "io"
  22. "os"
  23. "regexp"
  24. "runtime"
  25. "strconv"
  26. "strings"
  27. "sync"
  28. "time"
  29. )
  30. const (
  31. DEFAULT_SECTION = "DEFAULT"
  32. // Maximum allowed depth when recursively substituing variable names.
  33. _DEPTH_VALUES = 99
  34. _VERSION = "1.6.0"
  35. )
  36. func Version() string {
  37. return _VERSION
  38. }
  39. var (
  40. LineBreak = "\n"
  41. // Variable regexp pattern: %(variable)s
  42. varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`)
  43. // Write spaces around "=" to look better.
  44. PrettyFormat = true
  45. )
  46. func init() {
  47. if runtime.GOOS == "windows" {
  48. LineBreak = "\r\n"
  49. }
  50. }
  51. func inSlice(str string, s []string) bool {
  52. for _, v := range s {
  53. if str == v {
  54. return true
  55. }
  56. }
  57. return false
  58. }
  59. // dataSource is a interface that returns file content.
  60. type dataSource interface {
  61. ReadCloser() (io.ReadCloser, error)
  62. }
  63. type sourceFile struct {
  64. name string
  65. }
  66. func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) {
  67. return os.Open(s.name)
  68. }
  69. type bytesReadCloser struct {
  70. reader io.Reader
  71. }
  72. func (rc *bytesReadCloser) Read(p []byte) (n int, err error) {
  73. return rc.reader.Read(p)
  74. }
  75. func (rc *bytesReadCloser) Close() error {
  76. return nil
  77. }
  78. type sourceData struct {
  79. data []byte
  80. }
  81. func (s *sourceData) ReadCloser() (io.ReadCloser, error) {
  82. return &bytesReadCloser{bytes.NewReader(s.data)}, nil
  83. }
  84. // ____ __.
  85. // | |/ _|____ ___.__.
  86. // | <_/ __ < | |
  87. // | | \ ___/\___ |
  88. // |____|__ \___ > ____|
  89. // \/ \/\/
  90. // Key represents a key under a section.
  91. type Key struct {
  92. s *Section
  93. Comment string
  94. name string
  95. value string
  96. isAutoIncr bool
  97. }
  98. // Name returns name of key.
  99. func (k *Key) Name() string {
  100. return k.name
  101. }
  102. // Value returns raw value of key for performance purpose.
  103. func (k *Key) Value() string {
  104. return k.value
  105. }
  106. // String returns string representation of value.
  107. func (k *Key) String() string {
  108. val := k.value
  109. if strings.Index(val, "%") == -1 {
  110. return val
  111. }
  112. for i := 0; i < _DEPTH_VALUES; i++ {
  113. vr := varPattern.FindString(val)
  114. if len(vr) == 0 {
  115. break
  116. }
  117. // Take off leading '%(' and trailing ')s'.
  118. noption := strings.TrimLeft(vr, "%(")
  119. noption = strings.TrimRight(noption, ")s")
  120. // Search in the same section.
  121. nk, err := k.s.GetKey(noption)
  122. if err != nil {
  123. // Search again in default section.
  124. nk, _ = k.s.f.Section("").GetKey(noption)
  125. }
  126. // Substitute by new value and take off leading '%(' and trailing ')s'.
  127. val = strings.Replace(val, vr, nk.value, -1)
  128. }
  129. return val
  130. }
  131. // Validate accepts a validate function which can
  132. // return modifed result as key value.
  133. func (k *Key) Validate(fn func(string) string) string {
  134. return fn(k.String())
  135. }
  136. // parseBool returns the boolean value represented by the string.
  137. //
  138. // It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, ON, on, On,
  139. // 0, f, F, FALSE, false, False, NO, no, No, OFF, off, Off.
  140. // Any other value returns an error.
  141. func parseBool(str string) (value bool, err error) {
  142. switch str {
  143. case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "ON", "on", "On":
  144. return true, nil
  145. case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "OFF", "off", "Off":
  146. return false, nil
  147. }
  148. return false, fmt.Errorf("parsing \"%s\": invalid syntax", str)
  149. }
  150. // Bool returns bool type value.
  151. func (k *Key) Bool() (bool, error) {
  152. return parseBool(k.String())
  153. }
  154. // Float64 returns float64 type value.
  155. func (k *Key) Float64() (float64, error) {
  156. return strconv.ParseFloat(k.String(), 64)
  157. }
  158. // Int returns int type value.
  159. func (k *Key) Int() (int, error) {
  160. return strconv.Atoi(k.String())
  161. }
  162. // Int64 returns int64 type value.
  163. func (k *Key) Int64() (int64, error) {
  164. return strconv.ParseInt(k.String(), 10, 64)
  165. }
  166. // Uint returns uint type valued.
  167. func (k *Key) Uint() (uint, error) {
  168. u, e := strconv.ParseUint(k.String(), 10, 64)
  169. return uint(u), e
  170. }
  171. // Uint64 returns uint64 type value.
  172. func (k *Key) Uint64() (uint64, error) {
  173. return strconv.ParseUint(k.String(), 10, 64)
  174. }
  175. // Duration returns time.Duration type value.
  176. func (k *Key) Duration() (time.Duration, error) {
  177. return time.ParseDuration(k.String())
  178. }
  179. // TimeFormat parses with given format and returns time.Time type value.
  180. func (k *Key) TimeFormat(format string) (time.Time, error) {
  181. return time.Parse(format, k.String())
  182. }
  183. // Time parses with RFC3339 format and returns time.Time type value.
  184. func (k *Key) Time() (time.Time, error) {
  185. return k.TimeFormat(time.RFC3339)
  186. }
  187. // MustString returns default value if key value is empty.
  188. func (k *Key) MustString(defaultVal string) string {
  189. val := k.String()
  190. if len(val) == 0 {
  191. return defaultVal
  192. }
  193. return val
  194. }
  195. // MustBool always returns value without error,
  196. // it returns false if error occurs.
  197. func (k *Key) MustBool(defaultVal ...bool) bool {
  198. val, err := k.Bool()
  199. if len(defaultVal) > 0 && err != nil {
  200. return defaultVal[0]
  201. }
  202. return val
  203. }
  204. // MustFloat64 always returns value without error,
  205. // it returns 0.0 if error occurs.
  206. func (k *Key) MustFloat64(defaultVal ...float64) float64 {
  207. val, err := k.Float64()
  208. if len(defaultVal) > 0 && err != nil {
  209. return defaultVal[0]
  210. }
  211. return val
  212. }
  213. // MustInt always returns value without error,
  214. // it returns 0 if error occurs.
  215. func (k *Key) MustInt(defaultVal ...int) int {
  216. val, err := k.Int()
  217. if len(defaultVal) > 0 && err != nil {
  218. return defaultVal[0]
  219. }
  220. return val
  221. }
  222. // MustInt64 always returns value without error,
  223. // it returns 0 if error occurs.
  224. func (k *Key) MustInt64(defaultVal ...int64) int64 {
  225. val, err := k.Int64()
  226. if len(defaultVal) > 0 && err != nil {
  227. return defaultVal[0]
  228. }
  229. return val
  230. }
  231. // MustUint always returns value without error,
  232. // it returns 0 if error occurs.
  233. func (k *Key) MustUint(defaultVal ...uint) uint {
  234. val, err := k.Uint()
  235. if len(defaultVal) > 0 && err != nil {
  236. return defaultVal[0]
  237. }
  238. return val
  239. }
  240. // MustUint64 always returns value without error,
  241. // it returns 0 if error occurs.
  242. func (k *Key) MustUint64(defaultVal ...uint64) uint64 {
  243. val, err := k.Uint64()
  244. if len(defaultVal) > 0 && err != nil {
  245. return defaultVal[0]
  246. }
  247. return val
  248. }
  249. // MustDuration always returns value without error,
  250. // it returns zero value if error occurs.
  251. func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration {
  252. val, err := k.Duration()
  253. if len(defaultVal) > 0 && err != nil {
  254. return defaultVal[0]
  255. }
  256. return val
  257. }
  258. // MustTimeFormat always parses with given format and returns value without error,
  259. // it returns zero value if error occurs.
  260. func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time {
  261. val, err := k.TimeFormat(format)
  262. if len(defaultVal) > 0 && err != nil {
  263. return defaultVal[0]
  264. }
  265. return val
  266. }
  267. // MustTime always parses with RFC3339 format and returns value without error,
  268. // it returns zero value if error occurs.
  269. func (k *Key) MustTime(defaultVal ...time.Time) time.Time {
  270. return k.MustTimeFormat(time.RFC3339, defaultVal...)
  271. }
  272. // In always returns value without error,
  273. // it returns default value if error occurs or doesn't fit into candidates.
  274. func (k *Key) In(defaultVal string, candidates []string) string {
  275. val := k.String()
  276. for _, cand := range candidates {
  277. if val == cand {
  278. return val
  279. }
  280. }
  281. return defaultVal
  282. }
  283. // InFloat64 always returns value without error,
  284. // it returns default value if error occurs or doesn't fit into candidates.
  285. func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 {
  286. val := k.MustFloat64()
  287. for _, cand := range candidates {
  288. if val == cand {
  289. return val
  290. }
  291. }
  292. return defaultVal
  293. }
  294. // InInt always returns value without error,
  295. // it returns default value if error occurs or doesn't fit into candidates.
  296. func (k *Key) InInt(defaultVal int, candidates []int) int {
  297. val := k.MustInt()
  298. for _, cand := range candidates {
  299. if val == cand {
  300. return val
  301. }
  302. }
  303. return defaultVal
  304. }
  305. // InInt64 always returns value without error,
  306. // it returns default value if error occurs or doesn't fit into candidates.
  307. func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 {
  308. val := k.MustInt64()
  309. for _, cand := range candidates {
  310. if val == cand {
  311. return val
  312. }
  313. }
  314. return defaultVal
  315. }
  316. // InUint always returns value without error,
  317. // it returns default value if error occurs or doesn't fit into candidates.
  318. func (k *Key) InUint(defaultVal uint, candidates []uint) uint {
  319. val := k.MustUint()
  320. for _, cand := range candidates {
  321. if val == cand {
  322. return val
  323. }
  324. }
  325. return defaultVal
  326. }
  327. // InUint64 always returns value without error,
  328. // it returns default value if error occurs or doesn't fit into candidates.
  329. func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 {
  330. val := k.MustUint64()
  331. for _, cand := range candidates {
  332. if val == cand {
  333. return val
  334. }
  335. }
  336. return defaultVal
  337. }
  338. // InTimeFormat always parses with given format and returns value without error,
  339. // it returns default value if error occurs or doesn't fit into candidates.
  340. func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time {
  341. val := k.MustTimeFormat(format)
  342. for _, cand := range candidates {
  343. if val == cand {
  344. return val
  345. }
  346. }
  347. return defaultVal
  348. }
  349. // InTime always parses with RFC3339 format and returns value without error,
  350. // it returns default value if error occurs or doesn't fit into candidates.
  351. func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time {
  352. return k.InTimeFormat(time.RFC3339, defaultVal, candidates)
  353. }
  354. // RangeFloat64 checks if value is in given range inclusively,
  355. // and returns default value if it's not.
  356. func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 {
  357. val := k.MustFloat64()
  358. if val < min || val > max {
  359. return defaultVal
  360. }
  361. return val
  362. }
  363. // RangeInt checks if value is in given range inclusively,
  364. // and returns default value if it's not.
  365. func (k *Key) RangeInt(defaultVal, min, max int) int {
  366. val := k.MustInt()
  367. if val < min || val > max {
  368. return defaultVal
  369. }
  370. return val
  371. }
  372. // RangeInt64 checks if value is in given range inclusively,
  373. // and returns default value if it's not.
  374. func (k *Key) RangeInt64(defaultVal, min, max int64) int64 {
  375. val := k.MustInt64()
  376. if val < min || val > max {
  377. return defaultVal
  378. }
  379. return val
  380. }
  381. // RangeTimeFormat checks if value with given format is in given range inclusively,
  382. // and returns default value if it's not.
  383. func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time {
  384. val := k.MustTimeFormat(format)
  385. if val.Unix() < min.Unix() || val.Unix() > max.Unix() {
  386. return defaultVal
  387. }
  388. return val
  389. }
  390. // RangeTime checks if value with RFC3339 format is in given range inclusively,
  391. // and returns default value if it's not.
  392. func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time {
  393. return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max)
  394. }
  395. // Strings returns list of string devide by given delimiter.
  396. func (k *Key) Strings(delim string) []string {
  397. str := k.String()
  398. if len(str) == 0 {
  399. return []string{}
  400. }
  401. vals := strings.Split(str, delim)
  402. for i := range vals {
  403. vals[i] = strings.TrimSpace(vals[i])
  404. }
  405. return vals
  406. }
  407. // Float64s returns list of float64 devide by given delimiter.
  408. func (k *Key) Float64s(delim string) []float64 {
  409. strs := k.Strings(delim)
  410. vals := make([]float64, len(strs))
  411. for i := range strs {
  412. vals[i], _ = strconv.ParseFloat(strs[i], 64)
  413. }
  414. return vals
  415. }
  416. // Ints returns list of int devide by given delimiter.
  417. func (k *Key) Ints(delim string) []int {
  418. strs := k.Strings(delim)
  419. vals := make([]int, len(strs))
  420. for i := range strs {
  421. vals[i], _ = strconv.Atoi(strs[i])
  422. }
  423. return vals
  424. }
  425. // Int64s returns list of int64 devide by given delimiter.
  426. func (k *Key) Int64s(delim string) []int64 {
  427. strs := k.Strings(delim)
  428. vals := make([]int64, len(strs))
  429. for i := range strs {
  430. vals[i], _ = strconv.ParseInt(strs[i], 10, 64)
  431. }
  432. return vals
  433. }
  434. // Uints returns list of uint devide by given delimiter.
  435. func (k *Key) Uints(delim string) []uint {
  436. strs := k.Strings(delim)
  437. vals := make([]uint, len(strs))
  438. for i := range strs {
  439. u, _ := strconv.ParseUint(strs[i], 10, 64)
  440. vals[i] = uint(u)
  441. }
  442. return vals
  443. }
  444. // Uint64s returns list of uint64 devide by given delimiter.
  445. func (k *Key) Uint64s(delim string) []uint64 {
  446. strs := k.Strings(delim)
  447. vals := make([]uint64, len(strs))
  448. for i := range strs {
  449. vals[i], _ = strconv.ParseUint(strs[i], 10, 64)
  450. }
  451. return vals
  452. }
  453. // TimesFormat parses with given format and returns list of time.Time devide by given delimiter.
  454. func (k *Key) TimesFormat(format, delim string) []time.Time {
  455. strs := k.Strings(delim)
  456. vals := make([]time.Time, len(strs))
  457. for i := range strs {
  458. vals[i], _ = time.Parse(format, strs[i])
  459. }
  460. return vals
  461. }
  462. // Times parses with RFC3339 format and returns list of time.Time devide by given delimiter.
  463. func (k *Key) Times(delim string) []time.Time {
  464. return k.TimesFormat(time.RFC3339, delim)
  465. }
  466. // SetValue changes key value.
  467. func (k *Key) SetValue(v string) {
  468. k.value = v
  469. }
  470. // _________ __ .__
  471. // / _____/ ____ _____/ |_|__| ____ ____
  472. // \_____ \_/ __ \_/ ___\ __\ |/ _ \ / \
  473. // / \ ___/\ \___| | | ( <_> ) | \
  474. // /_______ /\___ >\___ >__| |__|\____/|___| /
  475. // \/ \/ \/ \/
  476. // Section represents a config section.
  477. type Section struct {
  478. f *File
  479. Comment string
  480. name string
  481. keys map[string]*Key
  482. keyList []string
  483. keysHash map[string]string
  484. }
  485. func newSection(f *File, name string) *Section {
  486. return &Section{f, "", name, make(map[string]*Key), make([]string, 0, 10), make(map[string]string)}
  487. }
  488. // Name returns name of Section.
  489. func (s *Section) Name() string {
  490. return s.name
  491. }
  492. // NewKey creates a new key to given section.
  493. func (s *Section) NewKey(name, val string) (*Key, error) {
  494. if len(name) == 0 {
  495. return nil, errors.New("error creating new key: empty key name")
  496. }
  497. if s.f.BlockMode {
  498. s.f.lock.Lock()
  499. defer s.f.lock.Unlock()
  500. }
  501. if inSlice(name, s.keyList) {
  502. s.keys[name].value = val
  503. return s.keys[name], nil
  504. }
  505. s.keyList = append(s.keyList, name)
  506. s.keys[name] = &Key{s, "", name, val, false}
  507. s.keysHash[name] = val
  508. return s.keys[name], nil
  509. }
  510. // GetKey returns key in section by given name.
  511. func (s *Section) GetKey(name string) (*Key, error) {
  512. // FIXME: change to section level lock?
  513. if s.f.BlockMode {
  514. s.f.lock.RLock()
  515. }
  516. key := s.keys[name]
  517. if s.f.BlockMode {
  518. s.f.lock.RUnlock()
  519. }
  520. if key == nil {
  521. // Check if it is a child-section.
  522. sname := s.name
  523. for {
  524. if i := strings.LastIndex(sname, "."); i > -1 {
  525. sname = sname[:i]
  526. sec, err := s.f.GetSection(sname)
  527. if err != nil {
  528. continue
  529. }
  530. return sec.GetKey(name)
  531. } else {
  532. break
  533. }
  534. }
  535. return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name)
  536. }
  537. return key, nil
  538. }
  539. // Key assumes named Key exists in section and returns a zero-value when not.
  540. func (s *Section) Key(name string) *Key {
  541. key, err := s.GetKey(name)
  542. if err != nil {
  543. // It's OK here because the only possible error is empty key name,
  544. // but if it's empty, this piece of code won't be executed.
  545. key, _ = s.NewKey(name, "")
  546. return key
  547. }
  548. return key
  549. }
  550. // Keys returns list of keys of section.
  551. func (s *Section) Keys() []*Key {
  552. keys := make([]*Key, len(s.keyList))
  553. for i := range s.keyList {
  554. keys[i] = s.Key(s.keyList[i])
  555. }
  556. return keys
  557. }
  558. // KeyStrings returns list of key names of section.
  559. func (s *Section) KeyStrings() []string {
  560. list := make([]string, len(s.keyList))
  561. copy(list, s.keyList)
  562. return list
  563. }
  564. // KeysHash returns keys hash consisting of names and values.
  565. func (s *Section) KeysHash() map[string]string {
  566. if s.f.BlockMode {
  567. s.f.lock.RLock()
  568. defer s.f.lock.RUnlock()
  569. }
  570. hash := map[string]string{}
  571. for key, value := range s.keysHash {
  572. hash[key] = value
  573. }
  574. return hash
  575. }
  576. // DeleteKey deletes a key from section.
  577. func (s *Section) DeleteKey(name string) {
  578. if s.f.BlockMode {
  579. s.f.lock.Lock()
  580. defer s.f.lock.Unlock()
  581. }
  582. for i, k := range s.keyList {
  583. if k == name {
  584. s.keyList = append(s.keyList[:i], s.keyList[i+1:]...)
  585. delete(s.keys, name)
  586. return
  587. }
  588. }
  589. }
  590. // ___________.__.__
  591. // \_ _____/|__| | ____
  592. // | __) | | | _/ __ \
  593. // | \ | | |_\ ___/
  594. // \___ / |__|____/\___ >
  595. // \/ \/
  596. // File represents a combination of a or more INI file(s) in memory.
  597. type File struct {
  598. // Should make things safe, but sometimes doesn't matter.
  599. BlockMode bool
  600. // Make sure data is safe in multiple goroutines.
  601. lock sync.RWMutex
  602. // Allow combination of multiple data sources.
  603. dataSources []dataSource
  604. // Actual data is stored here.
  605. sections map[string]*Section
  606. // To keep data in order.
  607. sectionList []string
  608. NameMapper
  609. }
  610. // newFile initializes File object with given data sources.
  611. func newFile(dataSources []dataSource) *File {
  612. return &File{
  613. BlockMode: true,
  614. dataSources: dataSources,
  615. sections: make(map[string]*Section),
  616. sectionList: make([]string, 0, 10),
  617. }
  618. }
  619. func parseDataSource(source interface{}) (dataSource, error) {
  620. switch s := source.(type) {
  621. case string:
  622. return sourceFile{s}, nil
  623. case []byte:
  624. return &sourceData{s}, nil
  625. default:
  626. return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s)
  627. }
  628. }
  629. // Load loads and parses from INI data sources.
  630. // Arguments can be mixed of file name with string type, or raw data in []byte.
  631. func Load(source interface{}, others ...interface{}) (_ *File, err error) {
  632. sources := make([]dataSource, len(others)+1)
  633. sources[0], err = parseDataSource(source)
  634. if err != nil {
  635. return nil, err
  636. }
  637. for i := range others {
  638. sources[i+1], err = parseDataSource(others[i])
  639. if err != nil {
  640. return nil, err
  641. }
  642. }
  643. f := newFile(sources)
  644. return f, f.Reload()
  645. }
  646. // Empty returns an empty file object.
  647. func Empty() *File {
  648. // Ignore error here, we sure our data is good.
  649. f, _ := Load([]byte(""))
  650. return f
  651. }
  652. // NewSection creates a new section.
  653. func (f *File) NewSection(name string) (*Section, error) {
  654. if len(name) == 0 {
  655. return nil, errors.New("error creating new section: empty section name")
  656. }
  657. if f.BlockMode {
  658. f.lock.Lock()
  659. defer f.lock.Unlock()
  660. }
  661. if inSlice(name, f.sectionList) {
  662. return f.sections[name], nil
  663. }
  664. f.sectionList = append(f.sectionList, name)
  665. f.sections[name] = newSection(f, name)
  666. return f.sections[name], nil
  667. }
  668. // NewSections creates a list of sections.
  669. func (f *File) NewSections(names ...string) (err error) {
  670. for _, name := range names {
  671. if _, err = f.NewSection(name); err != nil {
  672. return err
  673. }
  674. }
  675. return nil
  676. }
  677. // GetSection returns section by given name.
  678. func (f *File) GetSection(name string) (*Section, error) {
  679. if len(name) == 0 {
  680. name = DEFAULT_SECTION
  681. }
  682. if f.BlockMode {
  683. f.lock.RLock()
  684. defer f.lock.RUnlock()
  685. }
  686. sec := f.sections[name]
  687. if sec == nil {
  688. return nil, fmt.Errorf("error when getting section: section '%s' not exists", name)
  689. }
  690. return sec, nil
  691. }
  692. // Section assumes named section exists and returns a zero-value when not.
  693. func (f *File) Section(name string) *Section {
  694. sec, err := f.GetSection(name)
  695. if err != nil {
  696. // Note: It's OK here because the only possible error is empty section name,
  697. // but if it's empty, this piece of code won't be executed.
  698. sec, _ = f.NewSection(name)
  699. return sec
  700. }
  701. return sec
  702. }
  703. // Section returns list of Section.
  704. func (f *File) Sections() []*Section {
  705. sections := make([]*Section, len(f.sectionList))
  706. for i := range f.sectionList {
  707. sections[i] = f.Section(f.sectionList[i])
  708. }
  709. return sections
  710. }
  711. // SectionStrings returns list of section names.
  712. func (f *File) SectionStrings() []string {
  713. list := make([]string, len(f.sectionList))
  714. copy(list, f.sectionList)
  715. return list
  716. }
  717. // DeleteSection deletes a section.
  718. func (f *File) DeleteSection(name string) {
  719. if f.BlockMode {
  720. f.lock.Lock()
  721. defer f.lock.Unlock()
  722. }
  723. if len(name) == 0 {
  724. name = DEFAULT_SECTION
  725. }
  726. for i, s := range f.sectionList {
  727. if s == name {
  728. f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...)
  729. delete(f.sections, name)
  730. return
  731. }
  732. }
  733. }
  734. func cutComment(str string) string {
  735. i := strings.Index(str, "#")
  736. if i == -1 {
  737. return str
  738. }
  739. return str[:i]
  740. }
  741. func checkMultipleLines(buf *bufio.Reader, line, val, valQuote string) (string, error) {
  742. isEnd := false
  743. for {
  744. next, err := buf.ReadString('\n')
  745. if err != nil {
  746. if err != io.EOF {
  747. return "", err
  748. }
  749. isEnd = true
  750. }
  751. pos := strings.LastIndex(next, valQuote)
  752. if pos > -1 {
  753. val += next[:pos]
  754. break
  755. }
  756. val += next
  757. if isEnd {
  758. return "", fmt.Errorf("error parsing line: missing closing key quote from '%s' to '%s'", line, next)
  759. }
  760. }
  761. return val, nil
  762. }
  763. func checkContinuationLines(buf *bufio.Reader, val string) (string, bool, error) {
  764. isEnd := false
  765. for {
  766. valLen := len(val)
  767. if valLen == 0 || val[valLen-1] != '\\' {
  768. break
  769. }
  770. val = val[:valLen-1]
  771. next, err := buf.ReadString('\n')
  772. if err != nil {
  773. if err != io.EOF {
  774. return "", isEnd, err
  775. }
  776. isEnd = true
  777. }
  778. next = strings.TrimSpace(next)
  779. if len(next) == 0 {
  780. break
  781. }
  782. val += next
  783. }
  784. return val, isEnd, nil
  785. }
  786. // parse parses data through an io.Reader.
  787. func (f *File) parse(reader io.Reader) error {
  788. buf := bufio.NewReader(reader)
  789. // Handle BOM-UTF8.
  790. // http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding
  791. mask, err := buf.Peek(3)
  792. if err == nil && len(mask) >= 3 && mask[0] == 239 && mask[1] == 187 && mask[2] == 191 {
  793. buf.Read(mask)
  794. }
  795. count := 1
  796. comments := ""
  797. isEnd := false
  798. section, err := f.NewSection(DEFAULT_SECTION)
  799. if err != nil {
  800. return err
  801. }
  802. for {
  803. line, err := buf.ReadString('\n')
  804. line = strings.TrimSpace(line)
  805. length := len(line)
  806. // Check error and ignore io.EOF just for a moment.
  807. if err != nil {
  808. if err != io.EOF {
  809. return fmt.Errorf("error reading next line: %v", err)
  810. }
  811. // The last line of file could be an empty line.
  812. if length == 0 {
  813. break
  814. }
  815. isEnd = true
  816. }
  817. // Skip empty lines.
  818. if length == 0 {
  819. continue
  820. }
  821. switch {
  822. case line[0] == '#' || line[0] == ';': // Comments.
  823. if len(comments) == 0 {
  824. comments = line
  825. } else {
  826. comments += LineBreak + line
  827. }
  828. continue
  829. case line[0] == '[' && line[length-1] == ']': // New sction.
  830. section, err = f.NewSection(strings.TrimSpace(line[1 : length-1]))
  831. if err != nil {
  832. return err
  833. }
  834. if len(comments) > 0 {
  835. section.Comment = comments
  836. comments = ""
  837. }
  838. // Reset counter.
  839. count = 1
  840. continue
  841. }
  842. // Other possibilities.
  843. var (
  844. i int
  845. keyQuote string
  846. kname string
  847. valQuote string
  848. val string
  849. )
  850. // Key name surrounded by quotes.
  851. if line[0] == '"' {
  852. if length > 6 && line[0:3] == `"""` {
  853. keyQuote = `"""`
  854. } else {
  855. keyQuote = `"`
  856. }
  857. } else if line[0] == '`' {
  858. keyQuote = "`"
  859. }
  860. if len(keyQuote) > 0 {
  861. qLen := len(keyQuote)
  862. pos := strings.Index(line[qLen:], keyQuote)
  863. if pos == -1 {
  864. return fmt.Errorf("error parsing line: missing closing key quote: %s", line)
  865. }
  866. pos = pos + qLen
  867. i = strings.IndexAny(line[pos:], "=:")
  868. if i < 0 {
  869. return fmt.Errorf("error parsing line: key-value delimiter not found: %s", line)
  870. } else if i == pos {
  871. return fmt.Errorf("error parsing line: key is empty: %s", line)
  872. }
  873. i = i + pos
  874. kname = line[qLen:pos] // Just keep spaces inside quotes.
  875. } else {
  876. i = strings.IndexAny(line, "=:")
  877. if i < 0 {
  878. return fmt.Errorf("error parsing line: key-value delimiter not found: %s", line)
  879. } else if i == 0 {
  880. return fmt.Errorf("error parsing line: key is empty: %s", line)
  881. }
  882. kname = strings.TrimSpace(line[0:i])
  883. }
  884. isAutoIncr := false
  885. // Auto increment.
  886. if kname == "-" {
  887. isAutoIncr = true
  888. kname = "#" + fmt.Sprint(count)
  889. count++
  890. }
  891. lineRight := strings.TrimSpace(line[i+1:])
  892. lineRightLength := len(lineRight)
  893. firstChar := ""
  894. if lineRightLength >= 2 {
  895. firstChar = lineRight[0:1]
  896. }
  897. if firstChar == "`" {
  898. valQuote = "`"
  899. } else if firstChar == `"` {
  900. if lineRightLength >= 3 && lineRight[0:3] == `"""` {
  901. valQuote = `"""`
  902. } else {
  903. valQuote = `"`
  904. }
  905. } else if firstChar == `'` {
  906. valQuote = `'`
  907. }
  908. if len(valQuote) > 0 {
  909. qLen := len(valQuote)
  910. pos := strings.LastIndex(lineRight[qLen:], valQuote)
  911. // For multiple-line value check.
  912. if pos == -1 {
  913. if valQuote == `"` || valQuote == `'` {
  914. return fmt.Errorf("error parsing line: single quote does not allow multiple-line value: %s", line)
  915. }
  916. val = lineRight[qLen:] + "\n"
  917. val, err = checkMultipleLines(buf, line, val, valQuote)
  918. if err != nil {
  919. return err
  920. }
  921. } else {
  922. val = lineRight[qLen : pos+qLen]
  923. }
  924. } else {
  925. val = strings.TrimSpace(cutComment(lineRight))
  926. val, isEnd, err = checkContinuationLines(buf, val)
  927. if err != nil {
  928. return err
  929. }
  930. }
  931. k, err := section.NewKey(kname, val)
  932. if err != nil {
  933. return err
  934. }
  935. k.isAutoIncr = isAutoIncr
  936. if len(comments) > 0 {
  937. k.Comment = comments
  938. comments = ""
  939. }
  940. if isEnd {
  941. break
  942. }
  943. }
  944. return nil
  945. }
  946. func (f *File) reload(s dataSource) error {
  947. r, err := s.ReadCloser()
  948. if err != nil {
  949. return err
  950. }
  951. defer r.Close()
  952. return f.parse(r)
  953. }
  954. // Reload reloads and parses all data sources.
  955. func (f *File) Reload() (err error) {
  956. for _, s := range f.dataSources {
  957. if err = f.reload(s); err != nil {
  958. return err
  959. }
  960. }
  961. return nil
  962. }
  963. // Append appends one or more data sources and reloads automatically.
  964. func (f *File) Append(source interface{}, others ...interface{}) error {
  965. ds, err := parseDataSource(source)
  966. if err != nil {
  967. return err
  968. }
  969. f.dataSources = append(f.dataSources, ds)
  970. for _, s := range others {
  971. ds, err = parseDataSource(s)
  972. if err != nil {
  973. return err
  974. }
  975. f.dataSources = append(f.dataSources, ds)
  976. }
  977. return f.Reload()
  978. }
  979. // WriteToIndent writes file content into io.Writer with given value indention.
  980. func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
  981. equalSign := "="
  982. if PrettyFormat {
  983. equalSign = " = "
  984. }
  985. // Use buffer to make sure target is safe until finish encoding.
  986. buf := bytes.NewBuffer(nil)
  987. for i, sname := range f.sectionList {
  988. sec := f.Section(sname)
  989. if len(sec.Comment) > 0 {
  990. if sec.Comment[0] != '#' && sec.Comment[0] != ';' {
  991. sec.Comment = "; " + sec.Comment
  992. }
  993. if _, err = buf.WriteString(sec.Comment + LineBreak); err != nil {
  994. return 0, err
  995. }
  996. }
  997. if i > 0 {
  998. if _, err = buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
  999. return 0, err
  1000. }
  1001. } else {
  1002. // Write nothing if default section is empty.
  1003. if len(sec.keyList) == 0 {
  1004. continue
  1005. }
  1006. }
  1007. for _, kname := range sec.keyList {
  1008. key := sec.Key(kname)
  1009. if len(key.Comment) > 0 {
  1010. if len(indent) > 0 && sname != DEFAULT_SECTION {
  1011. buf.WriteString(indent)
  1012. }
  1013. if key.Comment[0] != '#' && key.Comment[0] != ';' {
  1014. key.Comment = "; " + key.Comment
  1015. }
  1016. if _, err = buf.WriteString(key.Comment + LineBreak); err != nil {
  1017. return 0, err
  1018. }
  1019. }
  1020. if len(indent) > 0 && sname != DEFAULT_SECTION {
  1021. buf.WriteString(indent)
  1022. }
  1023. switch {
  1024. case key.isAutoIncr:
  1025. kname = "-"
  1026. case strings.Contains(kname, "`") || strings.Contains(kname, `"`):
  1027. kname = `"""` + kname + `"""`
  1028. case strings.Contains(kname, `=`) || strings.Contains(kname, `:`):
  1029. kname = "`" + kname + "`"
  1030. }
  1031. val := key.value
  1032. // In case key value contains "\n", "`" or "\"".
  1033. if strings.Contains(val, "\n") || strings.Contains(val, "`") || strings.Contains(val, `"`) ||
  1034. strings.Contains(val, "#") {
  1035. val = `"""` + val + `"""`
  1036. }
  1037. if _, err = buf.WriteString(kname + equalSign + val + LineBreak); err != nil {
  1038. return 0, err
  1039. }
  1040. }
  1041. // Put a line between sections.
  1042. if _, err = buf.WriteString(LineBreak); err != nil {
  1043. return 0, err
  1044. }
  1045. }
  1046. return buf.WriteTo(w)
  1047. }
  1048. // WriteTo writes file content into io.Writer.
  1049. func (f *File) WriteTo(w io.Writer) (int64, error) {
  1050. return f.WriteToIndent(w, "")
  1051. }
  1052. // SaveToIndent writes content to file system with given value indention.
  1053. func (f *File) SaveToIndent(filename, indent string) error {
  1054. // Note: Because we are truncating with os.Create,
  1055. // so it's safer to save to a temporary file location and rename afte done.
  1056. tmpPath := filename + "." + strconv.Itoa(time.Now().Nanosecond()) + ".tmp"
  1057. defer os.Remove(tmpPath)
  1058. fw, err := os.Create(tmpPath)
  1059. if err != nil {
  1060. return err
  1061. }
  1062. if _, err = f.WriteToIndent(fw, indent); err != nil {
  1063. fw.Close()
  1064. return err
  1065. }
  1066. fw.Close()
  1067. // Remove old file and rename the new one.
  1068. os.Remove(filename)
  1069. return os.Rename(tmpPath, filename)
  1070. }
  1071. // SaveTo writes content to file system.
  1072. func (f *File) SaveTo(filename string) error {
  1073. return f.SaveToIndent(filename, "")
  1074. }