Code:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define DELIM ":"
struct pktnode
{
int pkt_id;
char *message;
struct pktnode *next;
};
struct messagenode
{
int msg_id;
int prefix_len;
char id_prefix[3];
struct pktnode *pkthead;
struct messagenode *next;
};
void initiate(char *filename, FILE **fp,char **packet);
void populateInList(char *packet, struct messagenode **msg_node,FILE **fp);
struct messagenode *getMsgNode();
struct pktnode *getPktNode();
struct messagenode *search_msg(int msg_id, struct messagenode **head_msg);
struct pktnode *search_pkt(int pkt_id, struct pktnode **head_pkt);
void getPacketInfo(char *packet, int *msg_id,int *pkt_id,char *message,int *prefix_len_msg,struct messagenode **head_msg,FILE **fp);
void display(struct messagenode **head_msg);
void cleanUpAll(struct messagenode **head_msg,FILE **fp,char *packet);
void sortMsg(struct messagenode **head_msg);
int getlen(char *arg);
int main(int argc, char **argv)
{
FILE *fp;
char *packet;
struct messagenode *head_msg = NULL;
if(argc != 2){
printf("Please provide one message data file\n");
return 0;
}
initiate(argv[1],&fp,&packet);
while(1){
fgets(packet,2001,fp);
if(packet == NULL || !strcmp(packet,"END\n")|| !strcmp(packet,"END"))
break;
populateInList(packet,&head_msg,&fp);
}
sortMsg(&head_msg);
display(&head_msg);
cleanUpAll(&head_msg,&fp,packet);
return 0;
}
/* Opening packet data file */
void initiate(char *filename, FILE **fp,char **packet)
{
*fp = fopen(filename,"r");
if(*fp == NULL)
{
printf("Unable to open %s\n",filename);
exit(0);
}
*packet = (char *)malloc(2000 * sizeof(char));
}
/* Get message id, packet id and packet message from each
* packet string passed to function as argument.
*/
void populateInList(char *packet, struct messagenode **head_msg,FILE **fp)
{
int msg_id,pkt_id,prefix_len_msg,prefix_len_pkt;
int pos;
char *message;
struct messagenode *tmp_message, *loc, *current_msg, *save_msg;
struct pktnode *tmp_packet, *loc_pkt, *head_pkt;
message = (char *)malloc(1500*sizeof(char));
getPacketInfo(packet,&msg_id,&pkt_id,message,&prefix_len_msg,head_msg,fp);
if((loc = search_msg(msg_id,head_msg)) != NULL){
tmp_packet = getPktNode();
tmp_packet->pkt_id = pkt_id;
tmp_packet->message = message;
head_pkt = loc->pkthead;
if(head_pkt == NULL)
head_pkt = tmp_packet;
else
{
loc_pkt = search_pkt(pkt_id,&head_pkt);
if(loc_pkt == head_pkt && pkt_id < loc_pkt->pkt_id)
{
tmp_packet->next = head_pkt;
head_pkt = tmp_packet;
loc->pkthead = head_pkt;
}
else
{
tmp_packet->next = loc_pkt->next;
loc_pkt->next = tmp_packet;
}
}
}
else
{
tmp_message = getMsgNode();
tmp_message->msg_id = msg_id;
tmp_message->prefix_len = prefix_len_msg;
tmp_message->next = NULL;
tmp_message->pkthead = getPktNode();
tmp_message->pkthead->pkt_id = pkt_id;
tmp_message->pkthead->message = message;
if(*head_msg == NULL)
*head_msg = tmp_message;
else
{
current_msg = *head_msg;
while(current_msg != NULL)
{
save_msg = current_msg;
current_msg = current_msg->next;
}
save_msg->next = tmp_message;
}
}
}
struct messagenode *getMsgNode()
{
struct messagenode *tmp;
tmp = (struct messagenode *)malloc(sizeof(struct messagenode));
tmp->pkthead = NULL;
return tmp;
}
struct pktnode * getPktNode()
{
struct pktnode *tmp;
tmp = (struct pktnode *)malloc(sizeof(struct pktnode));
tmp->next = NULL;
return tmp;
}
/* Function to search a message node in message linked list. */
struct messagenode *search_msg(int msg_id, struct messagenode **head_msg)
{
struct messagenode *current_msg;
current_msg = *head_msg;
if(*head_msg == NULL)
return NULL;
else
{
while((current_msg != NULL) && (current_msg->msg_id != msg_id))
current_msg = current_msg->next;
if(current_msg == NULL)
return NULL;
if(current_msg->msg_id == msg_id)
return current_msg;
else
return NULL;
}
}
/* Function to search a packet node in packet linked list.*/
struct pktnode *search_pkt(int pkt_id, struct pktnode **head_pkt)
{
struct pktnode *current_pkt, *save_pkt;
current_pkt = *head_pkt;
save_pkt = current_pkt;
while((current_pkt != NULL) && (pkt_id > current_pkt->pkt_id))
{
save_pkt = current_pkt;
current_pkt = current_pkt->next;
}
return save_pkt;
}
/* Function to get packet info from packet string.
* Tokenize the string by strtok() with delemeter ':'.
*/
void getPacketInfo(char *packet, int *msg_id,int *pkt_id,char *message,int *prefix_len_msg,struct messagenode **head_msg,FILE **fp)
{
char *tokenPtr = NULL;
char array[10][1500];
char bkp_packet[2000];
int counter = 0,i=0;
strcpy(bkp_packet,packet);
tokenPtr = (char *)strtok(packet,DELIM);
if(tokenPtr == NULL)
{
printf("Fatal Error1 !! Invalid Message Format\n");
cleanUpAll(head_msg,fp,packet);
exit(0);
}
strcpy(array[0],tokenPtr);
counter++;
while(1)
{
tokenPtr = (char *)strtok(NULL,DELIM);
if(tokenPtr == NULL)
break;
strcpy(array[counter],tokenPtr);
if(counter>2)
strcat(array[counter-1],":");
counter++;
}
if(counter < 3)
{
printf("Fatal Error3 !! Invalid Message Format\n");
cleanUpAll(head_msg,fp,packet);
exit(0);
}
*prefix_len_msg = getlen(array[0]);
*msg_id = atoi(array[0]);
*pkt_id = atoi(array[1]);
for(i=2; i<counter; i++){
strcat(message,array[i]);
}
}
int getlen(char *arg)
{
int n=0;
char ch;
while(1)
{
ch = arg[n];
if(ch != '0')
break;
n++;
}
return n;
}
/* Move through formulated linked list and display the content.*/
void display(struct messagenode **head_msg)
{
char display_string[2000];
char pkt_id[10];
char prefix[3];
struct messagenode *current_msg;
struct pktnode *current_pkt;
int i;
current_msg = *head_msg;
while(current_msg != NULL)
{
for(i=0;i<current_msg->prefix_len;i++)
prefix[i]= '0';
prefix[i]='\0';
sprintf(display_string,"Message %s%d\n",prefix,current_msg->msg_id);
current_pkt = current_msg->pkthead;
while(current_pkt != NULL)
{
strcat(display_string,current_pkt->message);
current_pkt = current_pkt->next;
}
current_msg = current_msg->next;
printf("%s\n",display_string);
}
}
/* Move through linked list and deallocate it. Close file pointer also */
void cleanUpAll(struct messagenode **head_msg,FILE **fp,char *packet)
{
fclose(*fp);
free(packet);
struct messagenode *current_msg, *head_msg_local;
struct pktnode *current_pkt, *head_pkt;
head_msg_local = head_msg;
while(head_msg_local != NULL)
{
head_pkt = head_msg_local->pkthead;
while(head_pkt != NULL)
{
free(head_pkt->message);
current_pkt = head_pkt->next;
free(head_pkt);
head_pkt = current_pkt;
}
current_msg = head_msg_local->next;
free(head_msg_local);
head_msg_local = current_msg;
}
}
/* Sort the message linked list, i.e. the outer one.*/
void sortMsg(struct messagenode **head_msg)
{
int tmp_id,tmp_len;
struct pktnode *tmp_head;
struct messagenode *current_msg, *save_msg;
if(*head_msg == NULL)
return;
else {
for(current_msg = *head_msg;(current_msg != NULL);current_msg = current_msg->next)
{
for(save_msg = current_msg->next;(save_msg != NULL);save_msg = save_msg->next)
{
if(current_msg->msg_id > save_msg->msg_id)
{
tmp_id = save_msg->msg_id;
tmp_head = save_msg->pkthead;
tmp_len = save_msg->prefix_len;
save_msg->msg_id = current_msg->msg_id;
save_msg->pkthead = current_msg->pkthead;
save_msg->prefix_len = current_msg->prefix_len;
current_msg->msg_id = tmp_id;
current_msg->pkthead = tmp_head;
current_msg->prefix_len = tmp_len;
}
}
}
}
}