Skip to content
Snippets Groups Projects
path_traversal.go 2.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Manuel Kieweg's avatar
    Manuel Kieweg committed
    package util
    
    import (
    	"fmt"
    	"github.com/openconfig/goyang/pkg/yang"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"github.com/openconfig/ygot/ytypes"
    
    	log "github.com/sirupsen/logrus"
    	"strings"
    
    const DELIM = "/"
    
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    type PathElement struct {
    	Children []*PathElement
    	Name     string
    }
    
    
    func (p *PathElement) Print() {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	printPE(0, p)
    }
    
    func printPE(indent int, pe *PathElement) {
    	for i := 0; i < indent; i++ {
    		fmt.Print("    ")
    	}
    	fmt.Println(pe.Name)
    	if len(pe.Children) > 0 {
    
    		for _, p := range pe.Children {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			printPE(indent+1, p)
    		}
    	}
    }
    
    func NewPaths() Paths {
    	return make(map[string]*PathElement)
    }
    
    type Paths map[string]*PathElement
    
    
    func processEntry(e *yang.Entry) *PathElement {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	if e.Dir != nil {
    		elem := &PathElement{
    			Children: make([]*PathElement, len(e.Dir)),
    			Name:     e.Name,
    		}
    		i := 0
    
    		for _, v := range e.Dir {
    			elem.Children[i] = processEntry(v)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			i++
    		}
    		return elem
    	}
    	leaf := &PathElement{
    
    		Name: e.Name,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	}
    	return leaf
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    }
    
    func (p Paths) ParseSchema(schema *ytypes.Schema, root string) error {
    	tree := schema.SchemaTree
    
    	for k, v := range tree {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		if v.Parent != nil {
    			if v.Parent.Name == root {
    
    				path := processEntry(v)
    				p[k] = path
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			}
    		}
    	}
    	return nil
    
    }
    
    func (p Paths) StringBuilder() []string {
    	paths := make([]string, 0)
    	ch := make(chan string)
    	stop := make(chan bool)
    	val := make(chan []string)
    	go appendix(ch, stop, val)
    	for _, v := range p {
    		var b strings.Builder
    		stringBuilder(ch, &b, v)
    	}
    	stop <- true
    	paths = <-val
    	return paths
    }
    
    func appendix(c chan string, stop chan bool,p chan []string) {
    	paths := make([]string, 0)
    	var sig bool
    	for {
    		select {
    		case path := <-c:
    			paths = append(paths, path)
    			log.Debug(path)
    		case sig = <-stop:
    			log.Debug("Signal received: %v", sig)
    
    		}
    		if sig {break}
    	}
    	p <- paths
    }
    
    func stringBuilder(ch chan string, b *strings.Builder, v *PathElement) {
    	if b.Len() == 0 {
    
    		b.WriteString(DELIM)
    
    	}
    	b.WriteString(v.Name)
    	if v.Children != nil {
    		b.WriteString(DELIM)
    		for _, c := range v.Children {
    			var b_cpy strings.Builder
    			b_cpy.WriteString(b.String())
    			stringBuilder(ch, &b_cpy, c)
    		}
    	} else {
    		log.Debug("leaf")
    		ch <- b.String()
    	}
    }