Kaynağa Gözat

Fetch Query-Rows on Access

Fixes Issue #10
Julien Schmidt 13 yıl önce
ebeveyn
işleme
070215408a
5 değiştirilmiş dosya ile 283 ekleme ve 263 silme
  1. 11 5
      connection.go
  2. 208 216
      packets.go
  3. 48 9
      rows.go
  4. 10 25
      statement.go
  5. 6 8
      utils.go

+ 11 - 5
connection.go

@@ -208,7 +208,7 @@ func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, err
 		e
 }
 
-// Internal function to execute statements
+// Internal function to execute commands
 func (mc *mysqlConn) exec(query string) (e error) {
 	// Send command
 	e = mc.writeCommandPacket(COM_QUERY, query)
@@ -217,7 +217,8 @@ func (mc *mysqlConn) exec(query string) (e error) {
 	}
 
 	// Read Result
-	resLen, e := mc.readResultSetHeaderPacket()
+	var resLen int
+	resLen, e = mc.readResultSetHeaderPacket()
 	if e != nil {
 		return
 	}
@@ -258,13 +259,18 @@ func (mc *mysqlConn) getSystemVar(name string) (val string, e error) {
 			return
 		}
 
-		var rows []*[]*[]byte
-		rows, e = mc.readRows(int(n))
+		var row *[]*[]byte
+		row, e = mc.readRow(int(n))
+		if e != nil {
+			return
+		}
+
+		_, e = mc.readUntilEOF()
 		if e != nil {
 			return
 		}
 
-		val = string(*(*rows[0])[0])
+		val = string(*(*row)[0])
 	}
 
 	return

+ 208 - 216
packets.go

@@ -13,6 +13,7 @@ import (
 	"database/sql/driver"
 	"errors"
 	"fmt"
+	"io"
 	"reflect"
 	"time"
 )
@@ -56,7 +57,7 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
 		if e == nil {
 			e = fmt.Errorf("Length of read data (%d) does not match body length (%d)", n, pktLen)
 		}
-		errLog.Print(`packets:58 `, e)
+		errLog.Print(`packets:60 `, e)
 		return nil, driver.ErrBadConn
 	}
 	return data, e
@@ -76,7 +77,7 @@ func (mc *mysqlConn) readNumber(nr uint8) (uint64, error) {
 		if e == nil {
 			e = fmt.Errorf("Length of read data (%d) does not match header length (%d)", n, nr)
 		}
-		errLog.Print(`packets:78 `, e)
+		errLog.Print(`packets:80 `, e)
 		return 0, driver.ErrBadConn
 	}
 
@@ -100,7 +101,7 @@ func (mc *mysqlConn) writePacket(data *[]byte) error {
 		if e == nil {
 			e = errors.New("Length of send data does not match packet length")
 		}
-		errLog.Print(`packets:102 `, e)
+		errLog.Print(`packets:104 `, e)
 		return driver.ErrBadConn
 	}
 
