예제 #1
0
파일: network.go 프로젝트: navaneeth/spike
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()
			}
		}
	}
}
예제 #2
0
파일: client.go 프로젝트: FashGek/gohadoop
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
}
예제 #3
0
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
}
예제 #4
0
// 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)
}
예제 #5
0
파일: decode.go 프로젝트: jameswei/xcodis
// 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)
}
예제 #6
0
// 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()
}