2014-04-26 09:18:56 +00:00
package ICCC
2014-10-19 17:19:11 +00:00
import (
"fmt"
2015-06-21 18:18:23 +00:00
"github.com/SommerEngineering/Ocean/Log"
LM "github.com/SommerEngineering/Ocean/Log/Meta"
2014-10-19 17:19:11 +00:00
"reflect"
"strconv"
)
2014-04-26 09:18:56 +00:00
2015-06-17 15:44:52 +00:00
// Function to convert an ICCC message to HTTP data.
2015-06-21 18:18:23 +00:00
func Message2Data ( channel , command string , message interface { } ) ( data map [ string ] [ ] string ) {
defer func ( ) {
if err := recover ( ) ; err != nil {
Log . LogFull ( senderName , LM . CategorySYSTEM , LM . LevelERROR , LM . SeverityUnknown , LM . ImpactUnknown , LM . MessageNamePARSE , fmt . Sprintf ( "Was not able to convert the message to HTTP values. %s" , err ) )
data = make ( map [ string ] [ ] string , 0 )
return
}
} ( )
2015-06-17 15:44:52 +00:00
// Create the map:
2014-06-08 09:35:01 +00:00
data = make ( map [ string ] [ ] string )
2015-06-17 15:44:52 +00:00
// Add the meta information:
2014-06-08 09:35:01 +00:00
data [ ` command ` ] = [ ] string { command }
data [ ` channel ` ] = [ ] string { channel }
2014-04-26 09:18:56 +00:00
if message == nil {
return
}
2015-06-17 15:44:52 +00:00
// Use reflection to determine the types:
2014-04-26 09:18:56 +00:00
element := reflect . ValueOf ( message )
elementType := element . Type ( )
2015-06-17 15:44:52 +00:00
// Iterate over all fields of the data type.
// Transform the data regarding the type.
2014-04-26 09:18:56 +00:00
for i := 0 ; i < element . NumField ( ) ; i ++ {
field := element . Field ( i )
keyName := elementType . Field ( i ) . Name
switch field . Kind ( ) . String ( ) {
case ` int64 ` :
key := fmt . Sprintf ( ` int:%s ` , keyName )
data [ key ] = [ ] string { strconv . FormatInt ( field . Int ( ) , 10 ) }
case ` string ` :
key := fmt . Sprintf ( ` str:%s ` , keyName )
data [ key ] = [ ] string { field . String ( ) }
case ` float64 ` :
key := fmt . Sprintf ( ` f64:%s ` , keyName )
data [ key ] = [ ] string { strconv . FormatFloat ( field . Float ( ) , 'f' , 9 , 64 ) }
case ` bool ` :
key := fmt . Sprintf ( ` bool:%s ` , keyName )
data [ key ] = [ ] string { strconv . FormatBool ( field . Bool ( ) ) }
case ` uint8 ` : // byte
key := fmt . Sprintf ( ` ui8:%s ` , keyName )
data [ key ] = [ ] string { strconv . FormatUint ( field . Uint ( ) , 16 ) }
2015-06-17 15:44:52 +00:00
// Case: Arrays...
2014-04-26 09:18:56 +00:00
case ` slice ` :
sliceLen := field . Len ( )
if sliceLen > 0 {
sliceKind := field . Index ( 0 ) . Kind ( )
key := ` `
dataValues := make ( [ ] string , sliceLen , sliceLen )
switch sliceKind . String ( ) {
case ` uint8 ` : // bytes
key = fmt . Sprintf ( ` ui8[]:%s ` , keyName )
values := field . Interface ( ) . ( [ ] uint8 )
for index , value := range values {
dataValues [ index ] = strconv . FormatUint ( uint64 ( value ) , 16 )
}
case ` int64 ` :
key = fmt . Sprintf ( ` int[]:%s ` , keyName )
values := field . Interface ( ) . ( [ ] int64 )
for index , value := range values {
dataValues [ index ] = strconv . FormatInt ( value , 10 )
}
case ` bool ` :
key = fmt . Sprintf ( ` bool[]:%s ` , keyName )
values := field . Interface ( ) . ( [ ] bool )
for index , value := range values {
dataValues [ index ] = strconv . FormatBool ( value )
}
case ` string ` :
key = fmt . Sprintf ( ` str[]:%s ` , keyName )
values := field . Interface ( ) . ( [ ] string )
for index , value := range values {
dataValues [ index ] = value
}
case ` float64 ` :
key = fmt . Sprintf ( ` f64[]:%s ` , keyName )
values := field . Interface ( ) . ( [ ] float64 )
for index , value := range values {
dataValues [ index ] = strconv . FormatFloat ( value , 'f' , 9 , 64 )
}
}
data [ key ] = dataValues
}
}
}
return
}