www.pudn.com > SmartFDISK.zip > helpbase.cc
#define HELPEXTENSIONS /*------------------------------------------------------------*/ /* filename - HelpBase.cpp */ /* */ /* function(s) */ /* Member function(s) of following classes */ /* THelpTopic */ /* THelpIndex */ /* THelpFile */ /*------------------------------------------------------------*/ /*------------------------------------------------------------*/ /* */ /* Turbo Vision - Version 1.0 */ /* */ /* */ /* Copyright (c) 1991 by Borland International */ /* All Rights Reserved. */ /* */ /*------------------------------------------------------------*/ #define Uses_TStreamableClass #define Uses_TPoint #define Uses_TStreamable #define Uses_ipstream #define Uses_opstream #define Uses_fpstream #define Uses_TRect #define Uses_TObject #include#if !defined( __HELP_H ) #include "HelpBase.h" #endif // __HELP_H #if !defined( __UTIL_H ) #include "Util.h" #endif // __UTIL_H #if !defined( __STRING_H ) #include #endif // __STRING_H #if !defined( __LIMITS_H ) #include #endif // __LIMITS_H #if !defined( __STAT_H ) #include #endif // __STAT_H #if !defined( __CTYPE_H ) #include #endif // __CTYPE_H #if !defined( __IO_H ) #include #endif // __IO_H #ifdef HELPEXTENSIONS int THelpFile::oldFront; int THelpFile::oldCount; unsigned int THelpFile::oldTopics[THelpFile::maxOldTopics]; #endif TCrossRefHandler crossRefHandler = notAssigned; // THelpTopic const char * const near THelpTopic::name = "THelpTopic"; void THelpTopic::write( opstream& os ) { writeParagraphs( os ); writeCrossRefs( os ); } void *THelpTopic::read( ipstream& is ) { readParagraphs( is ); readCrossRefs( is ); width = 0; lastLine = INT_MAX; return this; } TStreamable *THelpTopic::build() { return new THelpTopic( streamableInit ); } TStreamableClass RHelpTopic( THelpTopic::name, THelpTopic::build, __DELTA(THelpTopic) ); THelpTopic::THelpTopic() : TObject() { paragraphs = 0; numRefs = 0; crossRefs = 0; width = 0; lastOffset = 0; lastLine = INT_MAX; lastParagraph = 0; }; void THelpTopic::readParagraphs( ipstream& s ) { int i; unsigned int size; TParagraph **pp; int temp; s >> i; pp = ¶graphs; while ( i > 0) { s >> size; *pp = new TParagraph; (*pp)->text = new char[size]; (*pp)->size = size; s >> temp; (*pp)->wrap = Boolean(temp); s.readBytes((*pp)->text, (*pp)->size); pp = &((*pp)->next); --i; } *pp = 0; } void THelpTopic::readCrossRefs( ipstream& s ) { int i; TCrossRef *crossRefPtr; s >> numRefs; crossRefs = new TCrossRef[numRefs]; for (i = 0; i < numRefs; ++i) { crossRefPtr = (TCrossRef *)crossRefs + i; s >> crossRefPtr->ref >> crossRefPtr->offset >> crossRefPtr->length; // s.readBytes(crossRefPtr, sizeof(TCrossRef)); } } void THelpTopic::disposeParagraphs() { TParagraph *p, *t; p = paragraphs; while (p != 0) { t = p; p = p->next; delete t->text; delete t; } } THelpTopic::~THelpTopic() { TCrossRef *crossRefPtr; disposeParagraphs(); if (crossRefs != 0) { crossRefPtr = (TCrossRef *)crossRefs; delete crossRefPtr; } } void THelpTopic::addCrossRef( TCrossRef ref ) { TCrossRef *p; TCrossRef *crossRefPtr; p = new TCrossRef[numRefs+1]; if (numRefs > 0) { crossRefPtr = crossRefs; memmove(p, crossRefPtr, numRefs * sizeof(TCrossRef)); delete crossRefPtr; } crossRefs = p; crossRefPtr = crossRefs + numRefs; *crossRefPtr = ref; ++numRefs; } void THelpTopic::addParagraph( TParagraph *p ) { TParagraph *pp, *back; if (paragraphs == 0) paragraphs = p; else { pp = paragraphs; back = pp; while (pp != 0) { back = pp; pp = pp->next; } back->next = p; } p->next = 0; } void THelpTopic::getCrossRef( int i, TPoint& loc, uchar& length, int& ref ) { int oldOffset, curOffset, offset, paraOffset; TParagraph *p; int line; TCrossRef *crossRefPtr; paraOffset = 0; curOffset = 0; oldOffset = 0; line = 0; crossRefPtr = crossRefs + i; offset = crossRefPtr->offset; p = paragraphs; while (paraOffset + curOffset < offset) { oldOffset = paraOffset + curOffset; wrapText(p->text, p->size, curOffset, p->wrap); ++line; if ((uint32)curOffset >= p->size) { paraOffset += p->size; p = p->next; curOffset = 0; } } loc.x = offset - oldOffset - 1; loc.y = line; length = crossRefPtr->length; ref = crossRefPtr->ref; } char *THelpTopic::getLine( int line ) { int offset, i; TParagraph *p; static char buffer[256]; if (lastLine < line) { i = line; line -= lastLine; lastLine = i; offset = lastOffset; p = lastParagraph; } else { p = paragraphs; offset = 0; lastLine = line; } buffer[0] = 0; while (p != 0) { while ((uint32)offset < p->size) { --line; strcpy(buffer, wrapText(p->text, p->size, offset, p->wrap)); if (line == 0) { lastOffset = offset; lastParagraph = p; return buffer; } } p = p->next; offset = 0; } buffer[0] = 0; return buffer; } int THelpTopic::getNumCrossRefs() { return numRefs; } int THelpTopic::numLines() { int offset, lines; TParagraph *p; offset = 0; lines = 0; p = paragraphs; while (p != 0) { offset = 0; while ((uint32)offset < p->size) { ++lines; wrapText(p->text, p->size, offset, p->wrap); } p = p->next; } return lines; } void THelpTopic::setCrossRef( int i, TCrossRef& ref ) { TCrossRef *crossRefPtr; if (i < numRefs) { crossRefPtr = crossRefs + i; *crossRefPtr = ref; } } void THelpTopic::setNumCrossRefs( int i ) { TCrossRef *p, *crossRefPtr; if (numRefs == i) return; p = new TCrossRef[i]; if (numRefs > 0) { crossRefPtr = crossRefs; if (i > numRefs) memmove(p, crossRefPtr, numRefs * sizeof(TCrossRef)); else memmove(p, crossRefPtr, i * sizeof(TCrossRef)); delete crossRefPtr; } crossRefs = p; numRefs = i; } void THelpTopic::setWidth( int aWidth ) { width = aWidth; } void THelpTopic::writeParagraphs( opstream& s ) { int i; TParagraph *p; int temp; p = paragraphs; for (i = 0; p != 0; ++i) p = p->next; s << i; for(p = paragraphs; p != 0; p = p->next) { s << p->size; temp = int(p->wrap); s << temp; s.writeBytes(p->text, p->size); } } void THelpTopic::writeCrossRefs( opstream& s ) { int i; TCrossRef *crossRefPtr; s << numRefs; if (crossRefHandler == notAssigned) { for(i = 0; i < numRefs; ++i) { crossRefPtr = crossRefs + i; s << crossRefPtr->ref << crossRefPtr->offset << crossRefPtr->length; } } else for (i = 0; i < numRefs; ++i) { crossRefPtr = crossRefs + i; crossRefHandler(s, crossRefPtr->ref); s << crossRefPtr->offset << crossRefPtr->length; } } Boolean isBlank( uchar ch ) // fix Help-4 { if (isspace(ch)) return True; else return False; } int scan( char *p, int offset, char c) { char *temp1, *temp2; temp1 = p + offset; temp2 = strchr(temp1, c); if (temp2 == 0) return 256; else { if ((int)(temp2 - temp1) <= 256 ) return (int) (temp2 - temp1) + 1; else return 256; } } void textToLine( void *text, int offset, int length, char *line ) { strncpy(line, (char *)text+offset, length); line[length] = 0; } char *THelpTopic::wrapText( char *text, int size, int& offset, Boolean wrap ) { static char line[256]; int i; i = scan(text, offset, '\n'); if (i + offset > size ) i = size - offset; if ((i >= width) && (wrap == True)) { i = offset + width; if (i > size) i = size; else { while((i > offset) && !(isBlank(text[i]))) --i; /************************************************************************ if (i == offset) i = offset + width; else ++i; *************************************************************************/ if (i == offset) { i = offset + width; while ( (i < size) && !isBlank(text[i]) ) ++i; if ( i < size ) ++i; // Skip blank } else ++i; } if (i == offset) i = offset + width; i -= offset; } textToLine(text, offset, i, line); if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = 0; offset += i; return line; } // THelpIndex const char * const near THelpIndex::name = "THelpIndex"; void THelpIndex::write( opstream& os ) { long *indexArrayPtr; os << size; for (int i = 0; i < (int)size; ++i) { indexArrayPtr = index + i; os << *indexArrayPtr; } } void *THelpIndex::read( ipstream& is ) { long *indexArrayPtr; is >> size; if (size == 0) index = 0; else { index = new long[size]; for(int i = 0; i < (int)size; ++i) { indexArrayPtr = index + i; is >> *indexArrayPtr; } } return this; } TStreamable *THelpIndex::build() { return new THelpIndex( streamableInit ); } TStreamableClass RHelpIndex( THelpIndex::name, THelpIndex::build, __DELTA(THelpIndex) ); THelpIndex::~THelpIndex() { delete index; } THelpIndex::THelpIndex(void): TObject () { size = 0; index = 0; } long THelpIndex::position(int i) { long *indexArrayPtr; if (i < (int)size) { indexArrayPtr = index + i; return (*indexArrayPtr); } else return -1; } void THelpIndex::add( int i, long val ) { int delta = 10; long *p; int newSize; long *indexArrayPtr; if (i >= (int)size) { newSize = (i + delta) / delta * delta; p = new long[newSize]; if (p != 0) { memmove(p, index, size * sizeof(long)); memset(p+size, 0xFF, (newSize - size) * sizeof(long)); } if (size > 0) { delete index; } index = p; size = newSize; } indexArrayPtr = index + i; *indexArrayPtr = val; } // THelpFile THelpFile::THelpFile( fpstream& s ) { long magic; int handle; long size; #ifdef HELPEXTENSIONS helpAlreadyPopped = False; #endif magic = 0; s.seekg(0); handle = s.rdbuf()->fd(); size = filelength(handle); if (size > (long)sizeof(magic)) s >> magic; if (magic != magicHeader) { indexPos = 12; s.seekg(indexPos); index = new THelpIndex; modified = True; } else { s.seekg(8); s >> indexPos; s.seekg(indexPos); s >> index; modified = False; } stream = &s; } THelpFile::~THelpFile(void) { long magic, size; int handle; if (modified == True) { stream->seekp(indexPos); *stream << index; stream->seekp(0); magic = magicHeader; handle = stream->rdbuf()->fd(); size = filelength(handle) - 8; *stream << magic; *stream << size; *stream << indexPos; } delete stream; delete index; } THelpTopic *THelpFile::getTopic( int i ) { long pos; THelpTopic *topic; #ifdef HELPEXTENSIONS if (i == previousTopic) // Show previous help if (oldCount == 0) i = 0; // No previous topics else { if (helpAlreadyPopped) { // Skip current (saved) topic oldFront--; if (oldFront < 0) oldFront=maxOldTopics; oldCount--; } if (helpAlreadyPopped && oldCount == 0) i = 0; // No previous topics else i = oldTopics[oldFront]; // Get previous topic } else // Don't save duplicate entries if (oldCount == 0 || i != (int)oldTopics[oldFront]) { // Save new topic in oldTopics stack oldFront++; if (oldFront > maxOldTopics) oldFront = 0; oldTopics[oldFront] = i; if (oldCount < maxOldTopics) oldCount++; } helpAlreadyPopped = True; #endif pos = index->position(i); if (pos > 0 ) { stream->seekg(pos); *stream >> topic; return topic; } else return(invalidTopic()); } THelpTopic *THelpFile::invalidTopic() { THelpTopic *topic; TParagraph *para; char invalidText[] = "\n No help available in this context."; topic = new THelpTopic; para = new TParagraph; para->text = newStr(invalidText); para->size = strlen(invalidText); para->wrap = False; para->next = 0; topic->addParagraph(para); return topic; } void THelpFile::recordPositionInIndex( int i ) { index->add(i, indexPos); modified = True; } void THelpFile::putTopic( THelpTopic *topic ) { stream->seekp(indexPos); *stream << topic; indexPos = stream->tellp(); modified = True; } void notAssigned( opstream& , int ) { }