gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/ipc/cgo/shm-server/packet.go (about)

     1  package shmServer
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  )
     7  
     8  const (
     9  	minPacketLength    = 16
    10  	maxPacketLength    = 32
    11  	allocRequestLength = minPacketLength + 12
    12  )
    13  
    14  const magicCode = 0x20230805
    15  
    16  type Command uint16
    17  
    18  const (
    19  	CommandOpenRequest = Command(iota) + 1
    20  	CommandAllocRequest
    21  	CommandKeepaliveRequest
    22  	CommandCloseRequest
    23  )
    24  
    25  const (
    26  	CommandOpenResponse = Command(iota) + 1<<15
    27  	CommandAllocResponse
    28  	CommandKeepaliveResponse
    29  	CommandCloseResponse
    30  )
    31  
    32  type (
    33  	InvalidPacketLength  int
    34  	InvalidPacketMagic   uint64
    35  	InvalidPacketCommand Command
    36  )
    37  
    38  func (e InvalidPacketLength) Error() string {
    39  	return fmt.Sprintf("invalid packet length: %d", int(e))
    40  }
    41  
    42  func (e InvalidPacketMagic) Error() string {
    43  	return fmt.Sprintf("invalid packet magic code: %08x", uint32(e))
    44  }
    45  
    46  func (e InvalidPacketCommand) Error() string {
    47  	return fmt.Sprintf("invalid packet command: %d", uint16(e))
    48  }
    49  
    50  type BasePacket struct {
    51  	magic   uint32
    52  	command Command
    53  	seq     uint16
    54  }
    55  
    56  func (p *BasePacket) Unmarshal(data []byte) (error, ErrType) {
    57  	if len(data) < minPacketLength || len(data) > maxPacketLength {
    58  		return InvalidPacketLength(len(data)), ErrTypePacketInvalidLength
    59  	}
    60  	p.magic = binary.BigEndian.Uint32(data)
    61  	if p.magic != magicCode {
    62  		return InvalidPacketMagic(p.magic), ErrTypePacketInvalidMagic
    63  	}
    64  	p.command = Command(binary.BigEndian.Uint16(data[4:]))
    65  	if p.command < CommandOpenRequest || (p.command > CommandCloseRequest &&
    66  		p.command < CommandOpenResponse) || p.command > CommandCloseResponse {
    67  		return InvalidPacketCommand(p.command), ErrTypePacketInvalidCommand
    68  	}
    69  	p.seq = binary.BigEndian.Uint16(data[6:])
    70  	return nil, 0
    71  }
    72  
    73  type OpenRequest struct {
    74  	BasePacket
    75  }
    76  
    77  type AllocRequest struct {
    78  	BasePacket
    79  	chunk uint32
    80  	size  uint64
    81  }
    82  
    83  func (r *AllocRequest) Unmarshal(data []byte) (error, ErrType) {
    84  	if len(data) < allocRequestLength {
    85  		return InvalidPacketLength(len(data)), ErrTypePacketInvalidLength
    86  	}
    87  	r.chunk = binary.BigEndian.Uint32(data[minPacketLength:])
    88  	r.size = binary.BigEndian.Uint64(data[minPacketLength+4:])
    89  	return nil, 0
    90  }
    91  
    92  type KeepaliveRequest struct {
    93  	BasePacket
    94  }
    95  
    96  type CloseRequest struct {
    97  	BasePacket
    98  }
    99  
   100  type BaseResponse struct {
   101  	BasePacket
   102  	status uint32
   103  }
   104  
   105  type OpenResponse struct {
   106  }