github.com/jshiv/can-go@v0.2.1-0.20210224011015-069e90e90bdf/pkg/cantext/encode.go (about)

     1  package cantext
     2  
     3  import (
     4  	"strconv"
     5  
     6  	"go.einride.tech/can"
     7  	"go.einride.tech/can/pkg/descriptor"
     8  	"go.einride.tech/can/pkg/generated"
     9  )
    10  
    11  // preAllocatedBytesPerSignal is an estimate of how many bytes each signal needs.
    12  const preAllocatedBytesPerSignal = 40
    13  
    14  func MessageString(m generated.Message) string {
    15  	return string(MarshalCompact(m))
    16  }
    17  
    18  func MarshalCompact(m generated.Message) []byte {
    19  	f := m.Frame()
    20  	buf := make([]byte, 0, len(m.Descriptor().Signals)*preAllocatedBytesPerSignal)
    21  	buf = append(buf, "{"...)
    22  	for i, s := range m.Descriptor().Signals {
    23  		buf = AppendSignalCompact(buf, s, f.Data)
    24  		if i != len(m.Descriptor().Signals)-1 {
    25  			buf = append(buf, ", "...)
    26  		}
    27  	}
    28  	buf = append(buf, "}"...)
    29  	return buf
    30  }
    31  
    32  func Marshal(m generated.Message) []byte {
    33  	f := m.Frame()
    34  	// allocate space for one "extra" signal to account for message header
    35  	buf := make([]byte, 0, (len(m.Descriptor().Signals)+1)*preAllocatedBytesPerSignal)
    36  	buf = append(buf, m.Descriptor().Name...)
    37  	for _, s := range m.Descriptor().Signals {
    38  		buf = append(buf, "\n\t"...)
    39  		buf = AppendSignal(buf, s, f.Data)
    40  	}
    41  	return buf
    42  }
    43  
    44  func AppendSignal(buf []byte, s *descriptor.Signal, d can.Data) []byte {
    45  	buf = append(buf, s.Name...)
    46  	buf = append(buf, ": "...)
    47  	switch {
    48  	case s.Length == 1: // bool
    49  		val := s.UnmarshalBool(d)
    50  		buf = strconv.AppendBool(buf, val)
    51  	case s.IsSigned: // signed
    52  		buf = strconv.AppendFloat(buf, s.UnmarshalPhysical(d), 'g', -1, 64)
    53  		buf = append(buf, s.Unit...)
    54  		buf = append(buf, " ("...)
    55  		buf = append(buf, "0x"...)
    56  		buf = strconv.AppendUint(buf, uint64(s.UnmarshalSigned(d)), 16)
    57  		buf = append(buf, ')')
    58  	default: // unsigned
    59  		buf = strconv.AppendFloat(buf, s.UnmarshalPhysical(d), 'g', -1, 64)
    60  		buf = append(buf, s.Unit...)
    61  		buf = append(buf, " ("...)
    62  		buf = append(buf, "0x"...)
    63  		buf = strconv.AppendUint(buf, s.UnmarshalUnsigned(d), 16)
    64  		buf = append(buf, ")"...)
    65  	}
    66  	if vd, ok := s.UnmarshalValueDescription(d); ok {
    67  		buf = append(buf, ' ')
    68  		buf = append(buf, vd...)
    69  	}
    70  	return buf
    71  }
    72  
    73  func AppendSignalCompact(buf []byte, s *descriptor.Signal, d can.Data) []byte {
    74  	buf = append(buf, s.Name...)
    75  	buf = append(buf, ": "...)
    76  	valueDescription, hasValueDescription := s.UnmarshalValueDescription(d)
    77  	switch {
    78  	case hasValueDescription:
    79  		buf = append(buf, valueDescription...)
    80  	case s.Length == 1: // bool
    81  		val := s.UnmarshalBool(d)
    82  		buf = strconv.AppendBool(buf, val)
    83  	case s.IsSigned: // signed
    84  		buf = strconv.AppendFloat(buf, s.UnmarshalPhysical(d), 'g', -1, 64)
    85  		buf = append(buf, s.Unit...)
    86  	default: // unsigned
    87  		buf = strconv.AppendFloat(buf, s.UnmarshalPhysical(d), 'g', -1, 64)
    88  		buf = append(buf, s.Unit...)
    89  	}
    90  	return buf
    91  }
    92  
    93  func AppendID(buf []byte, m *descriptor.Message) []byte {
    94  	buf = append(buf, "ID: "...)
    95  	buf = strconv.AppendUint(buf, uint64(m.ID), 10)
    96  	buf = append(buf, " (0x"...)
    97  	buf = strconv.AppendUint(buf, uint64(m.ID), 16)
    98  	buf = append(buf, ")"...)
    99  	return buf
   100  }
   101  
   102  func AppendSender(buf []byte, m *descriptor.Message) []byte {
   103  	return appendAttributeString(buf, "Sender", m.SenderNode)
   104  }
   105  
   106  func AppendSendType(buf []byte, m *descriptor.Message) []byte {
   107  	return appendAttributeString(buf, "SendType", m.SendType.String())
   108  }
   109  
   110  func AppendCycleTime(buf []byte, m *descriptor.Message) []byte {
   111  	return appendAttributeString(buf, "CycleTime", m.CycleTime.String())
   112  }
   113  
   114  func AppendDelayTime(buf []byte, m *descriptor.Message) []byte {
   115  	return appendAttributeString(buf, "DelayTime", m.DelayTime.String())
   116  }
   117  
   118  func AppendFrame(buf []byte, f can.Frame) []byte {
   119  	return appendAttributeString(buf, "Frame", f.String())
   120  }
   121  
   122  func appendAttributeString(buf []byte, name string, s string) []byte {
   123  	buf = append(buf, name...)
   124  	buf = append(buf, ": "...)
   125  	buf = append(buf, s...)
   126  	return buf
   127  }