github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/internal/body/body.go (about)

     1  package body
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"io"
     7  	"log"
     8  
     9  	"github.com/volts-dev/dataset"
    10  	"github.com/volts-dev/volts/codec"
    11  )
    12  
    13  type (
    14  	// NOTED 不提供IO Reader/Writer/Closer
    15  	TBody struct {
    16  		Data  *bytes.Buffer // 存储已经编码的数据
    17  		Codec codec.ICodec
    18  		len   int
    19  	}
    20  )
    21  
    22  func (self *TBody) Reset() error {
    23  	self.Data.Reset()
    24  	return nil
    25  }
    26  
    27  func New(coder codec.ICodec, data ...interface{}) *TBody {
    28  	if coder == nil {
    29  		coder = codec.IdentifyCodec(codec.Bytes)
    30  	}
    31  
    32  	bd := &TBody{
    33  		Data:  &bytes.Buffer{},
    34  		Codec: coder,
    35  	}
    36  
    37  	if data != nil {
    38  		bd.Encode(data[0])
    39  	}
    40  
    41  	return bd
    42  }
    43  
    44  // 读取原始数据或者编码数据
    45  func (self *TBody) _Read(p []byte) (int, error) {
    46  	return self.Data.Read(p)
    47  }
    48  
    49  // as ioreader
    50  func (self *TBody) __Read(p []byte) (int, error) {
    51  	if self.Codec != nil {
    52  		cnt, err := self.Data.Read(p)
    53  		if err != nil && err != io.EOF {
    54  			return 0, err
    55  		}
    56  
    57  		raw := make([]byte, 0, len(p)*2) // 必须保留有解码后长度增加的空间
    58  		err = self.Codec.Decode(p[0:cnt], &raw)
    59  		if err != nil {
    60  			return 0, err
    61  		}
    62  
    63  		n := copy(p, raw[0:])
    64  		if cnt < len(p) {
    65  			return n, io.EOF
    66  		}
    67  		return n, nil
    68  	}
    69  
    70  	return self.Data.Read(p)
    71  }
    72  
    73  // 写入原始数据或者编码数据
    74  func (self *TBody) _Write(p []byte) (n int, err error) {
    75  	return self.Data.Write(p)
    76  }
    77  
    78  // 写入原始数据转编码数据
    79  func (self *TBody) __Write(p []byte) (n int, err error) {
    80  	if self.Codec != nil {
    81  		data, err := self.Codec.Encode(p)
    82  		if err != nil {
    83  			return 0, err
    84  		}
    85  
    86  		return self.Data.Write(data)
    87  	}
    88  
    89  	return self.Data.Write(p)
    90  }
    91  
    92  // mapping to data type
    93  func (self *TBody) Decode(out interface{}) (err error) {
    94  	if self.Codec != nil {
    95  		return self.Codec.Decode(self.Data.Bytes(), out)
    96  	}
    97  
    98  	return errors.New("body not support convert to this type")
    99  }
   100  
   101  func (self *TBody) Encode(in interface{}) (int, error) {
   102  	if self.Codec != nil {
   103  		data, err := self.Codec.Encode(in)
   104  		if err != nil {
   105  			return 0, err
   106  		}
   107  
   108  		return self.Data.Write(data)
   109  	}
   110  	return 0, errors.New("body not support convert to this type")
   111  }
   112  
   113  func (self *TBody) AsBuffer() *bytes.Buffer {
   114  	return bytes.NewBuffer(self.AsBytes())
   115  }
   116  
   117  // the boady data in bytes
   118  func (self *TBody) AsBytes() (res []byte) {
   119  	if self.Codec != nil {
   120  		err := self.Codec.Decode(self.Data.Bytes(), &res)
   121  		if err != nil {
   122  			// NOTED it should not happen!
   123  			log.Panic(err)
   124  		}
   125  		return res
   126  	}
   127  
   128  	return self.Data.Bytes()
   129  }
   130  
   131  // TODO 优化
   132  // 根据序列强制转换为Map
   133  func (self *TBody) AsMap(c ...codec.SerializeType) (map[string]interface{}, error) {
   134  	if c != nil {
   135  		self.Codec = codec.IdentifyCodec(c[0])
   136  	}
   137  
   138  	if self.Codec != nil {
   139  		result := make(map[string]interface{})
   140  		err := self.Codec.Decode(self.Data.Bytes(), &result)
   141  		if err != nil {
   142  			return nil, err
   143  		}
   144  
   145  		return result, err
   146  	}
   147  
   148  	return nil, errors.New("Must input the serialize type")
   149  }
   150  
   151  // 根据序列强制转换为TRecordSet
   152  // 默认为codec.JSON
   153  func (self *TBody) AsRecordset(c ...codec.SerializeType) (rec *dataset.TRecordSet, err error) {
   154  	if c != nil {
   155  		self.Codec = codec.IdentifyCodec(c[0])
   156  	} else if self.Codec == nil {
   157  		self.Codec = codec.IdentifyCodec(codec.JSON)
   158  	}
   159  
   160  	m := make(map[string]interface{})
   161  	err = self.Codec.Decode(self.Data.Bytes(), &m)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  	return dataset.NewRecordSet(m), err
   166  }