func handleConnection(conn net.Conn) { buffer := new(bytes.Buffer) data := make([]byte, 8192) for { n, err := conn.Read(data) if err != nil { if err == io.EOF { log.Println("Client exited") return } log.Println(err.Error()) } buffer.Write(data[0:n]) messageLength, bytesRead := proto.DecodeVarint(buffer.Bytes()) if messageLength > 0 && messageLength < uint64(buffer.Len()) { message := &Message{} err = proto.Unmarshal(buffer.Bytes()[bytesRead:messageLength+uint64(bytesRead)], message) if err != nil { log.Printf("Failed to read proto message: %s\n", err.Error()) } else { responseChannel := pendingRequests[*message.MessageId] responseChannel <- message delete(pendingRequests, *message.MessageId) buffer.Reset() } } } }
func readDelimited(rawData []byte, msg proto.Message) (int, error) { headerLength, off := proto.DecodeVarint(rawData) if off == 0 { log.Fatal("proto.DecodeVarint(rawData) returned zero") return -1, nil } err := proto.Unmarshal(rawData[off:off+int(headerLength)], msg) if err != nil { log.Fatal("proto.Unmarshal(rawData[off:off+headerLength]) ", err) return -1, err } return off + int(headerLength), nil }
func signed_varint_decoder(L *lua.LState) int { buffer := L.CheckString(1) pos := L.CheckInt(2) b_value := []byte(buffer) value, len := proto.DecodeVarint((b_value[pos:])) L.Push(lua.LNumber(int64(value))) L.Push(lua.LNumber(len + pos)) return 2 }
// ReadDelimited decodes a message from the provided length-delimited stream, // where the length is encoded as 32-bit varint prefix to the message body. // It returns the total number of bytes read and any applicable error. func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) { // Per AbstractParser#parsePartialDelimitedFrom with // CodedInputStream#readRawVarint32. headerBuf := make([]byte, binary.MaxVarintLen32) var bytesRead, varIntBytes int var messageLength uint64 for varIntBytes == 0 { if bytesRead >= len(headerBuf) { return bytesRead, errInvalidVarint } newBytesRead, err := r.Read(headerBuf[bytesRead:]) if newBytesRead == 0 { if err != nil { return bytesRead, err } // A Reader should not return (0, nil), but if it does, // it should be treated as no-op (according to the // Reader contract). So let's go on... continue } bytesRead += newBytesRead messageLength, varIntBytes = proto.DecodeVarint(headerBuf) } headerBuf = headerBuf[varIntBytes:] // Need to process what's not used yet in headerBuf. if messageLength-uint64(len(headerBuf)) <= 0 { return bytesRead, proto.Unmarshal(headerBuf, m) } messageBuf := make([]byte, messageLength) copy(messageBuf, headerBuf) newBytesRead, err := io.ReadFull(r, messageBuf[len(headerBuf):]) bytesRead += newBytesRead if err != nil { return bytesRead, err } return bytesRead, proto.Unmarshal(messageBuf, m) }
// ReadDelimited decodes a message from the provided length-delimited stream, // where the length is encoded as 32-bit varint prefix to the message body. // It returns the total number of bytes read and any applicable error. This is // roughly equivalent to the companion Java API's // MessageLite#parseDelimitedFrom. As per the reader contract, this function // calls r.Read repeatedly as required until exactly one message including its // prefix is read and decoded (or an error has occurred). The function never // reads more bytes from the stream than required. The function never returns // an error if a message has been read and decoded correctly, even if the end // of the stream has been reached in doing so. In that case, any subsequent // calls return (0, io.EOF). func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) { // Per AbstractParser#parsePartialDelimitedFrom with // CodedInputStream#readRawVarint32. headerBuf := make([]byte, binary.MaxVarintLen32) var bytesRead, varIntBytes int var messageLength uint64 for varIntBytes == 0 { // i.e. no varint has been decoded yet. if bytesRead >= len(headerBuf) { return bytesRead, errInvalidVarint } // We have to read byte by byte here to avoid reading more bytes // than required. Each read byte is appended to what we have // read before. newBytesRead, err := r.Read(headerBuf[bytesRead : bytesRead+1]) if newBytesRead == 0 { if err != nil { return bytesRead, err } // A Reader should not return (0, nil), but if it does, // it should be treated as no-op (according to the // Reader contract). So let's go on... continue } bytesRead += newBytesRead // Now present everything read so far to the varint decoder and // see if a varint can be decoded already. messageLength, varIntBytes = proto.DecodeVarint(headerBuf[:bytesRead]) } messageBuf := make([]byte, messageLength) newBytesRead, err := io.ReadFull(r, messageBuf) bytesRead += newBytesRead if err != nil { return bytesRead, err } return bytesRead, proto.Unmarshal(messageBuf, m) }
// Read from a base connection in a loop. // The top-level function for the BaseConn's read goroutine. func (b *BaseConn) readLoop() { msgBuffer := make([]byte, 1024) var readLen uint64 var length int var readUpTo int for { // If we're still reading the length... if length == 0 { // Read up to a maximum of six bytes. // Six bytes encodes up to 2^(7*6) == 2^35, // much more than the legal maximum length. // We don't want to read too much, because we have to // copy any excess read down the buffer afterwards. if readUpTo < 6 { n, err := b.conn.Read(msgBuffer[readUpTo:6]) if err != nil { break } readUpTo += n } // Try to read the length. var used int readLen, used = proto.DecodeVarint(msgBuffer[:readUpTo]) if used == 0 { // If we couldn't read it yet, // and have already read six bytes, // the other end is playing silly buggers. // Drop the connection. if readUpTo >= 6 { break } // Otherwise, if we weren't able to read it, // continue reading the length. continue } // If readLen is illegally huge, drop connection. // Otherwise, we've got our length. if readLen > 0x7FFFFFFF { break } length = int(readLen) // Grow message buffer if needed. if length > len(msgBuffer) { newMsgBuffer := make([]byte, length) // Copy over any excess read. if used != readUpTo { copy(newMsgBuffer, msgBuffer[used:readUpTo]) } msgBuffer = newMsgBuffer } else { // Copy down any excess read. if used != readUpTo { copy(msgBuffer, msgBuffer[used:readUpTo]) } } // This leaves readUpTo set to the length of // any excess read, zero if there was none. readUpTo -= used } // Read the message. // We don't want to read too much, because we have to // copy any excess read down the buffer afterwards. // It can still happen with short messages already read past. if readUpTo < length { n, err := b.conn.Read(msgBuffer[readUpTo:length]) if err != nil { break } readUpTo += n continue } // Unmarshal the message and send it for receipt. msg := new(baseproto.Message) err := proto.Unmarshal(msgBuffer[:length], msg) if err != nil { break } if *msg.MsgType == 1 { b.receivedCapabilities <- msg } else { b.received <- msg } // Copy down any excess read. if length != readUpTo { copy(msgBuffer, msgBuffer[length:readUpTo]) } // This leaves readUpTo set to the length of // any excess read, zero if there was none. readUpTo -= length // Set length to 0, ready to read the next length. length = 0 } close(b.received) b.Close() }