github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/encoding/kson/ksonv2_test.go (about) 1 package kson 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "reflect" 7 "testing" 8 "time" 9 "unsafe" 10 ) 11 12 func MarshalTcpPacketV2(o *TcpPacket) (b []byte, err error) { 13 //timeb,err:=o.Time.MarshalBinary() //13.73% 14 //if err!=nil{ 15 // return nil,err 16 //} 17 //timeBSize:=len(timeb) 18 srcIpSize := len(o.SrcIp) 19 dstIpSize := len(o.DstIp) 20 //size:=1+timeBSize+1+srcIpSize+2+1+ dstIpSize +2+4+4 21 size := 1 + srcIpSize + 2 + 1 + dstIpSize + 2 + 4 + 4 22 b = make([]byte, size) // 24.44% 23 pos := 0 24 //b[pos] = byte(timeBSize) 25 //pos++ 26 //copy(b[pos:pos+timeBSize],timeb) 27 //pos+=timeBSize 28 29 b[pos] = byte(srcIpSize) 30 pos++ 31 copy(b[pos:pos+srcIpSize], o.SrcIp) 32 pos += srcIpSize 33 34 b[pos] = byte(o.SrcPort) 35 b[pos+1] = byte(o.SrcPort >> 8) 36 //binary.LittleEndian.PutUint16(b[pos:pos+2],o.SrcPort) 37 pos += 2 38 39 b[pos] = byte(dstIpSize) 40 pos++ 41 copy(b[pos:pos+srcIpSize], o.SrcIp) 42 pos += dstIpSize 43 44 b[pos] = byte(o.DstPort) 45 b[pos+1] = byte(o.DstPort >> 8) 46 //binary.LittleEndian.PutUint16(b[pos:pos+2],o.DstPort) 47 pos += 2 48 49 b[pos] = byte(o.Seq) 50 b[pos+1] = byte(o.Seq >> 8) 51 b[pos+2] = byte(o.Seq >> 16) 52 b[pos+3] = byte(o.Seq >> 24) 53 //binary.LittleEndian.PutUint32(b[pos:pos+4],o.Seq) 54 pos += 4 55 56 b[pos] = byte(o.Ack) 57 b[pos+1] = byte(o.Ack >> 8) 58 b[pos+2] = byte(o.Ack >> 16) 59 b[pos+3] = byte(o.Ack >> 24) 60 //binary.LittleEndian.PutUint32(b[pos:pos+4],o.Ack) 61 pos += 4 62 63 return b, nil 64 } 65 66 func MarshalTcpPacketV2ToBuffer(o *TcpPacket, b []byte) (err error) { 67 //timeb,err:=o.Time.MarshalBinary() //13.73% 68 //if err!=nil{ 69 // return err 70 //} 71 //timeBSize:=len(timeb) 72 srcIpSize := len(o.SrcIp) 73 dstIpSize := len(o.DstIp) 74 //size:=1+timeBSize+1+srcIpSize+2+1+ dstIpSize +2+4+4 75 size := 1 + srcIpSize + 2 + 1 + dstIpSize + 2 + 4 + 4 76 if len(b) < size { 77 return fmt.Errorf("[MarshalTcpPacketV2ToBuffer] too small buffer") 78 } 79 pos := 0 80 //b[pos] = byte(timeBSize) 81 //pos++ 82 //copy(b[pos:pos+timeBSize],timeb) 83 //pos+=timeBSize 84 85 b[pos] = byte(srcIpSize) 86 pos++ 87 copy(b[pos:pos+srcIpSize], o.SrcIp) 88 pos += srcIpSize 89 90 b[pos] = byte(o.SrcPort) 91 b[pos+1] = byte(o.SrcPort >> 8) 92 //binary.LittleEndian.PutUint16(b[pos:pos+2],o.SrcPort) 93 pos += 2 94 95 b[pos] = byte(dstIpSize) 96 pos++ 97 copy(b[pos:pos+srcIpSize], o.SrcIp) 98 pos += dstIpSize 99 100 b[pos] = byte(o.DstPort) 101 b[pos+1] = byte(o.DstPort >> 8) 102 //binary.LittleEndian.PutUint16(b[pos:pos+2],o.DstPort) 103 pos += 2 104 105 b[pos] = byte(o.Seq) 106 b[pos+1] = byte(o.Seq >> 8) 107 b[pos+2] = byte(o.Seq >> 16) 108 b[pos+3] = byte(o.Seq >> 24) 109 //binary.LittleEndian.PutUint32(b[pos:pos+4],o.Seq) 110 pos += 4 111 112 b[pos] = byte(o.Ack) 113 b[pos+1] = byte(o.Ack >> 8) 114 b[pos+2] = byte(o.Ack >> 16) 115 b[pos+3] = byte(o.Ack >> 24) 116 //binary.LittleEndian.PutUint32(b[pos:pos+4],o.Ack) 117 pos += 4 118 119 return nil 120 } 121 122 func UnmarshalTcpPacketV2(b []byte) (packet TcpPacket, err error) { 123 packet = TcpPacket{} // 13.73% 124 pos := 0 125 //timeSize:=b[pos] 126 //pos++ 127 //err = packet.Time.UnmarshalBinary(b[pos:pos+int(timeSize)]) //4.39% 128 //if err!=nil{ 129 // return packet,err 130 //} 131 //pos+=int(timeSize) 132 133 sSize := b[pos] 134 packet.SrcIp = BytesToString(b[pos : pos+int(sSize)]) //12.48% 135 pos += int(sSize) 136 137 packet.SrcPort = binary.LittleEndian.Uint16(b[pos : pos+2]) 138 pos += 2 139 140 sSize = b[pos] 141 packet.DstIp = BytesToString(b[pos : pos+int(sSize)]) 142 pos += int(sSize) 143 144 packet.DstPort = binary.LittleEndian.Uint16(b[pos : pos+2]) 145 pos += 2 146 147 packet.Seq = binary.LittleEndian.Uint32(b[pos : pos+4]) 148 pos += 4 149 150 packet.Ack = binary.LittleEndian.Uint32(b[pos : pos+4]) 151 pos += 4 152 return packet, nil 153 } 154 155 func BytesToString(b []byte) string { 156 bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) 157 sh := reflect.StringHeader{bh.Data, bh.Len} 158 return *(*string)(unsafe.Pointer(&sh)) 159 } 160 161 func StringToBytes(s string) []byte { 162 sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) 163 bh := reflect.SliceHeader{sh.Data, sh.Len, 0} 164 return *(*[]byte)(unsafe.Pointer(&bh)) 165 } 166 167 func BenchmarkKsonV2Marshal(b *testing.B) { 168 data := &TcpPacket{ 169 Time: time.Now().In(time.UTC), 170 SrcIp: "1.2.3.4", 171 DstIp: "1.2.3.4", 172 } 173 total := 0 174 buf := make([]byte, 4096) 175 b.ResetTimer() 176 for i := 0; i < b.N; i++ { 177 err := MarshalTcpPacketV2ToBuffer(data, buf) 178 if err != nil { 179 panic(err) 180 } 181 //total += len(buf) 182 } 183 b.SetBytes(int64(total / b.N)) 184 } 185 186 func BenchmarkKsonV2Unmarshal(b *testing.B) { 187 data := &TcpPacket{ 188 Time: time.Now().In(time.UTC), 189 SrcIp: "1.2.3.4", 190 DstIp: "1.2.3.4", 191 } 192 buf, err := MarshalTcpPacketV2(data) 193 if err != nil { 194 panic(err) 195 } 196 b.SetBytes(int64(len(buf))) 197 b.ResetTimer() 198 for i := 0; i < b.N; i++ { 199 _, err := UnmarshalTcpPacketV2(buf) 200 if err != nil { 201 panic(err) 202 } 203 } 204 }