Compare commits

..

No commits in common. "5d5ee9c644d44c4736ab24523ff37bbf633825b4" and "00f55788c2228abc2b6961ad1e3ac9627a15c506" have entirely different histories.

7 changed files with 23 additions and 71 deletions

View File

@ -1,38 +1,19 @@
package hopp
import "net"
// import "time"
import "io"
// Conn is a HOPP connection.
type Conn interface {
// Close closes the connection. Any blocked operations on the connection
// or its transactions will be unblocked and return errors.
Close() error
// See documentation for [net.Conn]
LocalAddr() net.Addr
RemoteAddr() net.Addr
// OpenTrans opens a transaction. The other party will not know about
// this until the first message is sent.
io.Closer
OpenTrans() (Trans, error)
// AcceptTrans accepts a transaction from the other party. This must
// be called in a loop to avoid the connection locking up.
AcceptTrans() (Trans, error)
}
// Trans is a HOPP transaction.
type Trans interface {
// Close closes the transaction. Any blocked operations will be
// unblocked and return errors.
Close() error
// ID returns the transaction ID. This must not change, and it must be
// unique within the connection.
io.Closer
ID() int64
// TODO: add methods for setting send and receive deadlines
// Send sends a message.
Send(method uint16, data []byte) error
// Receive receives a message.

View File

@ -3,7 +3,6 @@ package generate
import "io"
import "fmt"
import "bufio"
import "strings"
const send =
`// Send sends one message along a transaction.
@ -63,6 +62,7 @@ func (this *Protocol) Generate(writer io.Writer, packag string) error {
if err != nil { return err }
}
// TODO
return nil
}
@ -86,13 +86,13 @@ func (this *Protocol) receive(out io.Writer) error {
}
func (this *Protocol) defineMessage(out io.Writer, message Message) error {
fmt.Fprintln(out, comment("//", fmt.Sprintf("(%d) %s\n", message.Method, message.Doc)))
fmt.Fprintf(out, "// (%d) %s\n", message.Method, message.Doc)
fmt.Fprintf(out, "type Message%s struct {\n", message.Name)
for _, field := range message.Fields {
typ, err := this.ResolveType(field.Type)
if err != nil { return err }
if field.Doc != "" {
fmt.Fprintf(out, "\t%s\n", comment("\t//", field.Doc))
fmt.Fprintf(out, "\t// %s\n", field.Doc)
}
if field.Optional {
typ = fmt.Sprintf("hopp.Option[%s]", typ)
@ -222,12 +222,6 @@ func (this *Protocol) unmarshalMessage(out io.Writer, message Message) error {
fmt.Fprintf(out,
"func (msg *Message%s) UnmarshalBinary(buffer []byte) error {\n",
message.Name)
if len(message.Fields) < 1 {
fmt.Fprintf(out, "\t// no fields\n")
fmt.Fprintf(out, "\treturn nil\n")
fmt.Fprintf(out, "}\n\n")
return nil
}
fmt.Fprintf(out, "\tpairs, err := tape.DecodePairs(buffer)\n")
fmt.Fprintf(out, "\tif err != nil { return err }\n")
requiredTotal := 0
@ -249,12 +243,10 @@ func (this *Protocol) unmarshalMessage(out io.Writer, message Message) error {
fmt.Fprintf(out, "\n")
fmt.Fprintf(out, "\t\t\tif err != nil { return err }\n")
if field.Optional {
fmt.Fprintf(out, "\t\t\tmsg.%s = hopp.O(value)\n", field.Name)
fmt.Fprintf(out, "\t\t\tmsg.%s.Set(value)\n", field.Name)
} else {
fmt.Fprintf(out, "\t\t\tmsg.%s = value\n", field.Name)
if requiredTotal > 0 {
fmt.Fprintf(out, "\t\t\tfoundRequired ++\n")
}
fmt.Fprintf(out, "\t\t\tfoundRequired ++\n")
}
}
fmt.Fprintf(out, "\t\t}\n")
@ -296,7 +288,3 @@ func (this *Protocol) unmarshalField(out io.Writer, field Field) error {
}
return nil
}
func comment(prefix, text string) string {
return prefix + " " + strings.ReplaceAll(strings.TrimSpace(text), "\n", "\n" + prefix + " ")
}

2
go.mod
View File

@ -3,7 +3,7 @@ module git.tebibyte.media/sashakoshka/hopp
go 1.23.0
require (
git.tebibyte.media/sashakoshka/go-util v0.9.0
git.tebibyte.media/sashakoshka/go-util v0.8.0
github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62
github.com/quic-go/quic-go v0.48.2
)

4
go.sum
View File

@ -1,5 +1,5 @@
git.tebibyte.media/sashakoshka/go-util v0.9.0 h1:s4u6USI1yRqTFNv52qJlEy1qO9pfF2+U6IklxkSLckY=
git.tebibyte.media/sashakoshka/go-util v0.9.0/go.mod h1:0Q1t+PePdx6tFYkRuJNcpM1Mru7wE6X+it1kwuOH+6Y=
git.tebibyte.media/sashakoshka/go-util v0.8.0 h1:XFuZ8HQkrnibrV016rso00geCFPatKpX4jxkIVhZPaQ=
git.tebibyte.media/sashakoshka/go-util v0.8.0/go.mod h1:0Q1t+PePdx6tFYkRuJNcpM1Mru7wE6X+it1kwuOH+6Y=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=

View File

@ -46,14 +46,6 @@ func (this *a) Close() error {
return this.underlying.Close()
}
func (this *a) LocalAddr() net.Addr {
return this.underlying.LocalAddr()
}
func (this *a) RemoteAddr() net.Addr {
return this.underlying.RemoteAddr()
}
func (this *a) OpenTrans() (Trans, error) {
this.transLock.Lock()
defer this.transLock.Unlock()
@ -93,6 +85,10 @@ func (this *a) sendMessageSafe(trans int64, method uint16, data []byte) error {
}
func (this *a) receive() {
// TODO: multiplex receiving
// if a received transaction has a malformed ID, reject it here and
// cause the connection to fail
// at the end of this function, close all incoming channels
defer func() {
this.underlying.Close()
this.transLock.Lock()

View File

@ -23,14 +23,6 @@ func (this *b) Close() error {
return this.underlying.Close()
}
func (this *b) LocalAddr() net.Addr {
return this.underlying.LocalAddr()
}
func (this *b) RemoteAddr() net.Addr {
return this.underlying.RemoteAddr()
}
func (this *b) OpenTrans() (Trans, error) {
stream, err := this.underlying.OpenStream()
if err != nil { return nil, err }
@ -63,8 +55,7 @@ func (trans transB) Receive() (uint16, []byte, error) {
return decodeMessageB(trans.underlying)
}
// MultiConn represens a multiplexed stream-oriented transport for use in
// [AdaptB].
// MultiConn represens a multiplexed stream-oriented transport for use in [B].
type MultiConn interface {
// See documentation for [net.Conn].
io.Closer

View File

@ -6,18 +6,14 @@ import "git.tebibyte.media/sashakoshka/go-util/container"
// TODO make generic alias once go 1.24 releases
type Option[T any] ucontainer.Optional[T]
func O[T any](value T) Option[T] {
return Option[T](ucontainer.O(value))
func (option *Option[T]) Get() (T, bool) {
return option.Get()
}
func Void[T any]() Option[T] {
return Option[T](ucontainer.Void[T]())
func (option *Option[T]) Set(value T) {
option.Set(value)
}
func (option Option[T]) Ok() bool {
return (ucontainer.Optional[T])(option).Exists()
}
func (option Option[T]) Get() (T, bool) {
return (ucontainer.Optional[T])(option).Value()
func (option *Option[T]) Reset() {
option.Reset()
}