ååãåºå®ãããã¼ã表ãstructã®å®è£ ã«çæãã¾ããã
// fixed_header.go package packet type FixedHeader { PacketType byte } func ToFixedHeader(bs []byte) FixedHeader { b := bs[0] packetType := b >> 4 return FixedHeader{packetType} }
ããããã®ç¶ãã§ããGoã§ã®éçºã§ä¾¿å©ãããªgo vet, gofmtã¨ãã£ãã³ãã³ãã試ãã¦ã¿ã¾ãã
ç®æ¬¡ã
MQTTåºå®ãããã¼
MQTTã®åºå®ãããã¼ã¯ä»¥ä¸ã®ãããªãã©ã¼ãããã«ãªã£ã¦ãã
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
byte1 | MQTT Control Packet type | Flags specific to each MQTT Control Packet type | ||||||
byte2... | Remaining Length |
MQTT Control Packet type
ãå®è£
ããã®ã§ã次㯠Flags specific to each MQTT Control Packet type
ã«çæããããã®å¾ã Remaining Length
ã
Flags
ããã¯ãµã¯ãã¨ã
fixed_header_test.go
want packet.FixedHeader }{ { - "Reserved", - args{[]byte{0x00, 0x00}}, - packet.FixedHeader{0}, + "Reserved Dup:0 QoS:00 Retain:0", + args{[]byte{0x00, 0x00}}, // 0000 0 00 0 + packet.FixedHeader{PacketType: 0, Dup: 0, QoS1: 0, QoS2: 0, Retain: 0}, }, { - "CONNECT", - args{[]byte{0x10, 0x00}}, - packet.FixedHeader{1}, + "CONNECT Dup:1 QoS:01 Retain:1", + args{[]byte{0x1B, 0x00}}, // 0001 1 01 1 + packet.FixedHeader{PacketType: 1, Dup: 1, QoS1: 0, QoS2: 1, Retain: 1}, }, { - "CONNACK", - args{[]byte{0x20, 0x00}}, - packet.FixedHeader{2}, + "CONNACK Dup:0 QoS:10 Retain:1", + args{[]byte{0x24, 0x00}}, // 0002 0 10 0 + packet.FixedHeader{PacketType: 2, Dup: 0, QoS1: 1, QoS2: 0, Retain: 0}, }, } for _, tt := range tests {
fixed_header.go
type FixedHeader struct { PacketType byte + Dup byte + QoS1 byte + QoS2 byte + Retain byte } func ToFixedHeader(bs []byte) FixedHeader { b := bs[0] packetType := b >> 4 - return FixedHeader{packetType} + dup := refbit(bs[0], 3) + qos1 := refbit(bs[0], 2) + qos2 := refbit(bs[0], 1) + retain := refbit(bs[0], 0) + return FixedHeader{ + PacketType: packetType, + Dup: dup, + QoS1: qos1, + QoS2: qos2, + Retain: retain, + } +} + +func refbit(b byte, n uint) byte { + return (b >> n) & 1 }
Remining Length
次ã¯ãåºå®ãããã¼ã®2ãã¤ãç®ã表ãã¦ããRemining LengthãRemining Lengthã¯ãåºå®ãããã¼ã«ç¶ããå¯å¤ãããã¼ãããã¤ãã¼ããã®ãµã¤ãºãåè¨ã§ä½ãã¤ããªã®ãã示ãã
ããã¥ã¡ã³ãã«encodeã¨decodeã®ã¢ã«ã´ãªãºã ãæ¸ãã¦ããã
ããã¥ã¡ã³ããåèã«ãã¹ãã³ã¼ããä¿®æ£ã
fixed_header_test.go
want packet.FixedHeader }{ { - "Reserved Dup:0 QoS:00 Retain:0", - args{[]byte{0x00, 0x00}}, // 0000 0 00 0 - packet.FixedHeader{PacketType: 0, Dup: 0, QoS1: 0, QoS2: 0, Retain: 0}, + "Reserved Dup:0 QoS:00 Retain:0 RemainingLength:0", + args{[]byte{ + 0x00, // 0000 0 00 0 + 0x00, // 0 + }}, + packet.FixedHeader{PacketType: 0, Dup: 0, QoS1: 0, QoS2: 0, Retain: 0, RemainingLength: 0}, }, { - "CONNECT Dup:1 QoS:01 Retain:1", - args{[]byte{0x1B, 0x00}}, // 0001 1 01 1 - packet.FixedHeader{PacketType: 1, Dup: 1, QoS1: 0, QoS2: 1, Retain: 1}, + "CONNECT Dup:1 QoS:01 Retain:1 RemainingLength:127", + args{[]byte{ + 0x1B, // 0001 1 01 1 + 0x7F, // 127 + }}, + packet.FixedHeader{PacketType: 1, Dup: 1, QoS1: 0, QoS2: 1, Retain: 1, RemainingLength: 127}, }, { - "CONNACK Dup:0 QoS:10 Retain:1", - args{[]byte{0x24, 0x00}}, // 0002 0 10 0 - packet.FixedHeader{PacketType: 2, Dup: 0, QoS1: 1, QoS2: 0, Retain: 0}, + "CONNACK Dup:0 QoS:10 Retain:1 RemainingLength:128", + args{[]byte{ + 0x24, // 0002 0 10 0 + 0x80, 0x01, //128 + }}, + packet.FixedHeader{PacketType: 2, Dup: 0, QoS1: 1, QoS2: 0, Retain: 0, RemainingLength: 128}, }, } for _, tt := range tests {
ã³ã³ãã¤ã«ãéãããã«ä¿®æ£ã
fixed_header.go
package packet type FixedHeader struct { - PacketType byte - Dup byte - QoS1 byte - QoS2 byte - Retain byte + PacketType byte + Dup byte + QoS1 byte + QoS2 byte + Retain byte + RemainingLength uint } func ToFixedHeader(bs []byte) FixedHeader {
ãã¹ãå®è¡ã
$ go test ./packet/fixed_header_test.go --- FAIL: TestToFixedHeader (0.00s) --- FAIL: TestToFixedHeader/CONNECT_Dup:1_QoS:01_Retain:1_RemainingLength:127 (0.00s) fixed_header_test.go:47: ToFixedHeader() = {1 1 0 1 1 0}, want {1 1 0 1 1 127} --- FAIL: TestToFixedHeader/CONNACK_Dup:0_QoS:10_Retain:1_RemainingLength:128 (0.00s) fixed_header_test.go:47: ToFixedHeader() = {2 0 1 0 0 0}, want {2 0 1 0 0 128} FAIL FAIL command-line-arguments 0.019s
ã¾ã å®è£ ãã¦ãªãã®ã§å¤±æãããã¥ã¡ã³ããåèã«decodeããå¦çã追å ã
fixed_header.go
qos1 := refbit(bs[0], 2) qos2 := refbit(bs[0], 1) retain := refbit(bs[0], 0) + remainingLength := decodeRemainingLength(bs[1:]) return FixedHeader{ - PacketType: packetType, - Dup: dup, - QoS1: qos1, - QoS2: qos2, - Retain: retain, + PacketType: packetType, + Dup: dup, + QoS1: qos1, + QoS2: qos2, + Retain: retain, + RemainingLength: remainingLength, } } func refbit(b byte, n uint) byte { return (b >> n) & 1 } + +func decodeRemainingLength(bs []byte) uint { + multiplier := uint(1) + var value uint + i := uint(0) + for ; i < 8; i++ { + b := bs[i] + digit := b + value = value + uint(digit&127)*multiplier + multiplier = multiplier * 128 + if (digit & 128) == 0 { + break + } + } + return value +}
ãã¹ãå®è¡ã
$ go test ./packet/fixed_header_test.go ok command-line-arguments 2.739s
OKOKã
ãã¹ãã±ã¼ã¹ã® name
ãæ¸ãã®ãé¢åãªã®ã§ãªãã¡ã¯ã¿ãªã³ã°ã
fmt.Sprintf
ã使ã£ã¦ã want
ã§æå®ãã¦ãstructããã¹ãã±ã¼ã¹ã® name
ã®ä»£ããã«ä½¿ãã
diff --git a/study/packet/fixed_header_test.go b/study/packet/fixed_header_test.go index 2670823..ed086a2 100644 --- a/study/packet/fixed_header_test.go +++ b/study/packet/fixed_header_test.go @@ -1,6 +1,7 @@ package packet_test import ( + "fmt" "reflect" "testing" @@ -12,12 +13,10 @@ func TestToFixedHeader(t *testing.T) { bs []byte } tests := []struct { - name string args args want packet.FixedHeader }{ { - "Reserved Dup:0 QoS:00 Retain:0 RemainingLength:0", args{[]byte{ 0x00, // 0000 0 00 0 0x00, // 0 @@ -25,7 +24,6 @@ func TestToFixedHeader(t *testing.T) { packet.FixedHeader{PacketType: 0, Dup: 0, QoS1: 0, QoS2: 0, Retain: 0, RemainingLength: 0}, }, { - "CONNECT Dup:1 QoS:01 Retain:1 RemainingLength:127", args{[]byte{ 0x1B, // 0001 1 01 1 0x7F, // 127 @@ -33,7 +31,6 @@ func TestToFixedHeader(t *testing.T) { packet.FixedHeader{PacketType: 1, Dup: 1, QoS1: 0, QoS2: 1, Retain: 1, RemainingLength: 127}, }, { - "CONNACK Dup:0 QoS:10 Retain:1 RemainingLength:128", args{[]byte{ 0x24, // 0002 0 10 0 0x80, 0x01, //128 @@ -42,7 +39,7 @@ func TestToFixedHeader(t *testing.T) { }, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + t.Run(fmt.Sprintf("%#v", tt.args.bs), func(t *testing.T) { if got := packet.ToFixedHeader(tt.args.bs); !reflect.DeepEqual(got, tt.want) { t.Errorf("ToFixedHeader() = %v, want %v", got, tt.want) }
以ä¸ã®ããã«ãã¹ãåã« []byte{0x23,_0x80,_0x1}
ã¨ãããããªæãã§åºåãããã
$ go test -v ./packet/fixed_header_test.go === RUN TestToFixedHeader === RUN TestToFixedHeader/[]byte{0x0,_0x0} === RUN TestToFixedHeader/[]byte{0x1b,_0x7f} === RUN TestToFixedHeader/[]byte{0x24,_0x80,_0x1} --- PASS: TestToFixedHeader (0.00s) --- PASS: TestToFixedHeader/[]byte{0x0,_0x0} (0.00s) --- PASS: TestToFixedHeader/[]byte{0x1b,_0x7f} (0.00s) --- PASS: TestToFixedHeader/[]byte{0x24,_0x80,_0x1} (0.00s) PASS ok command-line-arguments 1.299s
go vet
fmt.Sprintf
ã¯ããã便å©ãªã®ã ãã©ãä¾ãã° fmt.Sprinf("x is %v")
ã¨ããããã«ç¬¬2å¼æ°ãæå®ãå¿ãã¦ããã¨ãã¦ãã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªããããã¹ã«æ°ãã¤ãã«ããã
go vet
ã¨ããã³ãã³ãã使ãã¨ããããããã¹ãææãã¦ãããã
ãã£ãã®ãã¹ãã³ã¼ãã§ããã¨ééãã¦ã¿ãã
}, } for _, tt := range tests { - t.Run(fmt.Sprintf("%#v", tt.args.bs), func(t *testing.T) { + t.Run(fmt.Sprintf("%#v"), func(t *testing.T) { if got := packet.ToFixedHeader(tt.args.bs); !reflect.DeepEqual(got, tt.want) { t.Errorf("ToFixedHeader() = %v, want %v", got, tt.want) }
$ go vet ./packet/ # github.com/bati11/oreno-mqtt/packet_test packet/fixed_header_test.go:42: Sprintf format %#v reads arg #1, but call has 0 args
ããã¯å©ããï¼ä»ã«ã©ããªãã§ãã¯ããã¦ãããã®ãã¯ä»¥ä¸ã®ãã¼ã¸ãåç §ã
å®ã¯Go1.10ãã㯠go test
å®è¡æã«ãvetã®é
ç®ã®ãã¡ã®ããã¤ãããã§ãã¯ãã¦ãããããã«ãªã£ããããã
試ãã« fmt.Sprintf
ã®ç¬¬2å¼æ°ã渡ãã¦ãªãç¶æ
㧠go test
ãã¦ã¿ãã
$ go test ./packet/ # github.com/bati11/oreno-mqtt/packet_test packet/fixed_header_test.go:42: Sprintf format %#v reads arg #1, but call has 0 args FAIL github.com/bati11/oreno-mqtt/study/packet [build failed]
è¯ãã
gofmt
ã次ã¯ãã©ã¼ããã¿ã¼ã
gofmt
ã³ãã³ãã¨ã¯å¥ã« go fmt
ã¨ããã®ããããä½ãæ´å²çãªçµç·¯ãããã®ã ããããã¡ãªã¿ã« gofmt -l -w
㨠go fmt
ã®çµæãåãã«ãªã£ãã
$ gofmt --help ... -l list files whose formatting differs from gofmt's ... -w write result to (source) file instead of stdout
gofmt
㯠-d
ãªãã·ã§ã³ã§å®éã«ãã¡ã¤ã«ããã©ã¼ãããããã«å·®åã®åºåã ããããã¨ãã§ããã®ã§CIã§ã使ãåæè¯ãããã
go doc
ã次ã¯ããã¥ã¡ã³ãã¼ã·ã§ã³ã2éãããã
godoc
ã³ãã³ãgo doc
ã¨ããããã«goã³ãã³ãã«docãæå®ããæ¹æ³ã®
ã¾ã㯠godoc
ããã以ä¸ã®ããã«å®è¡ããã
$ godoc -http=:6060
ãã©ã¦ã¶ã§ http://localhost:6060
ã«ã¢ã¯ã»ã¹ãããã¨ãã¤ãã®Goã®ç»é¢ãã
ãã¤ãã®ã¨éã£ã¦ãPackagesãèªåãä½ã£ãããã±ã¼ã¸ãç´ãã¦ã¾ããèªåãä½ã£ãããã±ã¼ã¸ã®ä»ã«ããã¼ã«ã«PCã®GOPATHã«ããããã±ã¼ã¸ãè¼ã£ã¦ã¾ãã
ããã¥ã¡ã³ãã®æ¸ãæ¹ã¯ä»¥ä¸ã®è¨äºãåèã«ãªãããã
èµ·åæã« $ godoc -http=:6060 -analysis=pointer -analysis=type
ã¨ããããã« analysis
ãªãã·ã§ã³ãã¤ãã¦ãã¨ã³ã¼ãã®è§£æããã¦ãããããã ããèµ·åã«æéãããã...ã
- https://qiita.com/lufia/items/97acb391c26f967048f1#%E9%9D%99%E7%9A%84%E8%A7%A3%E6%9E%90
- Static analysis features of godoc - The Go Programming Language
ããä¸æ¹ã® go doc
ï¼goã³ãã³ã+docãªãã·ã§ã³ï¼ã§ããããã¡ãã¯ã³ãã³ãã©ã¤ã³ã§Go Docã確èªã§ããã
çµæ§è²ã ããã¿ããããã¡ãã®è¨äºãåèã«ãªãã
ããã¾ã
FixedHeader
ã« ReminingLength
ãã£ã¼ã«ãã追å ãã¾ããããããã ToFixedHeader
ã«æ¸¡ã []byte
ã®ãã§ãã¯ããã¦ãªãã®ã§1ãã¤ãã®é
åãnilã渡ãã¨panicãã¦ãã¾ãã¾ãã次åã¯ããã®ã¨ã©ã¼ãã³ããªã³ã°ããèãããã¨ã«ãã¾ãã
ä»åã®å¦ã³
- MQTTã®åºå®ãããã¼ã®Remining Length
- go vet
- gofmt
- go doc