Object-oriented Programming and the KWIC system---Part 2
Review the declaration for the List class template
Emphasis: handles lists of objects derived from Node.
Overview of LineStorage changes
- No change to
LineStorage.h;
little benefit in making it a class
- Line counts
LineStorage.c: 229
LineStorage.C: 127
List.h: 65
List.C: 46
Total: 238
- Local types and state invariant: much simpler
- Local functions:
getWord and getLine
replaced by List::operator[]
LSReset, LSAddLine, LSAddWord:
much simpler
LineStorage.C
/********** LineStorage module---implementation **********/
#include <string.h>
#include <iostream.h>
#include <stdlib.h>
#include "kwic.h"
#include "LineStorage.h"
#include "List.h"
/***** local constants *****/
/***** local types *****/
class WordNode : public Node {
public:
WordNode() { word = 0; }
~WordNode() { delete word; }
char *word;
};
typedef List<WordNode> WordList;
class LineNode : public Node {
public:
WordList wordList;
};
typedef List<LineNode> LineList;
/***** local variables *****/
static LineList lineList;
/***** state invariant *****
1. For every WordNode allocated
word is a null-terminated array of characters.
2. All of the LineNodes and WordNodes allocated by LineStorage
(and not yet deleted) are in lineList.
*/
/***** local functions *****/
/***** exported functions *****/
void LSInit(void)
{
// intentionally empty
}
void LSReset(void)
{
LineNode* lineNodePtr;
WordNode* wordNodePtr;
while (lineNodePtr = lineList.remove()) {
while (wordNodePtr = lineNodePtr->wordList.remove()) {
delete wordNodePtr;
}
delete lineNodePtr;
}
}
KWStatus LSAddLine(void)
{
LineNode* newPtr = new LineNode;
if (newPtr == 0)
return KWMEMORYERROR;
lineList.add(newPtr);
return KWSUCCESS;
}
KWStatus LSAddWord(char* word)
{
if (lineList.size() == 0)
return KWRANGEERROR;
/* create and fill a WordNode */
WordNode* wordNodePtr = new WordNode;
if (wordNodePtr == 0)
return KWMEMORYERROR;
wordNodePtr->word = new char [(strlen(word)+1)];
if (wordNodePtr->word == 0) {
delete wordNodePtr;
return KWMEMORYERROR;
}
strcpy(wordNodePtr->word,word);
lineList[lineList.size()-1]->wordList.add(wordNodePtr);
return KWSUCCESS;
}
const char* LSGetWord(int lineNum,int wordNum)
{
if (lineNum < 0 || lineNum >= lineList.size())
return 0;
WordNode* wordNodePtr = lineList[lineNum]->wordList[wordNum];
return wordNodePtr == 0 ? 0 : wordNodePtr->word;
}
int LSNumWords(int lineNum)
{
LineNode* tmpPtr = lineList[lineNum];
return tmpPtr == 0 ? KWRANGEERROR : tmpPtr->wordList.size();
}
int LSNumLines(void)
{
return lineList.size();
}
void LSPrintState(void)
{
int lineListSize = lineList.size();
cout << "lineList size: " << lineListSize << endl;
for (int i = 0; i < lineListSize; i++) {
LineNode* lineNodePtr = lineList[i];
int wordListSize = lineNodePtr->wordList.size();
cout << "wordList size: " << wordListSize << endl << "\t";
for (int j = 0; j < wordListSize; j++) {
cout << "!" << lineNodePtr->wordList[j]->word;
}
cout << "!" << endl;
}
}