/************************************************************/
/*                                                          */
/*  The cpp file of packet definition                       */
/*  For CS 145 (Fall 2003) Lab 2                            */
/*  Author: Xiaoliang (David) Wei                           */
/*  Date:   Nov 07, 2002                                    */
/*                                                          */
/************************************************************/

#include "udpfile.h"


/* Create a packet, probably for pure ack*/
Packet::Packet()
{
	getHeaderPtr()->len=0;
	getHeaderPtr()->seq=0;
	size=0;
}


/*parse an incoming packet */
Packet::Packet(char * newbuf, int len)
{
	memcpy(buf,newbuf,sizeof(len));
	parse(len);
};

Packet::Packet(FILE* pktfile)
{
	int len=0;
	while (!feof(pktfile))
	{
		if (len>=(S-1))
		{
			printf("The file is too large for a packet in my definition\n");
			break;
		}
		fscanf(pktfile,"%c",&(buf[len]));
		len++;		
	}
	parse(len-1);
};

//get a packet from a file
Packet::Packet(FILE* infile,int maxlen)
{
	if (infile==NULL) return;
	size=0;
	if (feof(infile)) return;
	int len=fread(getDataPtr(),1,maxlen-HEADER_SIZE,infile);
	if (len==0) return;
//	printf("%d got from file\n", len);
	struct header * header=getHeaderPtr();
	size=len+HEADER_SIZE;
	getHeaderPtr()->len=size;
	getHeaderPtr()->seq=0;
};


/* print the packet for debug. */
void Packet::print()
{
	printf("length: %d, seq: %d, ackseq:%d TYPE:%d\n",
		getHeaderPtr()->len, getHeaderPtr()->seq,getHeaderPtr()->tt_seq);
	/*printf("Content:\n");
	for (int i=HEADER_SIZE; i<getHeaderPtr()->len;i++)
	{
		printf("%c",buf[i]);
	}	
	printf("\n");*/
}






//write a packet to a file
void Packet::output(FILE* outfile)
{
	if (isValid())
	{
		if (outfile!=NULL)
		{
			int rval=fwrite(getDataPtr(),1,getDataLen(),outfile);
			if (rval!=getDataLen())
			{
				printf("Incomplete writing to the file %d vs %d\n", rval, getDataLen());
			}
		}
		else
			printf("ERROR: try to write to an unexisting file!\n");
	}
	else
		printf("ERROR: try to write an invalid packet to the file!\n");
};


//send a packet to the socket simulated by a file
void Packet::send_to_file(char prefix)
{
	char outFileName[100];
	FILE* outfile;
	if (isValid())
	{
				
		int  len=(getHeaderPtr()->len);
//		printf("sending size:%d\n",len );
		
		if (getHeaderPtr()->seq>=10000000)
		{
			printf("Error: The sequence number is too large for the filename!\n");
			printf("Failed in sending the packet!\n");
			return;
		}
		
		// Create the file name for this sequence number.
		sprintf(outFileName,"%lu.txt",getHeaderPtr()->seq+10000000);
		outFileName[0]=prefix;
		outfile=fopen(outFileName,"w");
		if (outfile==NULL)
		{
			printf("Error: cannot write to file %s\n", outFileName);
			return;
		};
		for (int i=0;i<len;i++)
		{
			fprintf(outfile,"%c",buf[i]);
		};
		fclose(outfile);
//		printf("packet with seq number %d sent to file %s\n",getHeaderPtr()->seq,outFileName);
	}
	else
		printf("ERROR: try to send an invalid packet!\n");
}

//parse the packet
void Packet::parse(int len)
{
	if (len<HEADER_SIZE) 
	{
		printf("incomplete packet received %d \n",len);
		return;
	}
	struct header * header=getHeaderPtr();
	if (len!=header->len)	
	{
		printf("packet len error:%d vs actual:%d\n",header->len, len);
		return;
	}
//	printf("Got a packet\n");
	size=len;
//	print();
}

