Shayan's Software & Technology

My adventure as a Software Engineer continues..,

Implementing the WebVTT Parser in C Programming Language for the 0.2 Release!

Overview

The team has decided to break up tasks we need to do for the WebVTT Standard into different parts. We need to implement the WebVTT parser in the C programming Language. To do so, we have 3 groups that will have to come up with 3 different versions of the parser. May the best team win! For this we are working in pairs. I am working with my good friend: Rick Eyre Here is my experience for the preliminary development of this parser in C.

Programming in C – The Structured Programming Paradigm 

Re-living C Programming. C is a very important programming language because it taught me how the computer works. How it interprets instructions that most higher level programming languages hide and “do for you”. It Taught me how to be a Software Engineer. so coming back to it was like a homecoming. But it wasn’t full of fun, I was quick to learn the amount I had forgotten. So I went back to my old notes and began to catch up. The most interesting thing came to me when I tried implementing methodologies I had learned in other languages in C, and the agony that ensued (more to come i’m sure!). It is like my programming life is coming full circle. Now this is what I enjoy! Enough of my feelings and thoughts let’s get down to business.

Implementation

For my part of the C-parser I looked for possible functions that might be needed in the WebVTT specification. I noticed that the WebVTT specification is written for a developer who might be implementing a parser in an Object-Oriented Language. The C programming language is  a predecessor  of many Object Oriented Programming languages such as C++. We are using C which is a Structured Programming language., meaning that in this paradigm you cannot “think in objects” it is different from tradition OO methodologies and behavior  With that being said Rick Eyre and I turned to structs. It’s been a while since I heard of  a struct but it is basically a data structure that allows you to encapsulate primitive types and nothing more. Using structs we turned to the specification and sought out anything that we could use to simplify our code and make it easy to use. We also looked for potential function candidates. The specification mentions “Algorithms” for various parts of the spec. This is an indication that the process is likely to be a function that can be re-used and be modular in our parser.

Here are some functions that I have made chosen to be potential candidates for implementation:


// Referenced from http://dev.w3.org/html5/webvtt/#webvtt-cue-text-tokenizer
char* webVttTokenizer(char *input, char *position);
// Referenced from http://dev.w3.org/html5/webvtt/#collect-webvtt-cue-timings-and-settings
void collectTimingsAndSettings(WebVttBufferInfo *info);
// Reference from http://dev.w3.org/html5/webvtt/#webvtt-timestamp-object
void attachInternalNodeObject();
// Referenced from http://dev.w3.org/html5/webvtt/#webvtt-timestamp-object
void parseCueTextString(WebVttBufferInfo *info, Node *current);

// Error functions
void createError(char *code, char *message);
void addToErrorList(Error* e);
void printErrorList();

Error Log Module

After we had designed out a skeleton for our parser. Rick Eyre and I decided to implement some of the functions and some of the features that we thought were easy to do. We did this so that in the future we can easily assign tasks.

I decided I would like to implement a module that allowed for easy logging of errors that the parser may encounter at run time. To log these errors I created a struct called Error. The responsibility of this structure is to keep track of all the errors that might occur and to store them in a file. Moreover, an array of Errors can also be used to print out errors on the Command Line in “Debug mode” which we will refine later during the development process. One thing we still need to discuss and hammer out is the format of the “Error Code” that we will attach to the Error Structure. This Error Code will help other developers pinpoint exactly what kind of error the parser has thrown. I decided to implement this Error Log module because I saw the advantage of ensuring our parser is behaving correctly and that everything is organized. Enough talk let me show you what i have so far.

// Represents an Error Logging Type
typedef struct
{
	char *errCode;
	char *errMessage;
} Error;

The Following code shows how to create an error, and store it in the struct. There is also a call to addToErrorList


// create an Error instance and populate it with error information and add to the list
void createError(char *code, char *message)
{
	// create and initialize the error structure
	Error *e = (Error*)malloc(sizeof(Error));
	e->errCode = (char *)malloc(sizeof(char) * strlen(code));
	e->errCode = code;
	e->errMessage = (char *)malloc(sizeof(char) * strlen(message));
	e->errMessage = message;

	// add to the end of the error array
	addToErrorList(e);
}

Here is the implementation of addToErrorList


// add an Error object to the end of the list
void addToErrorList(Error* e)
{
	// make use of the first allocated element before reallocating, and add to the size of array
	if(size == 0)
	{
		strcpy(errList[0].errCode,e->errCode);
		strcpy(errList[0].errMessage, e->errMessage);
		size++;
	}
	else
	{
		errList = (Error*)realloc(errList, sizeof(Error)+sizeof(errList));
		strcpy(errList[size].errCode,e->errCode);
		strcpy(errList[size].errMessage,e->errMessage);
                size++;
	}
}

The last function involves printing the array out to the Command Line and storing the error objects in a file as strings. This function is intended to be used at the end of the parser execution while in “Debug Mode”. This is still subject to change throughout the Development process. As a quick fix

// format and write out an error to a logfile
void printErrorList()
{
	FILE *fp = NULL;
	int i;

	fp = fopen("errorlog.txt", "w");
	for (i = 0; i < size; i++)
	{
		printf("%s%s\n",errList[i].errCode,errList[i].errMessage);
	        // try to add entry to the log file
		if (fp != NULL)
		{
			fprintf(fp, "%s%s", errList[i].errCode,errList[i].errMessage);
		}
		else
		{
			printf("Error could not be logged!\n");
		}
		// delallocate the current Error Object in the list
		free(errList[i].errCode);
		free(errList[i].errMessage);
	}
	fclose(fp);
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: