From a9b7487378ff40fec9e431ca5813eda08b716d45 Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Thu, 21 Nov 2024 09:02:37 +0100 Subject: [PATCH] slist.go add because it is required by apiguard. It could be remove in the future --- slist.go | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 slist.go diff --git a/slist.go b/slist.go new file mode 100644 index 0000000..1a49996 --- /dev/null +++ b/slist.go @@ -0,0 +1,267 @@ +// simple-list project slist.go +package slist + +import ( + "fmt" + + "portale-stac.it/packages/collections" +) + +type SNode struct { + data interface{} + next *SNode +} + +func (self *SNode) Data() interface{} { + return self.data +} + +type SList struct { + count uint32 + first *SNode + last *SNode +} + +func NewSimpleList() (list *SList) { + list = &SList{0, nil, nil} + return +} + +func (self *SList) Len() uint32 { + return self.count +} + +func (self *SList) Empty() bool { + return self.count == 0 +} + +func (self *SList) PushFront(data interface{}) *SNode { + self.first = &SNode{data, self.first} + if self.last == nil { + self.last = self.first + } + self.count++ + return self.first +} + +func (self *SList) PushBack(data interface{}) (node *SNode) { + node = &SNode{data, nil} + if self.last != nil { + self.last.next = node + } + self.last = node + if self.first == nil { + self.first = node + } + self.count++ + return +} + +func (self *SList) FirstNode() (node *SNode, err error) { + if self.first != nil { + node = self.first + } else { + err = errorListEmpty() + } + return +} + +func (self *SList) First() (data interface{}, err error) { + node, err := self.FirstNode() + if err == nil { + data = node.data + } else { + err = errorListEmpty() + } + return +} + +func (self *SList) LastNode() (node *SNode, err error) { + if self.last != nil { + node = self.last + } else { + err = errorListEmpty() + } + return +} + +func (self *SList) Last() (data interface{}, err error) { + node, err := self.LastNode() + if err == nil { + data = node.data + } + return +} + +func (self *SList) NodeAt(index uint32) (node *SNode, err error) { + if self.count == 0 { + err = errorListEmpty() + } else if index > self.count { + err = errorOutOfRange() + } else if index == self.count-1 { + node = self.last + } else { + current := self.first + for pos := uint32(0); pos < index; pos++ { + current = current.next + } + node = current + } + return +} + +func (self *SList) At(index uint32) (data interface{}, err error) { + node, err := self.NodeAt(index) + if err == nil { + data = node.data + } + return +} + +func (self *SList) Insert(index uint32, data interface{}) *SNode { + var prev *SNode + + prev = nil + current := self.first + for pos := uint32(0); current != nil && pos < index; pos++ { + prev = current + current = current.next + } + + node := &SNode{data, current} + + if prev != nil { + prev.next = node + } + + if self.first == current { + self.first = node + } + if node.next == nil { + self.last = node + } + self.count++ + return node +} + +func (self *SList) PushBackStringArray(items []string) { + for _, v := range items { + self.PushBack(v) + } +} + +type TraverseOperator func(index uint32, elem interface{}, userData interface{}) (err error) + +func (self *SList) Traverse(op TraverseOperator, user_data interface{}) (err error) { + index := uint32(0) + for current := self.first; current != nil; current = current.next { + err = op(index, current.data, user_data) + if err != nil { + break + } + index++ + } + return +} + +func (self *SList) Traverse2(observer collections.Observer, abortOnError bool) (err error) { + index := uint32(0) + for current := self.first; current != nil; current = current.next { + err = observer.Observe(current, index) + if err != nil && abortOnError { + break + } + index++ + } + return +} + +type EqualFunc func(current, target any) bool + +func (self *SList) FindFirst(eqFunc EqualFunc, targetData any) (targetNode *SNode) { + for current := self.first; current != nil && targetNode == nil; current = current.next { + if eqFunc(current.data, targetData) { + targetNode = current + } + } + return +} + +func (self *SList) FindNext(eqFunc EqualFunc, startNode *SNode) (targetNode *SNode) { + if startNode != nil { + for current := startNode.next; current != nil && targetNode == nil; current = current.next { + if eqFunc(current.data, startNode.Data()) { + targetNode = current + } + } + } + return +} + +type DataFeeder func(user_data interface{}) interface{} +type NodeObserver func(node *SNode, index uint32, userData interface{}) + +func (self *SList) FeedTail(feeder DataFeeder, feederUserData interface{}, observer NodeObserver, observerUserData interface{}) (count uint32) { + count = 0 + for item := feeder(feederUserData); item != nil; item = feeder(feederUserData) { + // fmt.Println("Item", count, item) + node := self.PushBack(item) + if observer != nil { + observer(node, count, observerUserData) + } + count++ + } + return +} + +func (self *SList) FeedTail2(feeder collections.Feeder, observer collections.Observer, abortOnError bool) (count uint32, err error) { + count = 0 + // item := feeder.Next() + for item, err1 := feeder.Next(); item != nil; item, err1 = feeder.Next() { + if err1 != nil { + if err == nil { + err = err1 + } + if abortOnError { + break + } + } + // fmt.Println("Item", count, item) + node := self.PushBack(item) + if observer != nil { + observer.Observe(node, count) + } + count++ + } + return +} + +// func (self *SList) FeedTail2(feeder collections.Feeder, observer NodeObserver, observerUserData interface{}, abortOnError bool) (count uint32, err error) { +// count = 0 +// // item := feeder.Next() +// for item, err1 := feeder.Next(); item != nil; item, err1 = feeder.Next() { +// if err1 != nil { +// if err == nil { +// err = err1 +// } +// if abortOnError { +// break +// } +// } +// // fmt.Println("Item", count, item) +// node := self.PushBack(item) +// if observer != nil { +// observer(node, count, observerUserData) +// } +// count++ +// } +// return +// } + +func errorListEmpty() error { + return fmt.Errorf("List is empty") +} + +func errorOutOfRange() error { + return fmt.Errorf("Out of range") +}