	.include "DS.S"
	.text
#-----------------------------------------------
#	C O N S T R U C T O R
#-----------------------------------------------
	ARGS
	DS	thisP				# -->Data inst
	DS	callerDeP			# -->originator's Debug
	PROLOC
	DL	deP				# -->Debug
	EPILOC
#-----------------------------------------------
	.global Data
Data:
	PROLOG
	mov	thisP(bp), b			# -->Data inst
	lea	Da.debug(b), a			# -->Debug
	mov	a, deP(bp)			# init local -->Debug
# construct debug ID from originator debID
	mov	callerDeP(bp), a		# -->caller's Debug
	lea	D.id(a), a
	push	a				# -->caller's DebugId
	DEBID	"%s DATA", 1
# calculate container size
	mov	C.csP,a
	push	C.txtP(a)
	call	strlen
	addl	$HeaderL, a
	addl	$PayloadL, a
	inc	a
	mov	thisP(bp), b			# -->Data inst
	mov	a, Da.datalen(b)		# save container length
# allocate container
	push	a
	call	malloc
	test	a, a
	jnz	0f
	SYSERR	"malloc"
0:
	mov	thisP(bp), b			# -->Data inst
	mov	a, Da.contP(b)	 		# save -->container
# initialize container
	mov	Da.contP(b), c			# -->Container
	lea	Co.hdr(c), a			# -->Header
	movl	$0, H.ttl(a)
	movl	$0, H.ts(a)
	push	$0f
	lea	Co.payl(c), a			# -->Payload
	lea	Pa.text(a), a
	push	a
	call	strcpy				# init Payload.text
	LOG	5, "Data instance established"
	EPILOG
0:	.asciz	"EMPTY"
#-----------------------------------------------
#	L O A D   P A Y L O A D
#-----------------------------------------------
# returns 	-->data container
	M_ARGS
	DS	ttl
	DS	loadP				# -->text to be sent
	M_LOCAL
	DL	t, timevalL			# timestamp buf
	M_PROLOG Da, load
	LOG	5, "loading..."
	mov	Da.contP(b), c			# -->Container
# fill header
	lea	Co.hdr(c), d			# -->containner header
	mov	ttl(bp), a
	mov	a, H.ttl(d)			# init TTL in header
# get timestamp
	call	D.getTs				# get timestamp
	mov	a, H.ts(d)			# timestamp to header
# init payload
	push	loadP(bp)			# -->loaded text
	lea	Co.payl(c), a			# -->Payload
	lea	Pa.text(a), a
	push	a
	call	strcpy				# copy text to payload
# return -->Data
	push	Da.datalen(b)
	LOG	5, "payload loaded to container, len=%u"
	mov	Da.contP(b), a			# return -->container
	EPILOG_R
#-----------------------------------------------
#	G E T   D A T A   C O N T A I N E R   L E N G T H
#-----------------------------------------------
# returns	length of container filled with data
	M_ARGS
	M_LOCAL
	M_PROLOG Da, getDataLen
	mov	Da.datalen(b), a
	EPILOG_R
#-----------------------------------------------
#	G E T   D A T A   C O N T A I N E R   P O I N T E R
#-----------------------------------------------
	M_ARGS
	M_LOCAL
	M_PROLOG Da, getContP
	mov	Da.contP(b), a
	EPILOG_R
#-----------------------------------------------
#	C H E C K   P A Y L O A D
#-----------------------------------------------
# returns	boolean: original text == received text
	M_ARGS
	M_LOCAL
	M_PROLOG Da, chk
# get original payload
	mov	C.csP, c			# -->CS
	pushl	C.txtP(c)			# -->orig text
# get payload from container
	mov	Da.contP(b), a			# -->Container
	lea	Co.payl(a), a			# -->Payload
	lea	Pa.text(a), a			# -->payload text
	push	a
	call	strcmp
	xor	c, c
	test	a, a				# 0 = texts are equal
	setz	%cl
	mov	c, a
	EPILOG_R
#-----------------------------------------------
#	U N L O A D   P A Y L O A D
#-----------------------------------------------
# returns	-->payload text
	M_ARGS
	M_LOCAL
	M_PROLOG Da, unl
	mov	thisP(bp), b			# -->Data inst
	lea	Da.debug(b), a
	mov	a, deP(bp)
# get payload from container
	mov	Da.contP(b), a			# -->Container
	lea	Co.payl(a), a			# -->Payload
	lea	Pa.text(a), a			# -->Payload.text
	EPILOG_R
