github.com/s7techlab/cckit@v0.10.5/convert/from_bytes.go (about)

     1  package convert
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  	"strconv"
     8  
     9  	"github.com/golang/protobuf/proto"
    10  	"github.com/hyperledger/fabric-chaincode-go/shim"
    11  	"github.com/hyperledger/fabric-protos-go/peer"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  // FromBytes converts []byte to target interface
    16  func FromBytes(bb []byte, target interface{}) (result interface{}, err error) {
    17  	// create copy
    18  
    19  	switch t := target.(type) {
    20  	case string:
    21  		return string(bb), nil
    22  	case []byte:
    23  		return bb, nil
    24  	case int:
    25  		return strconv.Atoi(string(bb))
    26  	case bool:
    27  		return strconv.ParseBool(string(bb))
    28  	case []string:
    29  		arrInterface, err := JSONUnmarshalPtr(bb, &target)
    30  
    31  		if err != nil {
    32  			return nil, err
    33  		}
    34  		var arrString []string
    35  		for _, v := range arrInterface.([]interface{}) {
    36  			arrString = append(arrString, v.(string))
    37  		}
    38  		return arrString, nil
    39  
    40  	case FromByter:
    41  		return t.FromBytes(bb)
    42  
    43  	case proto.Message:
    44  		return ProtoUnmarshal(bb, t)
    45  
    46  	default:
    47  		return FromBytesToStruct(bb, target)
    48  	}
    49  
    50  }
    51  
    52  // FromBytesToStruct converts []byte to struct,array,slice depending on target type
    53  func FromBytesToStruct(bb []byte, target interface{}) (result interface{}, err error) {
    54  	if bb == nil {
    55  		return nil, ErrUnableToConvertNilToStruct
    56  	}
    57  	targetType := reflect.TypeOf(target).Kind()
    58  
    59  	switch targetType {
    60  	case reflect.Struct:
    61  		fallthrough
    62  	case reflect.Array:
    63  		fallthrough
    64  	case reflect.Slice:
    65  		// will be map[string]interface{}
    66  		return JSONUnmarshalPtr(bb, &target)
    67  	case reflect.Ptr:
    68  		return JSONUnmarshalPtr(bb, target)
    69  
    70  	default:
    71  		return nil, fmt.Errorf(
    72  			`fromBytes converting supports ToByter interface,struct,array,slice and string, current type is %s`,
    73  			targetType)
    74  	}
    75  }
    76  
    77  // JsonUnmarshalPtr unmarshalls []byte as json to pointer, and returns value pointed to
    78  func JSONUnmarshalPtr(bb []byte, to interface{}) (result interface{}, err error) {
    79  	targetPtr := reflect.New(reflect.ValueOf(to).Elem().Type()).Interface()
    80  	err = json.Unmarshal(bb, targetPtr)
    81  	if err != nil {
    82  		return nil, fmt.Errorf(ErrUnableToConvertValueToStruct.Error())
    83  	}
    84  	return reflect.Indirect(reflect.ValueOf(targetPtr)).Interface(), nil
    85  }
    86  
    87  // ProtoUnmarshal r unmarshalls []byte as proto.Message to pointer, and returns value pointed to
    88  func ProtoUnmarshal(bb []byte, messageType proto.Message) (message proto.Message, err error) {
    89  	msg := proto.Clone(messageType)
    90  	err = proto.Unmarshal(bb, msg)
    91  	if err != nil {
    92  		return nil, errors.Wrap(err, ErrUnableToConvertValueToStruct.Error())
    93  	}
    94  	return msg, nil
    95  }
    96  
    97  // FromResponse converts response.Payload to target
    98  func FromResponse(response peer.Response, target interface{}) (result interface{}, err error) {
    99  	if response.Status == shim.ERROR {
   100  		return nil, errors.New(response.Message)
   101  	}
   102  	return FromBytes(response.Payload, target)
   103  }