# This file is part of bish-bosh. It is subject to the licence terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/raphaelcohn/bish-bosh/master/COPYRIGHT. No part of bish-bosh, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
# Copyright © 2014-2015 The developers of bish-bosh. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/raphaelcohn/bish-bosh/master/COPYRIGHT.


core_usesIn bishbosh/connection/read controlpacket byte

bishbosh_connection_read_nonBlockingFeatureTest()
{	
	case "$core_init_shellDetected" in
		
		# For some reason, pdksh / mksh just block forever
		pdksh|mksh)
			bishbosh_connection_supportsNonBlockingRead=0
			bishbosh_connection_exitCodeForReadTimeout=-1
			return 0
		;;
		
	esac
	
	local testFifoPath="$(bishbosh_connection_mkfifo 'non-blocking-read-feature-test')"
	exec 3<>"$testFifoPath"

	local exitCode
	# This code fails on Cygwin 1.7. Don't know why, but this related message suggests FIFOs aren't particularly robust (https://cygwin.com/ml/cygwin/2009-07/msg00233.html)
	set +e
	printf '%s\n' 'test' >&3 2>/dev/null
	exitCode=$?
	set -e
	
	if [ $exitCode -ne 0 ]; then
		core_message INFO "It seems there might be problems with FIFOs - we're assuming you're on Cygwin"
		bishbosh_connection_supportsNonBlockingRead=1
		bishbosh_connection_exitCodeForReadTimeout=1
		return 0
	fi
	
	local testVariable=''
	set +e
	read -r -u 3 -t $bishbosh_readLatency_inFractionalSeconds testVariable 2>/dev/null
	exitCode=$?
	set -e
	exec 3>&-
	exec 3<&-
	
	if [ -z "$testVariable" ]; then
		bishbosh_connection_supportsNonBlockingRead=0
		bishbosh_connection_exitCodeForReadTimeout=-1
		return 0
	else
		bishbosh_connection_supportsNonBlockingRead=1
	fi

	local timeoutExitCodeFifoPath="$(bishbosh_connection_mkfifo 'non-blocking-read-timeout-exit-code-feature-test')"
	exec 3<>"$testFifoPath"
	set +e
	read -r -u 3 -t $bishbosh_readLatency_inFractionalSeconds testVariable 
	bishbosh_connection_exitCodeForReadTimeout=$?
	exec 3>&-
	exec 3<&-
	set -e
}

core_dependency_requires '*' grep
bishbosh_connection_read_initialise()
{
	local isServer="$1"
	
	bishbosh_connection_read_controlpacket_initialise "$isServer"
	bishbosh_connection_read_nonBlockingFeatureTest
	bishbosh_connection_read_byte_initialise
}

bishbosh_connection_read_remainingLength()
{
	local controlPacket="$1"
	
	# For some reason, on AIX, this is empty
	local remainingLengthByte
	bishbosh_connection_read_byte_blocking remainingLengthByte
	if [ $remainingLengthByte -lt 128 ]; then
		remainingLength=$remainingLengthByte
		return 0
	fi
	remainingLength=$((remainingLengthByte-128))
	bishbosh_connection_read_byte_blocking remainingLengthByte
	if [ $remainingLengthByte -lt 128 ]; then
		remainingLength=$((remainingLength+remainingLengthByte*128))
		return 0
	fi
	remainingLength=$((remainingLength+(remainingLengthByte-128)*128))
	bishbosh_connection_read_byte_blocking remainingLengthByte
	if [ $remainingLengthByte -lt 128 ]; then
		remainingLength=$((remainingLength+remainingLengthByte*128*128))
		return 0
	fi
	remainingLength=$((remainingLength+(remainingLengthByte-128)*128*128))
	bishbosh_connection_read_byte_blocking remainingLengthByte
	if [ $remainingLengthByte -lt 128 ]; then
		remainingLength=$((remainingLength+remainingLengthByte*128*128*128))
		return 0
	fi
	bishbosh_connection_error_protocolReadControlPacket "$controlPacket" "Remaining length exceeds four bytes"
}

bishbosh_connection_read_packetIdentifier()
{
	local packetIdentifierMsb
	local packetIdentifierLsb
	bishbosh_connection_read_byte_blocking packetIdentifierMsb
	bishbosh_connection_read_byte_blocking packetIdentifierLsb
	
	packetIdentifier=$((packetIdentifierMsb * 256 + packetIdentifierLsb))
	
	# We should now 'free' the packet identifier...
}

bishbosh_connection_read_length()
{
	local lengthMsb
	local lengthLsb
	bishbosh_connection_read_byte_blocking lengthMsb
	bishbosh_connection_read_byte_blocking lengthLsb
	
	length=$((lengthMsb * 256 + lengthLsb))
}
