diff --git a/message/options.go b/message/options.go index 02a182a9..8211de72 100644 --- a/message/options.go +++ b/message/options.go @@ -210,10 +210,7 @@ func (options Options) GetUint32(id OptionID) (uint32, error) { // ContentFormat gets the content format of body. func (options Options) ContentFormat() (MediaType, error) { v, err := options.GetUint32(ContentFormat) - if err != nil { - return MediaType(0), err - } - return MediaTypeFromNumber(v) + return math.CastTo[MediaType](v), err } // GetString gets the string value of the first option with the given ID. @@ -359,10 +356,7 @@ func (options Options) SetAccept(buf []byte, contentFormat MediaType) (Options, // Accept gets accept option. func (options Options) Accept() (MediaType, error) { v, err := options.GetUint32(Accept) - if err != nil { - return MediaType(0), err - } - return MediaTypeFromNumber(v) + return math.CastTo[MediaType](v), err } // Find returns range of type options. First number is index and second number is index of next option type. diff --git a/message/pool/message.go b/message/pool/message.go index 5191e76e..2a6d7779 100644 --- a/message/pool/message.go +++ b/message/pool/message.go @@ -10,6 +10,7 @@ import ( "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" "github.com/plgd-dev/go-coap/v3/net" + "github.com/plgd-dev/go-coap/v3/pkg/math" "go.uber.org/atomic" ) @@ -373,10 +374,7 @@ func (r *Message) AddOptionUint32(opt message.OptionID, value uint32) { func (r *Message) ContentFormat() (message.MediaType, error) { v, err := r.GetOptionUint32(message.ContentFormat) - if err != nil { - return message.MediaType(0), err - } - return message.MediaTypeFromNumber(v) + return math.CastTo[message.MediaType](v), err } func (r *Message) HasOption(id message.OptionID) bool { @@ -395,18 +393,15 @@ func (r *Message) Observe() (uint32, error) { return r.GetOptionUint32(message.Observe) } -// SetAccept set's accept option. +// SetAccept sets accept option. func (r *Message) SetAccept(contentFormat message.MediaType) { r.SetOptionUint32(message.Accept, uint32(contentFormat)) } -// Accept get's accept option. +// Accept gets accept option. func (r *Message) Accept() (message.MediaType, error) { v, err := r.GetOptionUint32(message.Accept) - if err != nil { - return message.MediaType(0), err - } - return message.MediaTypeFromNumber(v) + return math.CastTo[message.MediaType](v), err } func (r *Message) BodySize() (int64, error) { diff --git a/net/blockwise/blockwise.go b/net/blockwise/blockwise.go index 72f7958a..33bc53b5 100644 --- a/net/blockwise/blockwise.go +++ b/net/blockwise/blockwise.go @@ -116,7 +116,7 @@ func DecodeBlockOption(blockVal uint32) (szx SZX, blockNumber int64, moreBlocksF return } - szx = SZX(blockVal & szxMask) // masking for the SZX + szx = math.CastTo[SZX](blockVal & szxMask) // masking for the SZX if (blockVal & moreBlocksFollowingMask) != 0 { // masking for the "M" moreBlocksFollowing = true } diff --git a/options/commonOptions.go b/options/commonOptions.go index 1c09b89a..dfad6344 100644 --- a/options/commonOptions.go +++ b/options/commonOptions.go @@ -116,7 +116,7 @@ func (o MuxHandlerOpt) UDPClientApply(cfg *udpClient.Config) { cfg.Handler = mux.ToHandler[*udpClient.Conn](o.m) } -// WithMux set's multiplexer for handle requests. +// WithMux sets multiplexer for handle requests. func WithMux(m mux.Handler) MuxHandlerOpt { return MuxHandlerOpt{ m: m, @@ -148,7 +148,7 @@ func (o ContextOpt) UDPClientApply(cfg *udpClient.Config) { cfg.Ctx = o.ctx } -// WithContext set's parent context of server. +// WithContext sets parent context of server. func WithContext(ctx context.Context) ContextOpt { return ContextOpt{ctx: ctx} } diff --git a/pkg/math/cast.go b/pkg/math/cast.go index 0c239869..a355f93a 100644 --- a/pkg/math/cast.go +++ b/pkg/math/cast.go @@ -9,6 +9,7 @@ import ( "golang.org/x/exp/constraints" ) +// Max returns maximal value for given integer type func Max[T constraints.Integer]() T { size := unsafe.Sizeof(T(0)) switch reflect.TypeOf((*T)(nil)).Elem().Kind() { @@ -21,6 +22,7 @@ func Max[T constraints.Integer]() T { } } +// Min returns minimal value for given integer type func Min[T constraints.Integer]() T { size := unsafe.Sizeof(T(0)) switch reflect.TypeOf((*T)(nil)).Elem().Kind() { @@ -33,6 +35,7 @@ func Min[T constraints.Integer]() T { } } +// CastTo casts one integer type to another with bounds checking and returns error in case of overflow func SafeCastTo[T, F constraints.Integer](from F) (T, error) { if from > 0 && uint64(Max[T]()) < uint64(from) { return T(0), fmt.Errorf("value(%v) exceeds the maximum value for type(%v)", from, Max[T]()) @@ -43,10 +46,12 @@ func SafeCastTo[T, F constraints.Integer](from F) (T, error) { return T(from), nil } +// CastTo casts one integer type to another without bounds checking func CastTo[T, F constraints.Integer](from F) T { return T(from) } +// MustSafeCastTo casts one integer type to another with bounds checking and panics in case of overflow func MustSafeCastTo[T, F constraints.Integer](from F) T { to, err := SafeCastTo[T](from) if err != nil { diff --git a/tcp/coder/coder.go b/tcp/coder/coder.go index cf87dd91..ec9468bb 100644 --- a/tcp/coder/coder.go +++ b/tcp/coder/coder.go @@ -37,11 +37,11 @@ func (c *Coder) Size(m message.Message) (int, error) { func getHeader(messageLength int) (uint8, []byte) { if messageLength < MessageLength13Base { - return uint8(messageLength), nil + return math.CastTo[uint8](messageLength), nil } if messageLength < MessageLength14Base { extLen := messageLength - MessageLength13Base - extLenBytes := []byte{uint8(extLen)} + extLenBytes := []byte{math.CastTo[uint8](extLen)} return 13, extLenBytes } if messageLength < MessageLength15Base { @@ -115,7 +115,7 @@ func (c *Coder) Encode(m message.Message, buf []byte) (int, error) { } // Length and TKL nibbles. - hdr[hdrOff] = uint8(0xf&len(m.Token)) | (lenNib << 4) + hdr[hdrOff] = math.CastTo[uint8](len(m.Token)) | (lenNib << 4) hdrOff++ // Extended length, if present.