#-----------------------------------------------
#	D E C R E M E N T   T T L
#-----------------------------------------------
# decrement TTL in data container header, save it and return it
	M_ARGS
	M_LOCAL
	M_PROLOG Da, dttl
	mov	Da.contP(b), a			# -->Container
	lea	Co.hdr(a), a			# -->container header
	decl	H.ttl(a)			# TTL--
	mov	H.ttl(a), a			# return TTL
	EPILOG_R
#-----------------------------------------------
#	G E T   T T L
#-----------------------------------------------
	M_ARGS
	M_LOCAL
	M_PROLOG Da, ttl
	mov	Da.contP(b), a			# -->Container
	lea	Co.hdr(a), a			# -->container header
	mov	H.ttl(a), a			# return TTL
	EPILOG_R
#-----------------------------------------------
#	P U T   l I S T E N   P O R T   T O   H E A D E R
#-----------------------------------------------
	ARGS
	DS	thisP				# -->Data inst
	DS	port
# returns	port value
	PROLOC
	DL	deP				# -->Debug
	EPILOC
#-----------------------------------------------
	.global Da.putPort
Da.putPort:
	PROLOG
	mov	thisP(bp), b			# -->Data inst
	lea	Da.debug(b), a
	mov	a, deP(bp)			# -->Debug

	mov	Da.contP(b), c			# -->Container
	lea	Co.hdr(a), c			# -->container header
	mov	port(bp), a
	mov	a, H.lport(c)
	EPILOG_R
#-----------------------------------------------
#	G E T   l I S T E N   P O R T   F R O M   H E A D E R
#-----------------------------------------------
	M_ARGS
	M_LOCAL
	M_PROLOG Da, getPort
	mov	Da.contP(b), c			# -->Container
	lea	Co.hdr(c), c			# -->container header
	mov	H.lport(c), a
	EPILOG_R
#-----------------------------------------------
#	G E T   T I M E S T A M P   F R O M   H E A D E R
#-----------------------------------------------
	M_ARGS
	M_LOCAL
	M_PROLOG Da, getTs
	mov	Da.contP(b), a			# -->Container
	lea	Co.hdr(a), a			# -->container header
	mov	H.ts(a), a			# return timestamp
	EPILOG_R
#-----------------------------------------------
#	S A B O T A G E   T E X T
#-----------------------------------------------
	ARGS
	DS	thisP				# -->Data inst
	PROLOC
	DL	deP				# -->Debug
	EPILOC
#-----------------------------------------------
	.global Da.sabotage
Da.sabotage:
	PROLOG
	lea	Da.contP(b), a			# -->Container
	lea	Co.payl(a), a			# -->Payload
	lea	Pa.text(a), a			# -->Payload.text
	movl	$'?', (a)
	EPILOG
#-----------------------------------------------
#	C R E A T E   D I G E S T   F R O M   T E X T
#-----------------------------------------------
# returns	-->24 chars payload text digest
	M_ARGS
	DS	digestP				# -->text digest buffer
	M_LOCAL
	DL	textP
	M_PROLOG Da, digest24
# check length of payload text
	mov	Da.contP(b), a			# -->Container
	lea	Co.payl(a), a			# -->Payload
	lea	Pa.text(a), a			# -->Payload.text
	mov	a, textP(bp)
	push	a
	call	strlen
	cmp	$24, a				# payload text length < 24 ?
	jl	Da.digest24Direct		# yes, direct copy
# create digest	from longer text
	push	$8
	push	textP(bp)
	push	digestP(bp)
	call	strncpy				# copy beg. of text
	push	$0f
	mov	digestP(bp), a			# -->digest
	add	$8, a
	push	a				# -->digest+8
	call	strcpy
	jmp	1f
0:	.asciz	"-------"
1:	push	textP(bp)
	call	strlen
	mov	textP(bp), c
	add	a, c
	lea	-8(c), c			# -->end of text - 8
	push	c
	mov	digestP(bp), a
	lea	15(a), a			# -->digest+15
	push	a
	call	strcpy
	jmp	Da.digest24Ex
# directly copy shorter text
Da.digest24Direct:
	push	textP(bp)
	push	digestP(bp)
	call	strcpy
Da.digest24Ex:
	mov	digestP(bp), a			# -->digest
	EPILOG_R
#-----------------------------------------------
	.end