@@ -442,7 +443,7 @@ The order of packets for a result set is:
 func (mc *mysqlConn) readResultSetHeaderPacket() (fieldCount int, e error) {
 	data, e := mc.readPacket()
 	if e != nil {
-		errLog.Print(`packets:437 `, e)
+		errLog.Print(`packets:446 `, e)
 		e = driver.ErrBadConn
 		return
 	}
@@ -570,43 +571,39 @@ func (mc *mysqlConn) readColumns(n int) (columns []mysqlField, e error) {
 }
 
 // Read Packets as Field Packets until EOF-Packet or an Error appears
-func (mc *mysqlConn) readRows(columnsCount int) (rows []*[]*[]byte, e error) {
-	var data []byte
-	var i, pos, n int
+func (mc *mysqlConn) readRow(columnsCount int) (*[]*[]byte, error) {
+	data, e := mc.readPacket()
+	if e != nil {
+		return nil, e
+	}
+
+	// EOF Packet
+	if data[0] == 254 && len(data) == 5 {
+		return nil, io.EOF
+	}
+
+	// RowSet Packet
+	row := make([]*[]byte, columnsCount)
+	var n int
 	var isNull bool
+	pos := 0
 
-	for {
-		data, e = mc.readPacket()
+	for i := 0; i < columnsCount; i++ {
+		// Read bytes and convert to string
+		row[i], n, isNull, e = readLengthCodedBinary(data[pos:])
 		if e != nil {
-			return
+			return nil, e
 		}
 
-		// EOF Packet
-		if data[0] == 254 && len(data) == 5 {
-			return
-		}
-
-		// RowSet Packet
-		row := make([]*[]byte, columnsCount)
-		pos = 0
-		for i = 0; i < columnsCount; i++ {
-			// Read bytes and convert to string
-			row[i], n, isNull, e = readLengthCodedBinary(data[pos:])
-			if e != nil {
-				return
-			}
-
-			// Append nil if field is NULL
-			if isNull {
-				row[i] = nil
-			}
-			pos += n
+		// nil if field is NULL
+		if isNull {
+			row[i] = nil
 		}
-		rows = append(rows, &row)
+		pos += n
 	}
 
-	mc.affectedRows = uint64(len(rows))
-	return
+	mc.affectedRows++
+	return &row, nil
 }
 
 // Reads Packets Packets until EOF-Packet or an Error appears. Returns count of Packets read
@@ -719,9 +716,9 @@ func (stmt mysqlStmt) buildExecutePacket(args *[]driver.Value) (e error) {
 	// Reset packet-sequence
 	stmt.mc.sequence = 0
 
-	pktLen := 1 + 4 + 1 + 4 + (stmt.paramCount+7)/8 + 1 + argsLen*2
+	pktLen := 1 + 4 + 1 + 4 + ((stmt.paramCount + 7) >> 3) + 1 + (argsLen << 1)
 	paramValues := make([][]byte, 0, argsLen)
-	paramTypes := make([]byte, 0, argsLen*2)
+	paramTypes := make([]byte, 0, (argsLen << 1))
 	bitMask := uint64(0)
 	var i, valLen int
 	var pv reflect.Value
@@ -840,209 +837,204 @@ func (stmt mysqlStmt) buildExecutePacket(args *[]driver.Value) (e error) {
 	return stmt.mc.writePacket(&data)
 }
 
-func (mc *mysqlConn) readBinaryRows(rc *rowsContent) (e error) {
-	var data, nullBitMap []byte
-	var i, pos, n int
-	var unsigned, isNull bool
+// http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::ResultsetRow
+func (mc *mysqlConn) readBinaryRow(rc *rowsContent) (*[]*[]byte, error) {
+	data, e := mc.readPacket()
+	if e != nil {
+		return nil, e
+	}
+
+	pos := 0
+
+	// EOF Packet
+	if data[pos] == 254 && len(data) == 5 {
+		return nil, io.EOF
+	}
+	pos++
+
+	// BinaryRowSet Packet
 	columnsCount := len(rc.columns)
+	row := make([]*[]byte, columnsCount)
 
-	for {
-		data, e = mc.readPacket()
-		if e != nil {
-			return
+	nullBitMap := data[pos : pos+(columnsCount+7+2)>>3]
+	pos += (columnsCount + 7 + 2) >> 3
+
+	var n int
+	var unsigned, isNull bool
+	for i := 0; i < columnsCount; i++ {
+		// Field is NULL
+		if (nullBitMap[(i+2)>>3] >> uint((i+2)&7) & 1) == 1 {
+			row[i] = nil
+			continue
 		}
 
-		pos = 0
+		unsigned = rc.columns[i].flags&FLAG_UNSIGNED != 0
 
-		// EOF Packet
-		if data[pos] == 254 && len(data) == 5 {
-			return
-		}
+		// Convert to byte-coded string
+		switch rc.columns[i].fieldType {
+		case FIELD_TYPE_NULL:
+			row[i] = nil
 
-		pos++
+		// Numeric Typs
+		case FIELD_TYPE_TINY:
+			var val []byte
+			if unsigned {
+				val = uintToByteStr(uint64(byteToUint8(data[pos])))
+			} else {
+				val = intToByteStr(int64(int8(byteToUint8(data[pos]))))
+			}
+			row[i] = &val
+			pos++
 
-		// BinaryRowSet Packet
-		row := make([]*[]byte, columnsCount)
+		case FIELD_TYPE_SHORT, FIELD_TYPE_YEAR:
+			var val []byte
+			if unsigned {
+				val = uintToByteStr(uint64(bytesToUint16(data[pos : pos+2])))
+			} else {
+				val = intToByteStr(int64(int16(bytesToUint16(data[pos : pos+2]))))
+			}
+			row[i] = &val
+			pos += 2
 
-		nullBitMap = data[pos : pos+(columnsCount+7+2)/8]
-		pos += (columnsCount + 7 + 2) / 8
+		case FIELD_TYPE_INT24, FIELD_TYPE_LONG:
+			var val []byte
+			if unsigned {
+				val = uintToByteStr(uint64(bytesToUint32(data[pos : pos+4])))
+			} else {
+				val = intToByteStr(int64(int32(bytesToUint32(data[pos : pos+4]))))
+			}
+			row[i] = &val
+			pos += 4
 
-		for i = 0; i < columnsCount; i++ {
-			// Field is NULL
-			if (nullBitMap[(i+2)/8] >> uint((i+2)%8) & 1) == 1 {
+		case FIELD_TYPE_LONGLONG:
+			var val []byte
+			if unsigned {
+				val = uintToByteStr(bytesToUint64(data[pos : pos+8]))
+			} else {
+				val = intToByteStr(int64(bytesToUint64(data[pos : pos+8])))
+			}
+			row[i] = &val
+			pos += 8
+
+		case FIELD_TYPE_FLOAT:
+			var val []byte
+			val = float32ToByteStr(bytesToFloat32(data[pos : pos+4]))
+			row[i] = &val
+			pos += 4
+
+		case FIELD_TYPE_DOUBLE:
+			var val []byte
+			val = float64ToByteStr(bytesToFloat64(data[pos : pos+8]))
+			row[i] = &val
+			pos += 8
+
+		case FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL:
+			row[i], n, isNull, e = readLengthCodedBinary(data[pos:])
+
+			if e != nil {
+				return nil, e
+			}
+
+			if isNull && rc.columns[i].flags&FLAG_NOT_NULL == 0 {
 				row[i] = nil
-				continue
 			}
+			pos += n
 
-			unsigned = rc.columns[i].flags&FLAG_UNSIGNED != 0
+		// Length coded Binary Strings
+		case FIELD_TYPE_VARCHAR, FIELD_TYPE_BIT, FIELD_TYPE_ENUM,
+			FIELD_TYPE_SET, FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB,
+			FIELD_TYPE_LONG_BLOB, FIELD_TYPE_BLOB, FIELD_TYPE_VAR_STRING,
+			FIELD_TYPE_STRING, FIELD_TYPE_GEOMETRY:
+			row[i], n, isNull, e = readLengthCodedBinary(data[pos:])
+			if e != nil {
+				return nil, e
+			}
 
-			// Convert to byte-coded string
-			switch rc.columns[i].fieldType {
-			case FIELD_TYPE_NULL:
+			if isNull && rc.columns[i].flags&FLAG_NOT_NULL == 0 {
 				row[i] = nil
+			}
+			pos += n
 
-			// Numeric Typs
-			case FIELD_TYPE_TINY:
-				var val []byte
-				if unsigned {
-					val = uintToByteStr(uint64(byteToUint8(data[pos])))
-				} else {
-					val = intToByteStr(int64(int8(byteToUint8(data[pos]))))
-				}
-				row[i] = &val
-				pos++
-
-			case FIELD_TYPE_SHORT, FIELD_TYPE_YEAR:
-				var val []byte
-				if unsigned {
-					val = uintToByteStr(uint64(bytesToUint16(data[pos : pos+2])))
-				} else {
-					val = intToByteStr(int64(int16(bytesToUint16(data[pos : pos+2]))))
-				}
-				row[i] = &val
-				pos += 2
-
-			case FIELD_TYPE_INT24, FIELD_TYPE_LONG:
-				var val []byte
-				if unsigned {
-					val = uintToByteStr(uint64(bytesToUint32(data[pos : pos+4])))
-				} else {
-					val = intToByteStr(int64(int32(bytesToUint32(data[pos : pos+4]))))
-				}
-				row[i] = &val
-				pos += 4
-
-			case FIELD_TYPE_LONGLONG:
-				var val []byte
-				if unsigned {
-					val = uintToByteStr(bytesToUint64(data[pos : pos+8]))
-				} else {
-					val = intToByteStr(int64(bytesToUint64(data[pos : pos+8])))
-				}
-				row[i] = &val
-				pos += 8
-
-			case FIELD_TYPE_FLOAT:
-				var val []byte
-				val = float32ToByteStr(bytesToFloat32(data[pos : pos+4]))
-				row[i] = &val
-				pos += 4
-
-			case FIELD_TYPE_DOUBLE:
-				var val []byte
-				val = float64ToByteStr(bytesToFloat64(data[pos : pos+8]))
-				row[i] = &val
-				pos += 8
-
-			case FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL:
-				row[i], n, isNull, e = readLengthCodedBinary(data[pos:])
-
-				if e != nil {
-					return
-				}
+		// Date YYYY-MM-DD
+		case FIELD_TYPE_DATE, FIELD_TYPE_NEWDATE:
+			var num uint64
+			num, n, e = bytesToLengthCodedBinary(data[pos:])
+			if e != nil {
+				return nil, e
+			}
+			pos += n
 
-				if isNull && rc.columns[i].flags&FLAG_NOT_NULL == 0 {
-					row[i] = nil
-				}
-				pos += n
-
-			// Length coded Binary Strings
-			case FIELD_TYPE_VARCHAR, FIELD_TYPE_BIT, FIELD_TYPE_ENUM,
-				FIELD_TYPE_SET, FIELD_TYPE_TINY_BLOB, FIELD_TYPE_MEDIUM_BLOB,
-				FIELD_TYPE_LONG_BLOB, FIELD_TYPE_BLOB, FIELD_TYPE_VAR_STRING,
-				FIELD_TYPE_STRING, FIELD_TYPE_GEOMETRY:
-				row[i], n, isNull, e = readLengthCodedBinary(data[pos:])
-				if e != nil {
-					return
-				}
+			var val []byte
+			if num == 0 {
+				val = []byte("0000-00-00")
+			} else {
+				val = []byte(fmt.Sprintf("%04d-%02d-%02d",
+					bytesToUint16(data[pos:pos+2]),
+					data[pos+2],
+					data[pos+3]))
+			}
+			row[i] = &val
+			pos += int(num)
 
-				if isNull && rc.columns[i].flags&FLAG_NOT_NULL == 0 {
-					row[i] = nil
-				}
-				pos += n
-
-			// Date YYYY-MM-DD
-			case FIELD_TYPE_DATE, FIELD_TYPE_NEWDATE:
-				var num uint64
-				num, n, e = bytesToLengthCodedBinary(data[pos:])
-				if e != nil {
-					return
-				}
-				pos += n
-
-				var val []byte
-				if num == 0 {
-					val = []byte("0000-00-00")
-				} else {
-					val = []byte(fmt.Sprintf("%04d-%02d-%02d",
-						bytesToUint16(data[pos:pos+2]),
-						data[pos+2],
-						data[pos+3]))
-				}
-				row[i] = &val
-				pos += int(num)
-
-			// Time HH:MM:SS
-			case FIELD_TYPE_TIME:
-				var num uint64
-				num, n, e = bytesToLengthCodedBinary(data[pos:])
-				if e != nil {
-					return
-				}
+		// Time HH:MM:SS
+		case FIELD_TYPE_TIME:
+			var num uint64
+			num, n, e = bytesToLengthCodedBinary(data[pos:])
+			if e != nil {
+				return nil, e
+			}
 
-				var val []byte
-				if num == 0 {
-					val = []byte("00:00:00")
-				} else {
-					val = []byte(fmt.Sprintf("%02d:%02d:%02d",
-						data[pos+6],
-						data[pos+7],
-						data[pos+8]))
-				}
-				row[i] = &val
-				pos += n + int(num)
-
-			// Timestamp YYYY-MM-DD HH:MM:SS
-			case FIELD_TYPE_TIMESTAMP, FIELD_TYPE_DATETIME:
-				var num uint64
-				num, n, e = bytesToLengthCodedBinary(data[pos:])
-				if e != nil {
-					return
-				}
-				pos += n
-
-				var val []byte
-				switch num {
-				case 0:
-					val = []byte("0000-00-00 00:00:00")
-				case 4:
-					val = []byte(fmt.Sprintf("%04d-%02d-%02d 00:00:00",
-						bytesToUint16(data[pos:pos+2]),
-						data[pos+2],
-						data[pos+3]))
-				default:
-					if num < 7 {
-						return fmt.Errorf("Invalid datetime-packet length %d", num)
-					}
-					val = []byte(fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d",
-						bytesToUint16(data[pos:pos+2]),
-						data[pos+2],
-						data[pos+3],
-						data[pos+4],
-						data[pos+5],
-						data[pos+6]))
-				}
-				row[i] = &val
-				pos += int(num)
+			var val []byte
+			if num == 0 {
+				val = []byte("00:00:00")
+			} else {
+				val = []byte(fmt.Sprintf("%02d:%02d:%02d",
+					data[pos+6],
+					data[pos+7],
+					data[pos+8]))
+			}
+			row[i] = &val
+			pos += n + int(num)
+
+		// Timestamp YYYY-MM-DD HH:MM:SS
+		case FIELD_TYPE_TIMESTAMP, FIELD_TYPE_DATETIME:
+			var num uint64
+			num, n, e = bytesToLengthCodedBinary(data[pos:])
+			if e != nil {
+				return nil, e
+			}
+			pos += n
 
-			// Please report if this happens!
+			var val []byte
+			switch num {
+			case 0:
+				val = []byte("0000-00-00 00:00:00")
+			case 4:
+				val = []byte(fmt.Sprintf("%04d-%02d-%02d 00:00:00",
+					bytesToUint16(data[pos:pos+2]),
+					data[pos+2],
+					data[pos+3]))
 			default:
-				return fmt.Errorf("Unknown FieldType %d", rc.columns[i].fieldType)
+				if num < 7 {
+					return nil, fmt.Errorf("Invalid datetime-packet length %d", num)
+				}
+				val = []byte(fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d",
+					bytesToUint16(data[pos:pos+2]),
+					data[pos+2],
+					data[pos+3],
+					data[pos+4],
+					data[pos+5],
+					data[pos+6]))
 			}
+			row[i] = &val
+			pos += int(num)
+
+		// Please report if this happens!
+		default:
+			return nil, fmt.Errorf("Unknown FieldType %d", rc.columns[i].fieldType)
 		}
-		rc.rows = append(rc.rows, &row)
 	}
 
-	mc.affectedRows = uint64(len(rc.rows))
-	return
+	mc.affectedRows++
+	return &row, nil
 }

+ 48 - 9
rows.go

@@ -11,6 +11,7 @@ package mysql
 
 import (
 	"database/sql/driver"
+	"errors"
 	"io"
 )
 
@@ -21,8 +22,10 @@ type mysqlField struct {
 }
 
 type rowsContent struct {
+	mc      *mysqlConn
+	binary  bool
+	unread  int
 	columns []mysqlField
-	rows    []*[]*[]byte
 }
 
 type mysqlRows struct {
@@ -37,27 +40,63 @@ func (rows mysqlRows) Columns() (columns []string) {
 	return
 }
 
-func (rows mysqlRows) Close() error {
-	rows.content = nil
+func (rows mysqlRows) Close() (e error) {
+	defer func() {
+		rows.content.mc = nil
+		rows.content = nil
+	}()
+
+	// Remove unread packets from stream
+	if rows.content.unread > -1 {
+		if rows.content.mc == nil {
+			return errors.New("Invalid Connection")
+		}
+
+		_, e = rows.content.mc.readUntilEOF()
+		if e != nil {
+			return
+		}
+	}
+
 	return nil
 }
 
 // Next returns []driver.Value filled with either nil values for NULL entries
 // or []byte's for all other entries. Type conversion is done on rows.scan(),
-// when the dest. type is know, which makes type conversion easier and avoids 
+// when the dest type is know, which makes type conversion easier and avoids 
 // unnecessary conversions.
 func (rows mysqlRows) Next(dest []driver.Value) error {
-	if len(rows.content.rows) > 0 {
-		for i := 0; i < cap(dest); i++ {
-			if (*rows.content.rows[0])[i] == nil {
+	if rows.content.unread > 0 {
+		if rows.content.mc == nil {
+			return errors.New("Invalid Connection")
+		}
+
+		columnsCount := cap(dest)
+
+		// Fetch next row from stream
+		var row *[]*[]byte
+		var e error
+		if rows.content.binary {
+			row, e = rows.content.mc.readBinaryRow(rows.content)
+		} else {
+			row, e = rows.content.mc.readRow(columnsCount)
+		}
+		rows.content.unread--
+
+		if e != nil {
+			return e
+		}
+
+		for i := 0; i < columnsCount; i++ {
+			if (*row)[i] == nil {
 				dest[i] = nil
 			} else {
-				dest[i] = *(*rows.content.rows[0])[i]
+				dest[i] = *(*row)[i]
 			}
 		}
-		rows.content.rows = rows.content.rows[1:]
 	} else {
 		return io.EOF
 	}
+
 	return nil
 }

+ 10 - 25
statement.go

@@ -25,10 +25,10 @@ type mysqlStmt struct {
 	*stmtContent
 }
 
-func (stmt mysqlStmt) Close() error {
-	e := stmt.mc.writeCommandPacket(COM_STMT_CLOSE, stmt.id)
+func (stmt mysqlStmt) Close() (e error) {
+	e = stmt.mc.writeCommandPacket(COM_STMT_CLOSE, stmt.id)
 	stmt.mc = nil
-	return e
+	return
 }
 
 func (stmt mysqlStmt) NumInput() int {
@@ -82,48 +82,33 @@ func (stmt mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
 		nil
 }
 
-func (stmt mysqlStmt) Query(args []driver.Value) (dr driver.Rows, e error) {
+func (stmt mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
 	if stmt.mc == nil {
 		return nil, errors.New(`Invalid Statement`)
 	}
 
 	// Send command
-	e = stmt.buildExecutePacket(&args)
+	e := stmt.buildExecutePacket(&args)
 	if e != nil {
 		return nil, e
 	}
 
-	// Get Result
+	// Read Result
 	var resLen int
-	rows := mysqlRows{new(rowsContent)}
 	resLen, e = stmt.mc.readResultSetHeaderPacket()
 	if e != nil {
 		return nil, e
 	}
 
+	rows := mysqlRows{&rowsContent{stmt.mc, true, resLen, nil}}
+
 	if resLen > 0 {
 		// Columns
 		rows.content.columns, e = stmt.mc.readColumns(resLen)
 		if e != nil {
-			return
-		}
-
-		// Rows
-		e = stmt.mc.readBinaryRows(rows.content)
-		if e != nil {
-			return
+			return nil, e
 		}
 	}
 
-	dr = rows
-	return
+	return rows, e
 }
-
-// ColumnConverter returns a ValueConverter for the provided
-// column index.  If the type of a specific column isn't known
-// or shouldn't be handled specially, DefaultValueConverter
-// can be returned.
-//func (stmt mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
-//	debug(fmt.Sprintf("ColumnConverter(%d)", idx))
-//	return driver.DefaultParameterConverter
-//}

+ 6 - 8
utils.go

@@ -144,7 +144,7 @@ func readLengthCodedBinary(data []byte) (*[]byte, int, bool, error) {
 		return nil, n, true, io.EOF
 	}
 
-	// Check if null
+	// Check if value is NULL
 	var isNull bool
 	if data[0] == 251 {
 		isNull = true
@@ -193,14 +193,14 @@ func bytesToUint16(b []byte) (n uint16) {
 func uint24ToBytes(n uint32) (b []byte) {
 	b = make([]byte, 3)
 	for i := uint8(0); i < 3; i++ {
-		b[i] = byte(n >> (i * 8))
+		b[i] = byte(n >> (i << 3))
 	}
 	return
 }
 
 func bytesToUint32(b []byte) (n uint32) {
 	for i := uint8(0); i < 4; i++ {
-		n |= uint32(b[i]) << (i * 8)
+		n |= uint32(b[i]) << (i << 3)
 	}
 	return
 }
@@ -208,14 +208,14 @@ func bytesToUint32(b []byte) (n uint32) {
 func uint32ToBytes(n uint32) (b []byte) {
 	b = make([]byte, 4)
 	for i := uint8(0); i < 4; i++ {
-		b[i] = byte(n >> (i * 8))
+		b[i] = byte(n >> (i << 3))
 	}
 	return
 }
 
 func bytesToUint64(b []byte) (n uint64) {
 	for i := uint8(0); i < 8; i++ {
-		n |= uint64(b[i]) << (i * 8)
+		n |= uint64(b[i]) << (i << 3)
 	}
 	return
 }
@@ -223,7 +223,7 @@ func bytesToUint64(b []byte) (n uint64) {
 func uint64ToBytes(n uint64) (b []byte) {
 	b = make([]byte, 8)
 	for i := uint8(0); i < 8; i++ {
-		b[i] = byte(n >> (i * 8))
+		b[i] = byte(n >> (i << 3))
 	}
 	return
 }
@@ -286,7 +286,6 @@ func bytesToLengthCodedBinary(b []byte) (length uint64, n int, e error) {
 
 func lengthCodedBinaryToBytes(n uint64) (b []byte) {
 	switch {
-
 	case n <= 250:
 		b = []byte{byte(n)}
 
@@ -300,7 +299,6 @@ func lengthCodedBinaryToBytes(n uint64) (b []byte) {
 }
 
 func intToByteStr(i int64) (b []byte) {
-	//tmp := make([]byte, 0)
 	return strconv.AppendInt(b, i, 10)
 }