Skip to content

Commit

Permalink
extended cast
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Klaban committed Dec 20, 2024
1 parent 5291e61 commit 9885c87
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 43 deletions.
76 changes: 47 additions & 29 deletions dlmsal/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func recast(trg reflect.Value, data *DlmsData) error {
_, isdlmstime := trg.Interface().(DlmsDateTime)
_, isobis := trg.Interface().(DlmsObis)
_, isdlmsdata := trg.Interface().(DlmsData)
_, isnumber := trg.Interface().(Number)
_, isvalue := trg.Interface().(Value)
if isdlmsdata {
trg.Set(reflect.ValueOf(*data))
return nil
Expand Down Expand Up @@ -85,8 +85,8 @@ func recast(trg reflect.Value, data *DlmsData) error {
}
return nil
}
if isnumber {
return recastnumber(trg, data)
if isvalue {
return recastvalue(trg, data)
}
switch {
case e == reflect.Pointer:
Expand Down Expand Up @@ -207,48 +207,66 @@ func recaststring(trg reflect.Value, data *DlmsData) error {
return fmt.Errorf("unexpected type %T", data.Value)
}

func recastnumber(trg reflect.Value, data *DlmsData) error {
number := Number{Type: UnsignedInt, UnsignedInt: 0}
switch v := data.Value.(type) {
func recastvalue(trg reflect.Value, data *DlmsData) error {
value := Value{Type: Unknown}
switch v := data.Value.(type) { // Tag should be also considered
case bool:
if v {
number.UnsignedInt = 1
}
value.Type = Boolean
value.Value = v
case int:
number.Type = SignedInt
number.SignedInt = int64(v)
value.Type = SignedInt
value.Value = int64(v)
case int8:
number.Type = SignedInt
number.SignedInt = int64(v)
value.Type = SignedInt
value.Value = int64(v)
case int16:
number.Type = SignedInt
number.SignedInt = int64(v)
value.Type = SignedInt
value.Value = int64(v)
case int32:
number.Type = SignedInt
number.SignedInt = int64(v)
value.Type = SignedInt
value.Value = int64(v)
case int64:
number.Type = SignedInt
number.SignedInt = v
value.Type = SignedInt
value.Value = v
case uint:
number.UnsignedInt = uint64(v)
value.Type = UnsignedInt
value.Value = uint64(v)
case uint8:
number.UnsignedInt = uint64(v)
value.Type = UnsignedInt
value.Value = uint64(v)
case uint16:
number.UnsignedInt = uint64(v)
value.Type = UnsignedInt
value.Value = uint64(v)
case uint32:
number.UnsignedInt = uint64(v)
value.Type = UnsignedInt
value.Value = uint64(v)
case uint64:
number.UnsignedInt = v
value.Type = UnsignedInt
value.Value = v
case float32:
number.Type = Real
number.Real = float64(v)
value.Type = Real
value.Value = float64(v)
case float64:
number.Type = Real
number.Real = v
value.Type = Real
value.Value = v
case string:
value.Type = String
value.Value = v
case []byte:
if len(v) == 12 {
d, err := NewDlmsDateTimeFromSlice(v)
if err == nil {
value.Type = DateTime
value.Value = d
break
}
}
value.Type = String
value.Value = string(v)
default:
return fmt.Errorf("unexpected type %T", data.Value)
}
trg.Set(reflect.ValueOf(number))
trg.Set(reflect.ValueOf(value))
return nil
}

Expand Down
41 changes: 27 additions & 14 deletions dlmsal/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,44 @@ import (
"time"
)

type NumberType byte
type ValueType byte

const (
SignedInt NumberType = 0
UnsignedInt NumberType = 1
Real NumberType = 2
SignedInt ValueType = 0 // int64
UnsignedInt ValueType = 1 // uint64
Real ValueType = 2 // float64
String ValueType = 3 // string
DateTime ValueType = 4 // DlmsDateTime
Boolean ValueType = 5 // bool
Unknown ValueType = 255 // nil
)

type Number struct {
Type NumberType
SignedInt int64
UnsignedInt uint64
Real float64
type Value struct {
Type ValueType
Value interface{}
}

func (n *Number) String() string {
func (n *Value) ToString() string {
switch n.Type {
case SignedInt:
return fmt.Sprintf("%d", n.SignedInt)
return fmt.Sprintf("%d", n.Value.(int64))
case UnsignedInt:
return fmt.Sprintf("%d", n.UnsignedInt)
return fmt.Sprintf("%d", n.Value.(uint64))
case Real:
return fmt.Sprintf("%f", n.Real)
return fmt.Sprintf("%f", n.Value.(float64))
case String:
return n.Value.(string)
case DateTime:
v := n.Value.(DlmsDateTime)
r, err := v.ToTime()
if err != nil {
break
}
return r.String()
case Boolean:
return fmt.Sprintf("%t", n.Value.(bool))
}
return "invalid"
return "invalid" // questionable
}

type DlmsDateTime struct {
Expand Down

0 comments on commit 9885c87

Please sign in to comment.