diff --git a/event.gui.pb.go b/event.gui.pb.go new file mode 100644 index 0000000..ac080d4 --- /dev/null +++ b/event.gui.pb.go @@ -0,0 +1,250 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package main + +import ( + "time" + + "github.com/google/uuid" + "go.wit.com/gui" + "go.wit.com/lib/protobuf/guipb" + "go.wit.com/log" + "google.golang.org/protobuf/proto" + anypb "google.golang.org/protobuf/types/known/anypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +// START GUI + +func (x *Events) NewTable(title string) *EventsTable { + t := new(EventsTable) + t.x = x + pb := new(guipb.Table) + pb.Title = title + t.pb = pb + return t +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *EventsTable) AddStringFunc(title string, f func(*Event) string) *EventAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(EventAnyFunc) + sf.title = title + sf.f = func(x *Event) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_STRING + + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *EventsTable) AddButtonFunc(title string, f func(*Event) string) *EventAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(EventAnyFunc) + sf.title = title + sf.f = func(x *Event) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_STRING + sf.attr.Click = true + + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *EventsTable) AddIntFunc(title string, f func(*Event) int) *EventAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(EventAnyFunc) + sf.title = title + sf.f = func(x *Event) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_INT + + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *EventsTable) AddTimeFunc(title string, f func(*Event) time.Time) *EventAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(EventAnyFunc) + sf.title = title + sf.f = func(x *Event) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_TIME + + // t.timeFuncs = append(t.timeFuncs, sf) + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +func (sf *EventAnyFunc) SetTitle(title string) { + sf.title = title +} + +func (mt *EventsTable) SetParent(p *gui.Node) { + mt.parent = p +} + +func (mt *EventsTable) ShowTable() { + // log.Info("ShowTable() SENDING TO GUI") + mt.MakeTable() + mt.parent.ShowTable(mt.pb) +} + +type EventAnyFunc struct { + title string + f func(*Event) any + Custom func(*Event) + Width int + attr *guipb.ColAttr +} + +type EventsTable struct { + pb *guipb.Table + parent *gui.Node + x *Events + hostnames []string + anyFuncs []*EventAnyFunc + CustomFunc func(*Event) +} + +func (mt *EventsTable) doAnyFuncNew(sf *EventAnyFunc) bool { + r := new(guipb.AnyCol) + r.Header = new(guipb.Widget) + r.Header.Name = sf.title + r.Attr = proto.Clone(sf.attr).(*guipb.ColAttr) + + for m := range mt.x.IterAll() { + t := sf.f(m) + switch r.Attr.Type { + case guipb.ColAttr_STRING: + // anyProto, err := anypb.New(tsProto) + stringValue := wrapperspb.String(t.(string)) + anyProto, err := anypb.New(stringValue) + _ = err // do something with err someday (?) + r.Vals = append(r.Vals, anyProto) + // return col.Vals[row] true + case guipb.ColAttr_INT: + var finalInt int + finalInt = t.(int) + intVal := wrapperspb.Int32(int32(finalInt)) + anyProto, _ := anypb.New(intVal) + r.Vals = append(r.Vals, anyProto) + case guipb.ColAttr_DURATION: + case guipb.ColAttr_TIME: + var goTime time.Time + goTime = t.(time.Time) + tsProto := timestamppb.New(goTime) + anyProto, err := anypb.New(tsProto) + _ = err // do something with err someday (?) + r.Vals = append(r.Vals, anyProto) + default: + log.Info("cell unhandled type", r.Attr.Type) + } + // cellTime := r.Vals[row] + // s := shell.FormatDuration(time.Since(cellTime.AsTime())) + } + + mt.pb.AnyCols = append(mt.pb.AnyCols, r) + return true +} + +func (mt *EventsTable) MakeTable() { + for _, sf := range mt.anyFuncs { + mt.doAnyFuncNew(sf) + } +} + +func (t *EventsTable) AddHostname() *EventAnyFunc { + sf := t.AddStringFunc("Hostname", func(m *Event) string { + return m.Hostname + }) + return sf +} + +func (t *EventsTable) AddLocalPort() *EventAnyFunc { + custf := t.AddIntFunc("LocalPort", func(m *Event) int { + return int(m.LocalPort) + }) + return custf +} +func (mt *EventsTable) NewUuid() { + mt.pb.Uuid = uuid.New().String() +} + +// START TABLE UPDATE (doesn't work yet) + +func (mt *EventsTable) dumpStringFunc(name string) { + for i, r := range mt.pb.StringCols { + // log.Info("could use", i, r.Header.Name, "for name =", name) + if r.Header.Name == name { + log.Info("dump Strings row", i, r.Header.Name, r.Vals) + break + } + } +} + +func (mt *EventsTable) Delete() { + if mt == nil { + log.Info("mt == nil table already deleted") + return + } + // log.Info("table Delete here") + mt.parent.DeleteTable(mt.pb) +} + +func (mt *EventsTable) eventsCustom(w *guipb.Widget) { + row := mt.x.Events[w.Location.Y-1] + // log.Info("got to eventsCustom() with", w.Location.X, w.Location.Y-1) + + for i, sf := range mt.anyFuncs { + if i == int(w.Location.X) { + if sf.Custom != nil { + log.Info("doing Custom() func for button") + sf.Custom(row) + return + } + } + } + mt.CustomFunc(row) +} + +func (mt *EventsTable) Custom(f func(*Event)) { + mt.pb.RegisterCustom(mt.eventsCustom) + mt.CustomFunc = f +} + +func (mt *EventsTable) GetUuid() string { + return mt.pb.Uuid +} + +// END TABLE UPDATE + +// END GUI diff --git a/event.marshal.pb.go b/event.marshal.pb.go new file mode 100644 index 0000000..34411b1 --- /dev/null +++ b/event.marshal.pb.go @@ -0,0 +1,56 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package main + +import ( + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/proto" +) + +// human readable JSON +func (v *Events) FormatJSON() string { + return protojson.Format(v) +} + +// marshal json +func (v *Events) MarshalJSON() ([]byte, error) { + return protojson.Marshal(v) +} + +// unmarshal json +func (v *Events) UnmarshalJSON(data []byte) error { + return protojson.Unmarshal(data, v) +} + +// apparently this isn't stable, but it's awesomely better +// https://protobuf.dev/reference/go/faq/#unstable-text +// it's brilliant for config files! +func (v *Events) FormatTEXT() string { + v.fixUuid() + return prototext.Format(v) +} + +// unmarshalTEXT. This reads the .text config file back in after the user edits it +func (v *Events) UnmarshalTEXT(data []byte) error { + return prototext.Unmarshal(data, v) +} + +// marshal to wire. This is called winning. +func (v *Events) Marshal() ([]byte, error) { + v.fixUuid() + return proto.Marshal(v) +} + +// unmarshal from wire. You have won. +func (v *Events) Unmarshal(data []byte) error { + return proto.Unmarshal(data, v) +} diff --git a/event.pb.go b/event.pb.go new file mode 100644 index 0000000..be03909 --- /dev/null +++ b/event.pb.go @@ -0,0 +1,470 @@ +// Code modified by go.wit.com/apps/autogenpb DO NOT EDIT. +// +// user defined Mutex locks were auto added +// +// autogenpb version & build time: v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// autogenpb auto generates Sort(), Unique() and Marshal() functions +// go install go.wit.com/apps/autogenpb@latest + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v3.21.12 +// source: event.proto + +package main // autogenpb changed the package name + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GusEventType int32 + +const ( + GusEventType_Connect GusEventType = 0 // a socket connect attempt + GusEventType_Disconnect GusEventType = 1 // a socket closed + GusEventType_Enable GusEventType = 2 // listening on a port was enabled + GusEventType_Disable GusEventType = 3 // listening on a port was disabled +) + +// Enum value maps for GusEventType. +var ( + GusEventType_name = map[int32]string{ + 0: "Connect", + 1: "Disconnect", + 2: "Enable", + 3: "Disable", + } + GusEventType_value = map[string]int32{ + "Connect": 0, + "Disconnect": 1, + "Enable": 2, + "Disable": 3, + } +) + +func (x GusEventType) Enum() *GusEventType { + p := new(GusEventType) + *p = x + return p +} + +func (x GusEventType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GusEventType) Descriptor() protoreflect.EnumDescriptor { + return file_event_proto_enumTypes[0].Descriptor() +} + +func (GusEventType) Type() protoreflect.EnumType { + return &file_event_proto_enumTypes[0] +} + +func (x GusEventType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GusEventType.Descriptor instead. +func (GusEventType) EnumDescriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{0} +} + +type GusSocket struct { + sync.RWMutex // auto-added by go.wit.com/apps/autogenpb + + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SrcHostname string `protobuf:"bytes,1,opt,name=srcHostname,proto3" json:"srcHostname,omitempty"` // the hostname + SrcIp string `protobuf:"bytes,2,opt,name=srcIp,proto3" json:"srcIp,omitempty"` // the IPv4 or IPv6 address + SrcPort string `protobuf:"bytes,3,opt,name=srcPort,proto3" json:"srcPort,omitempty"` // the port + DestHostname string `protobuf:"bytes,4,opt,name=destHostname,proto3" json:"destHostname,omitempty"` // the hostname + DestIp string `protobuf:"bytes,5,opt,name=destIp,proto3" json:"destIp,omitempty"` // the IPv4 or IPv6 address + DestPort string `protobuf:"bytes,6,opt,name=destPort,proto3" json:"destPort,omitempty"` // the port +} + +func (x *GusSocket) Reset() { + *x = GusSocket{} + if protoimpl.UnsafeEnabled { + mi := &file_event_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GusSocket) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GusSocket) ProtoMessage() {} + +func (x *GusSocket) ProtoReflect() protoreflect.Message { + mi := &file_event_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GusSocket.ProtoReflect.Descriptor instead. +func (*GusSocket) Descriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{0} +} + +func (x *GusSocket) GetSrcHostname() string { + if x != nil { + return x.SrcHostname + } + return "" +} + +func (x *GusSocket) GetSrcIp() string { + if x != nil { + return x.SrcIp + } + return "" +} + +func (x *GusSocket) GetSrcPort() string { + if x != nil { + return x.SrcPort + } + return "" +} + +func (x *GusSocket) GetDestHostname() string { + if x != nil { + return x.DestHostname + } + return "" +} + +func (x *GusSocket) GetDestIp() string { + if x != nil { + return x.DestIp + } + return "" +} + +func (x *GusSocket) GetDestPort() string { + if x != nil { + return x.DestPort + } + return "" +} + +type Event struct { + sync.RWMutex // auto-added by go.wit.com/apps/autogenpb + + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hostname string `protobuf:"bytes,1,opt,name=Hostname,proto3" json:"Hostname,omitempty"` // the hostname + LocalPort int64 `protobuf:"varint,2,opt,name=localPort,proto3" json:"localPort,omitempty"` // the port gus was listening on + Etype GusEventType `protobuf:"varint,3,opt,name=etype,proto3,enum=gus.GusEventType" json:"etype,omitempty"` // what kind of event was this + Sock *GusSocket `protobuf:"bytes,4,opt,name=sock,proto3" json:"sock,omitempty"` // socket details if event needs them + Ctime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=ctime,proto3" json:"ctime,omitempty"` // event create time + Etime *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=etime,proto3" json:"etime,omitempty"` // event end time +} + +func (x *Event) Reset() { + *x = Event{} + if protoimpl.UnsafeEnabled { + mi := &file_event_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Event) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event) ProtoMessage() {} + +func (x *Event) ProtoReflect() protoreflect.Message { + mi := &file_event_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{1} +} + +func (x *Event) GetHostname() string { + if x != nil { + return x.Hostname + } + return "" +} + +func (x *Event) GetLocalPort() int64 { + if x != nil { + return x.LocalPort + } + return 0 +} + +func (x *Event) GetEtype() GusEventType { + if x != nil { + return x.Etype + } + return GusEventType_Connect +} + +func (x *Event) GetSock() *GusSocket { + if x != nil { + return x.Sock + } + return nil +} + +func (x *Event) GetCtime() *timestamppb.Timestamp { + if x != nil { + return x.Ctime + } + return nil +} + +func (x *Event) GetEtime() *timestamppb.Timestamp { + if x != nil { + return x.Etime + } + return nil +} + +type Events struct { + // sync.RWMutex // skipped. protobuf file has `autogenpb:nomutex` + + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` // `autogenpb:uuid:4e91f9e6-f545-4c72-bec4-ab951276da1d` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` // `autogenpb:version:v0.0.1` + Events []*Event `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"` +} + +func (x *Events) Reset() { + *x = Events{} + if protoimpl.UnsafeEnabled { + mi := &file_event_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Events) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Events) ProtoMessage() {} + +func (x *Events) ProtoReflect() protoreflect.Message { + mi := &file_event_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Events.ProtoReflect.Descriptor instead. +func (*Events) Descriptor() ([]byte, []int) { + return file_event_proto_rawDescGZIP(), []int{2} +} + +func (x *Events) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +func (x *Events) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Events) GetEvents() []*Event { + if x != nil { + return x.Events + } + return nil +} + +var File_event_proto protoreflect.FileDescriptor + +var file_event_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x67, + 0x75, 0x73, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xb5, 0x01, 0x0a, 0x09, 0x47, 0x75, 0x73, 0x53, 0x6f, 0x63, 0x6b, 0x65, + 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x72, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x72, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x72, 0x63, 0x49, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x72, 0x63, 0x49, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x72, 0x63, + 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x72, 0x63, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x48, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x73, 0x74, 0x49, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x73, 0x74, 0x49, 0x70, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x64, 0x65, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xf2, 0x01, 0x0a, 0x05, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, + 0x27, 0x0a, 0x05, 0x65, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, + 0x2e, 0x67, 0x75, 0x73, 0x2e, 0x47, 0x75, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x05, 0x65, 0x74, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x73, 0x6f, 0x63, 0x6b, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x67, 0x75, 0x73, 0x2e, 0x47, 0x75, 0x73, + 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x04, 0x73, 0x6f, 0x63, 0x6b, 0x12, 0x30, 0x0a, 0x05, + 0x63, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x63, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x30, + 0x0a, 0x05, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x65, 0x74, 0x69, 0x6d, 0x65, + 0x22, 0x5a, 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x75, 0x73, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2a, 0x44, 0x0a, 0x0c, + 0x47, 0x75, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x10, 0x03, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_event_proto_rawDescOnce sync.Once + file_event_proto_rawDescData = file_event_proto_rawDesc +) + +func file_event_proto_rawDescGZIP() []byte { + file_event_proto_rawDescOnce.Do(func() { + file_event_proto_rawDescData = protoimpl.X.CompressGZIP(file_event_proto_rawDescData) + }) + return file_event_proto_rawDescData +} + +var file_event_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_event_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_event_proto_goTypes = []interface{}{ + (GusEventType)(0), // 0: gus.GusEventType + (*GusSocket)(nil), // 1: gus.GusSocket + (*Event)(nil), // 2: gus.Event + (*Events)(nil), // 3: gus.Events + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp +} +var file_event_proto_depIdxs = []int32{ + 0, // 0: gus.Event.etype:type_name -> gus.GusEventType + 1, // 1: gus.Event.sock:type_name -> gus.GusSocket + 4, // 2: gus.Event.ctime:type_name -> google.protobuf.Timestamp + 4, // 3: gus.Event.etime:type_name -> google.protobuf.Timestamp + 2, // 4: gus.Events.events:type_name -> gus.Event + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_event_proto_init() } +func file_event_proto_init() { + if File_event_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_event_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GusSocket); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_event_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_event_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Events); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_event_proto_rawDesc, + NumEnums: 1, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_event_proto_goTypes, + DependencyIndexes: file_event_proto_depIdxs, + EnumInfos: file_event_proto_enumTypes, + MessageInfos: file_event_proto_msgTypes, + }.Build() + File_event_proto = out.File + file_event_proto_rawDesc = nil + file_event_proto_goTypes = nil + file_event_proto_depIdxs = nil +} diff --git a/event.sort.pb.go b/event.sort.pb.go new file mode 100644 index 0000000..490f5ab --- /dev/null +++ b/event.sort.pb.go @@ -0,0 +1,224 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package main + +import ( + "fmt" + "iter" + "sync" + + "google.golang.org/protobuf/proto" +) + +// a simple global lock +var eventMu sync.RWMutex + +func (x *Events) fixUuid() { + if x == nil { + return + } + if x.Uuid == "4e91f9e6-f545-4c72-bec4-ab951276da1d" { + return + } + x.Uuid = "4e91f9e6-f545-4c72-bec4-ab951276da1d" + x.Version = "v0.0.1 go.wit.com/lib/daemons/gus" +} + +func NewEvents() *Events { + x := new(Events) + x.Uuid = "4e91f9e6-f545-4c72-bec4-ab951276da1d" + x.Version = "v0.0.1 go.wit.com/lib/daemons/gus" + return x +} + +// START SORT + +// DEFINE THE Events SCANNER. +// itializes a new scanner. +func newEventsScanner(things []*Events) *EventsScanner { + return &EventsScanner{things: things} +} + +type EventsScanner struct { + sync.Mutex + + things []*Events + index int +} + +func (it *EventsScanner) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.Lock() + it.index++ + it.Unlock() + return true +} + +// Next() returns the next thing in the array +func (it *EventsScanner) Next() *Events { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in EventsScanner", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE SCANNER + +// DEFINE THE Event SCANNER. +// itializes a new scanner. +func newEventScanner(things []*Event) *EventScanner { + return &EventScanner{things: things} +} + +type EventScanner struct { + sync.Mutex + + things []*Event + index int +} + +func (it *EventScanner) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.Lock() + it.index++ + it.Unlock() + return true +} + +// Next() returns the next thing in the array +func (it *EventScanner) Next() *Event { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in EventScanner", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE SCANNER + +// DEFINE THE GusSocket SCANNER. +// itializes a new scanner. +func newGusSocketScanner(things []*GusSocket) *GusSocketScanner { + return &GusSocketScanner{things: things} +} + +type GusSocketScanner struct { + sync.Mutex + + things []*GusSocket + index int +} + +func (it *GusSocketScanner) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.Lock() + it.index++ + it.Unlock() + return true +} + +// Next() returns the next thing in the array +func (it *GusSocketScanner) Next() *GusSocket { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in GusSocketScanner", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE SCANNER + +// safely returns a slice of pointers to the FRUIT protobufs +func (x *Events) allEvents() []*Event { + eventMu.RLock() + defer eventMu.RUnlock() + + // Create a new slice to hold pointers to each FRUIT + var tmp []*Event + tmp = make([]*Event, len(x.Events)) + for i, p := range x.Events { + tmp[i] = p // Copy pointers for safe iteration + } + + return tmp +} + +// safely returns a slice of pointers to the Event protobufs +func (x *Events) selectAllEvents() []*Event { + eventMu.RLock() + defer eventMu.RUnlock() + + // Create a new slice to hold pointers to each Event + var tmp []*Event + tmp = make([]*Event, len(x.Events)) + for i, p := range x.Events { + tmp[i] = p // Copy pointers for safe iteration + } + + return tmp +} + +// END SORT + +func (x *Events) Len() int { + eventMu.RLock() + defer eventMu.RUnlock() + + return len(x.Events) +} + +// a Append() shortcut (that does Clone() with a mutex) notsure if it really works +func (x *Events) Append(y *Event) *Event { + eventMu.Lock() + defer eventMu.Unlock() + + z := proto.Clone(y).(*Event) + x.Events = append(x.Events, z) + + return z +} + +func (x *Events) All() *EventScanner { + EventPointers := x.selectAllEvents() + + scanner := newEventScanner(EventPointers) + return scanner +} + +// Iterate 'for x := range' syntax using the awesome golang 1.24 'iter' +func (x *Events) IterAll() iter.Seq[*Event] { + items := x.selectAllEvents() + // log.Println("Made All() Iter.Seq[] with length", len(items)) + return func(yield func(*Event) bool) { + for _, v := range items { + if !yield(v) { + return + } + } + } +} +func (x *Events) Delete(y *Event) bool { + eventMu.Lock() + defer eventMu.Unlock() + + for i, _ := range x.Events { + if x.Events[i] == y { + x.Events[i] = x.Events[len(x.Events)-1] + x.Events = x.Events[:len(x.Events)-1] + return true + } + } + return false +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d80a5ac --- /dev/null +++ b/go.mod @@ -0,0 +1,57 @@ +module go.wit.com/lib/daemons/gus + +go 1.24.1 + +require ( + github.com/gin-gonic/gin v1.11.0 + github.com/google/uuid v1.6.0 + github.com/svent/go-nbreader v0.0.0-20150201200112-7cef48da76dc + go.wit.com/dev/alexflint/arg v1.6.3 + go.wit.com/gui v0.25.3 + go.wit.com/lib/debugger v0.22.40 + go.wit.com/lib/gadgets v0.22.40 + go.wit.com/lib/gui/prep v0.0.11 + go.wit.com/lib/http/ginpb v0.0.2 + go.wit.com/lib/protobuf/guipb v0.0.15 + go.wit.com/log v0.25.1 + google.golang.org/protobuf v1.36.9 +) + +require ( + github.com/alexflint/go-scalar v1.2.0 // indirect + github.com/bytedance/sonic v1.14.0 // indirect + github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/go-cmd/cmd v1.4.3 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-yaml v1.18.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.54.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.0 // indirect + go.uber.org/mock v0.5.0 // indirect + go.wit.com/lib/fhelp v0.0.23 // indirect + go.wit.com/lib/gui/logsettings v0.22.39 // indirect + go.wit.com/lib/gui/shell v0.22.33 // indirect + go.wit.com/widget v1.1.30 // indirect + golang.org/x/arch v0.20.0 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/mod v0.27.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/tools v0.36.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fc29032 --- /dev/null +++ b/go.sum @@ -0,0 +1,110 @@ +github.com/alexflint/go-scalar v1.2.0 h1:WR7JPKkeNpnYIOfHRa7ivM21aWAdHD0gEWHCx+WQBRw= +github.com/alexflint/go-scalar v1.2.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o= +github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= +github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= +github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= +github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/go-cmd/cmd v1.4.3 h1:6y3G+3UqPerXvPcXvj+5QNPHT02BUw7p6PsqRxLNA7Y= +github.com/go-cmd/cmd v1.4.3/go.mod h1:u3hxg/ry+D5kwh8WvUkHLAMe2zQCaXd00t35WfQaOFk= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= +github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= +github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/svent/go-nbreader v0.0.0-20150201200112-7cef48da76dc h1:usYkrH2/es/TT7ETdC/qLAagcJPW3EEYFKqvibSnFbA= +github.com/svent/go-nbreader v0.0.0-20150201200112-7cef48da76dc/go.mod h1:pPzZl0vMkUhyoxUF8PAGG5bDRGo7PY80oO/PMmpLkkc= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= +github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.wit.com/dev/alexflint/arg v1.6.3 h1:EduPl3oA/Sk4XcBVM7EYERlHjvbyEDysK5PqI/Wmdtw= +go.wit.com/dev/alexflint/arg v1.6.3/go.mod h1:RKOrAnxFl+856vbfvMEYcdd4qgBq2ZEO8atUcINendY= +go.wit.com/gui v0.25.3 h1:kDUzh/z52ghRlp/urVFCrDEIlkrfsKRmObN3LjbwsBU= +go.wit.com/gui v0.25.3/go.mod h1:H02phAerHwzSZMAb9mhL8rr7/zCbjASU8Cmg97tNvxY= +go.wit.com/lib/debugger v0.22.40 h1:SiSmM1xyMqgMMk/vs+E9YKEV/s4ky7MmOc0hG9nQMcI= +go.wit.com/lib/debugger v0.22.40/go.mod h1:ejXibtNbFQ6anGOWlTW+FCYPjD6xPeK93tGBOxul2n4= +go.wit.com/lib/fhelp v0.0.23 h1:XWQLxxS603xQwJ5IKjCKQ5vNeiivh3jfVrmDdc5piJ8= +go.wit.com/lib/fhelp v0.0.23/go.mod h1:8lRn3kJUuxkhief0JjbxL/ydw06ZJx/HLw7eMx9Xx9Y= +go.wit.com/lib/gadgets v0.22.40 h1:kpSjvDg3aTmRtRbeycnQ0oSY63fKBOVlb31BEXv90y0= +go.wit.com/lib/gadgets v0.22.40/go.mod h1:tWyvs4n33V6T88iL4cecLxKLYd+azXiRwlAbeOeRtSE= +go.wit.com/lib/gui/logsettings v0.22.39 h1:zL1lLS83LodMm7Z+HbzFHXclfPrkwfdtZsgcJEp3l58= +go.wit.com/lib/gui/logsettings v0.22.39/go.mod h1:PJul3sXAeT/eFf0s0kj7k4TW9kW0WS+DDOwXom1wrUE= +go.wit.com/lib/gui/prep v0.0.11 h1:8lla9pdZ3KkQVgt+F77imtqSMBkXZaFxIwXLcjBgW8E= +go.wit.com/lib/gui/prep v0.0.11/go.mod h1:6lgucjv3/RvzUV2tuo/Loh3WZNlePVRYEsEfiFIy97s= +go.wit.com/lib/gui/shell v0.22.33 h1:3MvWBQU4rOHK4Ac5MkQ62ndW7WhCBpu9F3AVeUF7YgQ= +go.wit.com/lib/gui/shell v0.22.33/go.mod h1:aRDwKXKXkZaO4y/0KPe1lhKQCXpyi8hXgUEOrHhzpAI= +go.wit.com/lib/http/ginpb v0.0.2 h1:U4p7ybedIvaTbgALC3hyHj1/950yIInV5R0yq8P6XLc= +go.wit.com/lib/http/ginpb v0.0.2/go.mod h1:G9CIzVBzNFXZRmRVuryH++PHJS+B2KbKSw0gtqp5adU= +go.wit.com/lib/protobuf/guipb v0.0.15 h1:0MJ9FNFuUuNS8AsK+UcgGGnb3Xlw+ve7AbWLnHyIJ08= +go.wit.com/lib/protobuf/guipb v0.0.15/go.mod h1:9AzFoNKnE0161IOTfdul6SX5+GPAFNW7RPKWohenmcQ= +go.wit.com/log v0.25.1 h1:74WVf9NSN6z5jc2oSbA1ehxdZ7V/NBXTk5t0jIoaTMg= +go.wit.com/log v0.25.1/go.mod h1:XE4lTfAibWgwBJksIk7u3IEJ8xcBvNhnlewYAQGj2Ew= +go.wit.com/widget v1.1.30 h1:O/dIG7QtDrZkR5P6f8JAMyevBiMXSun9vL6F0KFAWV8= +go.wit.com/widget v1.1.30/go.mod h1:wj7TpAr2gk7Poa+v8XQkH1aidnTdgAa/a8GxrMtcztw= +golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= +golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/portmap.gui.pb.go b/portmap.gui.pb.go new file mode 100644 index 0000000..fd9d1db --- /dev/null +++ b/portmap.gui.pb.go @@ -0,0 +1,264 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package main + +import ( + "time" + + "github.com/google/uuid" + "go.wit.com/gui" + "go.wit.com/lib/protobuf/guipb" + "go.wit.com/log" + "google.golang.org/protobuf/proto" + anypb "google.golang.org/protobuf/types/known/anypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +// START GUI + +func (x *Portmaps) NewTable(title string) *PortmapsTable { + t := new(PortmapsTable) + t.x = x + pb := new(guipb.Table) + pb.Title = title + t.pb = pb + return t +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *PortmapsTable) AddStringFunc(title string, f func(*Portmap) string) *PortmapAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(PortmapAnyFunc) + sf.title = title + sf.f = func(x *Portmap) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_STRING + + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *PortmapsTable) AddButtonFunc(title string, f func(*Portmap) string) *PortmapAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(PortmapAnyFunc) + sf.title = title + sf.f = func(x *Portmap) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_STRING + sf.attr.Click = true + + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *PortmapsTable) AddIntFunc(title string, f func(*Portmap) int) *PortmapAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(PortmapAnyFunc) + sf.title = title + sf.f = func(x *Portmap) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_INT + + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +// force the application to choose the type of data. this allows the GUI plugin to be smarter +func (t *PortmapsTable) AddTimeFunc(title string, f func(*Portmap) time.Time) *PortmapAnyFunc { + t.pb.Order = append(t.pb.Order, title) + + sf := new(PortmapAnyFunc) + sf.title = title + sf.f = func(x *Portmap) any { + return f(x) + } + sf.attr = new(guipb.ColAttr) + sf.attr.Width = int32(sf.Width) + sf.attr.Type = guipb.ColAttr_TIME + + // t.timeFuncs = append(t.timeFuncs, sf) + t.anyFuncs = append(t.anyFuncs, sf) + return sf +} + +func (sf *PortmapAnyFunc) SetTitle(title string) { + sf.title = title +} + +func (mt *PortmapsTable) SetParent(p *gui.Node) { + mt.parent = p +} + +func (mt *PortmapsTable) ShowTable() { + // log.Info("ShowTable() SENDING TO GUI") + mt.MakeTable() + mt.parent.ShowTable(mt.pb) +} + +type PortmapAnyFunc struct { + title string + f func(*Portmap) any + Custom func(*Portmap) + Width int + attr *guipb.ColAttr +} + +type PortmapsTable struct { + pb *guipb.Table + parent *gui.Node + x *Portmaps + hostnames []string + anyFuncs []*PortmapAnyFunc + CustomFunc func(*Portmap) +} + +func (mt *PortmapsTable) doAnyFuncNew(sf *PortmapAnyFunc) bool { + r := new(guipb.AnyCol) + r.Header = new(guipb.Widget) + r.Header.Name = sf.title + r.Attr = proto.Clone(sf.attr).(*guipb.ColAttr) + + for m := range mt.x.IterAll() { + t := sf.f(m) + switch r.Attr.Type { + case guipb.ColAttr_STRING: + // anyProto, err := anypb.New(tsProto) + stringValue := wrapperspb.String(t.(string)) + anyProto, err := anypb.New(stringValue) + _ = err // do something with err someday (?) + r.Vals = append(r.Vals, anyProto) + // return col.Vals[row] true + case guipb.ColAttr_INT: + var finalInt int + finalInt = t.(int) + intVal := wrapperspb.Int32(int32(finalInt)) + anyProto, _ := anypb.New(intVal) + r.Vals = append(r.Vals, anyProto) + case guipb.ColAttr_DURATION: + case guipb.ColAttr_TIME: + var goTime time.Time + goTime = t.(time.Time) + tsProto := timestamppb.New(goTime) + anyProto, err := anypb.New(tsProto) + _ = err // do something with err someday (?) + r.Vals = append(r.Vals, anyProto) + default: + log.Info("cell unhandled type", r.Attr.Type) + } + // cellTime := r.Vals[row] + // s := shell.FormatDuration(time.Since(cellTime.AsTime())) + } + + mt.pb.AnyCols = append(mt.pb.AnyCols, r) + return true +} + +func (mt *PortmapsTable) MakeTable() { + for _, sf := range mt.anyFuncs { + mt.doAnyFuncNew(sf) + } +} + +func (t *PortmapsTable) AddLocalport() *PortmapAnyFunc { + custf := t.AddIntFunc("Localport", func(m *Portmap) int { + return int(m.Localport) + }) + return custf +} + +func (t *PortmapsTable) AddDest() *PortmapAnyFunc { + sf := t.AddStringFunc("Dest", func(m *Portmap) string { + return m.Dest + }) + return sf +} + +func (t *PortmapsTable) AddHosts() *PortmapAnyFunc { + sf := t.AddStringFunc("Hosts", func(m *Portmap) string { + return m.Hosts + }) + return sf +} + +func (t *PortmapsTable) AddIptables() *PortmapAnyFunc { + sf := t.AddStringFunc("Iptables", func(m *Portmap) string { + return m.Iptables + }) + return sf +} +func (mt *PortmapsTable) NewUuid() { + mt.pb.Uuid = uuid.New().String() +} + +// START TABLE UPDATE (doesn't work yet) + +func (mt *PortmapsTable) dumpStringFunc(name string) { + for i, r := range mt.pb.StringCols { + // log.Info("could use", i, r.Header.Name, "for name =", name) + if r.Header.Name == name { + log.Info("dump Strings row", i, r.Header.Name, r.Vals) + break + } + } +} + +func (mt *PortmapsTable) Delete() { + if mt == nil { + log.Info("mt == nil table already deleted") + return + } + // log.Info("table Delete here") + mt.parent.DeleteTable(mt.pb) +} + +func (mt *PortmapsTable) portmapsCustom(w *guipb.Widget) { + row := mt.x.Portmaps[w.Location.Y-1] + // log.Info("got to portmapsCustom() with", w.Location.X, w.Location.Y-1) + + for i, sf := range mt.anyFuncs { + if i == int(w.Location.X) { + if sf.Custom != nil { + log.Info("doing Custom() func for button") + sf.Custom(row) + return + } + } + } + mt.CustomFunc(row) +} + +func (mt *PortmapsTable) Custom(f func(*Portmap)) { + mt.pb.RegisterCustom(mt.portmapsCustom) + mt.CustomFunc = f +} + +func (mt *PortmapsTable) GetUuid() string { + return mt.pb.Uuid +} + +// END TABLE UPDATE + +// END GUI diff --git a/portmap.marshal.pb.go b/portmap.marshal.pb.go new file mode 100644 index 0000000..ac955d7 --- /dev/null +++ b/portmap.marshal.pb.go @@ -0,0 +1,56 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package main + +import ( + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/proto" +) + +// human readable JSON +func (v *Portmaps) FormatJSON() string { + return protojson.Format(v) +} + +// marshal json +func (v *Portmaps) MarshalJSON() ([]byte, error) { + return protojson.Marshal(v) +} + +// unmarshal json +func (v *Portmaps) UnmarshalJSON(data []byte) error { + return protojson.Unmarshal(data, v) +} + +// apparently this isn't stable, but it's awesomely better +// https://protobuf.dev/reference/go/faq/#unstable-text +// it's brilliant for config files! +func (v *Portmaps) FormatTEXT() string { + v.fixUuid() + return prototext.Format(v) +} + +// unmarshalTEXT. This reads the .text config file back in after the user edits it +func (v *Portmaps) UnmarshalTEXT(data []byte) error { + return prototext.Unmarshal(data, v) +} + +// marshal to wire. This is called winning. +func (v *Portmaps) Marshal() ([]byte, error) { + v.fixUuid() + return proto.Marshal(v) +} + +// unmarshal from wire. You have won. +func (v *Portmaps) Unmarshal(data []byte) error { + return proto.Unmarshal(data, v) +} diff --git a/portmap.pb.go b/portmap.pb.go new file mode 100644 index 0000000..d7ccf46 --- /dev/null +++ b/portmap.pb.go @@ -0,0 +1,294 @@ +// Code modified by go.wit.com/apps/autogenpb DO NOT EDIT. +// +// user defined Mutex locks were auto added +// +// autogenpb version & build time: v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// autogenpb auto generates Sort(), Unique() and Marshal() functions +// go install go.wit.com/apps/autogenpb@latest + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v3.21.12 +// source: portmap.proto + +package main // autogenpb changed the package name + +import ( + reflect "reflect" + sync "sync" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Portmap struct { + sync.RWMutex // auto-added by go.wit.com/apps/autogenpb + + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Localport int64 `protobuf:"varint,1,opt,name=localport,proto3" json:"localport,omitempty"` // `autogenpb:unique` + Dest string `protobuf:"bytes,2,opt,name=dest,proto3" json:"dest,omitempty"` + Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"` + AllowIPv4 bool `protobuf:"varint,4,opt,name=allowIPv4,proto3" json:"allowIPv4,omitempty"` + UseME bool `protobuf:"varint,5,opt,name=useME,proto3" json:"useME,omitempty"` + Hosts string `protobuf:"bytes,6,opt,name=hosts,proto3" json:"hosts,omitempty"` + Iptables string `protobuf:"bytes,7,opt,name=iptables,proto3" json:"iptables,omitempty"` +} + +func (x *Portmap) Reset() { + *x = Portmap{} + if protoimpl.UnsafeEnabled { + mi := &file_portmap_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Portmap) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Portmap) ProtoMessage() {} + +func (x *Portmap) ProtoReflect() protoreflect.Message { + mi := &file_portmap_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Portmap.ProtoReflect.Descriptor instead. +func (*Portmap) Descriptor() ([]byte, []int) { + return file_portmap_proto_rawDescGZIP(), []int{0} +} + +func (x *Portmap) GetLocalport() int64 { + if x != nil { + return x.Localport + } + return 0 +} + +func (x *Portmap) GetDest() string { + if x != nil { + return x.Dest + } + return "" +} + +func (x *Portmap) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *Portmap) GetAllowIPv4() bool { + if x != nil { + return x.AllowIPv4 + } + return false +} + +func (x *Portmap) GetUseME() bool { + if x != nil { + return x.UseME + } + return false +} + +func (x *Portmap) GetHosts() string { + if x != nil { + return x.Hosts + } + return "" +} + +func (x *Portmap) GetIptables() string { + if x != nil { + return x.Iptables + } + return "" +} + +type Portmaps struct { + // sync.RWMutex // skipped. protobuf file has `autogenpb:nomutex` + + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` // `autogenpb:uuid:49a865ea-292d-48fd-8dc2-d0f82d5fd016` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` // `autogenpb:version:v0.0.1` + Portmaps []*Portmap `protobuf:"bytes,3,rep,name=portmaps,proto3" json:"portmaps,omitempty"` +} + +func (x *Portmaps) Reset() { + *x = Portmaps{} + if protoimpl.UnsafeEnabled { + mi := &file_portmap_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Portmaps) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Portmaps) ProtoMessage() {} + +func (x *Portmaps) ProtoReflect() protoreflect.Message { + mi := &file_portmap_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Portmaps.ProtoReflect.Descriptor instead. +func (*Portmaps) Descriptor() ([]byte, []int) { + return file_portmap_proto_rawDescGZIP(), []int{1} +} + +func (x *Portmaps) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +func (x *Portmaps) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Portmaps) GetPortmaps() []*Portmap { + if x != nil { + return x.Portmaps + } + return nil +} + +var File_portmap_proto protoreflect.FileDescriptor + +var file_portmap_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x03, 0x67, 0x75, 0x73, 0x22, 0xbb, 0x01, 0x0a, 0x07, 0x50, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, + 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x64, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, + 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x50, 0x76, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x49, 0x50, 0x76, 0x34, 0x12, 0x14, 0x0a, 0x05, 0x75, 0x73, + 0x65, 0x4d, 0x45, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x75, 0x73, 0x65, 0x4d, 0x45, + 0x12, 0x14, 0x0a, 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x70, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x70, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x22, 0x62, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, + 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x08, + 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x67, 0x75, 0x73, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x70, 0x52, 0x08, 0x70, 0x6f, + 0x72, 0x74, 0x6d, 0x61, 0x70, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_portmap_proto_rawDescOnce sync.Once + file_portmap_proto_rawDescData = file_portmap_proto_rawDesc +) + +func file_portmap_proto_rawDescGZIP() []byte { + file_portmap_proto_rawDescOnce.Do(func() { + file_portmap_proto_rawDescData = protoimpl.X.CompressGZIP(file_portmap_proto_rawDescData) + }) + return file_portmap_proto_rawDescData +} + +var file_portmap_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_portmap_proto_goTypes = []interface{}{ + (*Portmap)(nil), // 0: gus.Portmap + (*Portmaps)(nil), // 1: gus.Portmaps +} +var file_portmap_proto_depIdxs = []int32{ + 0, // 0: gus.Portmaps.portmaps:type_name -> gus.Portmap + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_portmap_proto_init() } +func file_portmap_proto_init() { + if File_portmap_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_portmap_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Portmap); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_portmap_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Portmaps); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_portmap_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_portmap_proto_goTypes, + DependencyIndexes: file_portmap_proto_depIdxs, + MessageInfos: file_portmap_proto_msgTypes, + }.Build() + File_portmap_proto = out.File + file_portmap_proto_rawDesc = nil + file_portmap_proto_goTypes = nil + file_portmap_proto_depIdxs = nil +} diff --git a/portmap.sort.pb.go b/portmap.sort.pb.go new file mode 100644 index 0000000..18a6a8a --- /dev/null +++ b/portmap.sort.pb.go @@ -0,0 +1,225 @@ +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.5.3-12-g0ccf2c0 2025-09-18_03:40:35_UTC +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package main + +import ( + "fmt" + "iter" + "sync" + + "google.golang.org/protobuf/proto" +) + +// a simple global lock +var portmapMu sync.RWMutex + +func (x *Portmaps) fixUuid() { + if x == nil { + return + } + if x.Uuid == "49a865ea-292d-48fd-8dc2-d0f82d5fd016" { + return + } + x.Uuid = "49a865ea-292d-48fd-8dc2-d0f82d5fd016" + x.Version = "v0.0.1 go.wit.com/lib/daemons/gus" +} + +func NewPortmaps() *Portmaps { + x := new(Portmaps) + x.Uuid = "49a865ea-292d-48fd-8dc2-d0f82d5fd016" + x.Version = "v0.0.1 go.wit.com/lib/daemons/gus" + return x +} + +// START SORT + +// DEFINE THE Portmaps SCANNER. +// itializes a new scanner. +func newPortmapsScanner(things []*Portmaps) *PortmapsScanner { + return &PortmapsScanner{things: things} +} + +type PortmapsScanner struct { + sync.Mutex + + things []*Portmaps + index int +} + +func (it *PortmapsScanner) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.Lock() + it.index++ + it.Unlock() + return true +} + +// Next() returns the next thing in the array +func (it *PortmapsScanner) Next() *Portmaps { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in PortmapsScanner", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE SCANNER + +// DEFINE THE Portmap SCANNER. +// itializes a new scanner. +func newPortmapScanner(things []*Portmap) *PortmapScanner { + return &PortmapScanner{things: things} +} + +type PortmapScanner struct { + sync.Mutex + + things []*Portmap + index int +} + +func (it *PortmapScanner) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.Lock() + it.index++ + it.Unlock() + return true +} + +// Next() returns the next thing in the array +func (it *PortmapScanner) Next() *Portmap { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in PortmapScanner", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE SCANNER + +// safely returns a slice of pointers to the FRUIT protobufs +func (x *Portmaps) allPortmaps() []*Portmap { + portmapMu.RLock() + defer portmapMu.RUnlock() + + // Create a new slice to hold pointers to each FRUIT + var tmp []*Portmap + tmp = make([]*Portmap, len(x.Portmaps)) + for i, p := range x.Portmaps { + tmp[i] = p // Copy pointers for safe iteration + } + + return tmp +} + +// safely returns a slice of pointers to the Portmap protobufs +func (x *Portmaps) selectAllPortmaps() []*Portmap { + portmapMu.RLock() + defer portmapMu.RUnlock() + + // Create a new slice to hold pointers to each Portmap + var tmp []*Portmap + tmp = make([]*Portmap, len(x.Portmaps)) + for i, p := range x.Portmaps { + tmp[i] = p // Copy pointers for safe iteration + } + + return tmp +} + +// END SORT + +func (x *Portmaps) Len() int { + portmapMu.RLock() + defer portmapMu.RUnlock() + + return len(x.Portmaps) +} + +// a Append() shortcut (that does Clone() with a mutex) notsure if it really works +func (x *Portmaps) Append(y *Portmap) *Portmap { + portmapMu.Lock() + defer portmapMu.Unlock() + + z := proto.Clone(y).(*Portmap) + x.Portmaps = append(x.Portmaps, z) + + return z +} + +func (x *Portmaps) All() *PortmapScanner { + PortmapPointers := x.selectAllPortmaps() + + scanner := newPortmapScanner(PortmapPointers) + return scanner +} + +// Iterate 'for x := range' syntax using the awesome golang 1.24 'iter' +func (x *Portmaps) IterAll() iter.Seq[*Portmap] { + items := x.selectAllPortmaps() + // log.Println("Made All() Iter.Seq[] with length", len(items)) + return func(yield func(*Portmap) bool) { + for _, v := range items { + if !yield(v) { + return + } + } + } +} +func (x *Portmaps) Delete(y *Portmap) bool { + portmapMu.Lock() + defer portmapMu.Unlock() + + for i, _ := range x.Portmaps { + if x.Portmaps[i] == y { + x.Portmaps[i] = x.Portmaps[len(x.Portmaps)-1] + x.Portmaps = x.Portmaps[:len(x.Portmaps)-1] + return true + } + } + return false +} + +// lookup a Portmaps by the Localport +func (x *Portmaps) FindByLocalport(y int64) *Portmap { + if x == nil { + return nil + } + + portmapMu.RLock() + defer portmapMu.RUnlock() + + for i, _ := range x.Portmaps { + if x.Portmaps[i].Localport == y { + return x.Portmaps[i] + } + } + return nil +} + +// returns a Portmap if Localport matches, otherwise create +func (x *Portmaps) InsertByLocalport(y int64) *Portmap { + portmapMu.Lock() + defer portmapMu.Unlock() + + for _, z := range x.Portmaps { + if z.Localport == y { + return z + } + } + + z := new(Portmap) + z.Localport = y + x.Portmaps = append(x.Portmaps, z) + return z +}