go语言解析INI文件

package main
  
 import (
    "bufio"
    "bytes"
    "io"
    "os"
    "unicode"
 )
  
 const (
    stat_none = iota
    stat_group
    stat_key
    stat_value
    stat_comment
 )
  
 type Attr struct {
    Name    string
    Value   string
    Comment string
    next    *Attr
 }
  
 type Element struct {
    Element string
    Attr    *Attr
    next    *Element
 }
  
 type Decoder struct {
    state int
    b     byte
    t     bytes.Buffer
    r     io.ByteReader
    err   error
    m     *Element
    n     string
 }
  
 func (d *Decoder) getAttr(m *Element, e string) string {
    for n := m.Attr; nil != n; n = n.next {
        if e == n.Name {
            return n.Value
        }
    }
    return ""
 }
  
 func (d *Decoder) GetElement(e string, a string) string {
    for n := d.m; nil != n; n = n.next {
        if e == n.Element {
            return d.getAttr(n, a)
        }
    }
    return ""
 }
  
 func (d *Decoder) newAttrNextComment(value string) {
    d.m.Attr.Comment = value
    println(value)
 }
  
 func (d *Decoder) newAttrNext(name string, value string) {
    attr := new(Attr)
    attr.Name = name
    attr.Value = value
    if nil == d.m.Attr {
        attr.next = nil
    } else {
        attr.next = d.m.Attr
    }
    d.m.Attr = attr
 }
  
 func (d *Decoder) newElement(name string) {
    element := new(Element)
    element.Element = name
    element.Attr = nil
    if nil == d.m {
        element.next = nil
    } else {
        element.next = d.m
    }
    d.m = element
 }
  
 func (d *Decoder) switchToMap() {
    for {
        d.b, d.err = d.r.ReadByte()
        if d.err != nil {
            break
        }
        switch d.state {
        case stat_none:
            if d.b == '[' {
                d.state = stat_group
            } else if d.b == ';' {
                d.state = stat_comment
            } else if !unicode.IsSpace(rune(d.b)) {
                d.state = stat_key
                d.t.WriteByte(byte(d.b))
            }
            break
        case stat_group:
            if d.b == ']' {
                d.state = stat_none
                d.newElement(d.t.String())
                d.t.Reset()
            } else if !unicode.IsSpace(rune(d.b)) {
                d.t.WriteByte(byte(d.b))
            }
            break
        case stat_key:
            if d.b == '=' {
                d.state = stat_value
                d.n = d.t.String()
                d.t.Reset()
            } else if !unicode.IsSpace(rune(d.b)) {
                d.t.WriteByte(byte(d.b))
            }
            break
        case stat_value:
            if !unicode.IsSpace(rune(d.b)) {
                d.t.WriteByte(byte(d.b))
            } else {
                d.state = stat_none
                d.newAttrNext(d.n, d.t.String())
                d.t.Reset()
            }
            break
        case stat_comment:
            if !unicode.IsSpace(rune(d.b)) {
                d.t.WriteByte(byte(d.b))
            } else {
                d.state = stat_none
                d.newAttrNextComment(d.t.String())
                d.t.Reset()
            }
            break
        default:
            d.state = stat_none
            break
        }
    }
 }
  
 func (d *Decoder) switchToReader(r io.Reader) {
    if rb, ok := r.(io.ByteReader); ok {
        d.r = rb
    } else {
        d.r = bufio.NewReader(r)
    }
    d.switchToMap()
 }
  
 func NewDecoder(r io.Reader) *Decoder {
    d := &Decoder{}
    d.switchToReader(r)
    return d
 }
  
 func main() {
    xmlFile, err := os.Open("hh.ini")
    if nil != err {
        return
    }
    defer xmlFile.Close()
    d := NewDecoder(xmlFile)
    println(d.GetElement("aaaa", "ac"))
 }

  

posted on   RTFSC  阅读(1100)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
< 2012年10月 >
30 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 1 2 3
4 5 6 7 8 9 10

导航

统计

点击右上角即可分享
微信分享提示