summaryrefslogtreecommitdiff
path: root/rhtvision/examples/bhelp/bhelp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'rhtvision/examples/bhelp/bhelp.cc')
-rw-r--r--rhtvision/examples/bhelp/bhelp.cc325
1 files changed, 325 insertions, 0 deletions
diff --git a/rhtvision/examples/bhelp/bhelp.cc b/rhtvision/examples/bhelp/bhelp.cc
new file mode 100644
index 0000000..7a5b231
--- /dev/null
+++ b/rhtvision/examples/bhelp/bhelp.cc
@@ -0,0 +1,325 @@
+/**[txh]********************************************************************
+
+ Copyright (c) 2002 by Jan Van Buggenhout <Chipzz@ULYSSIS.Org>
+
+ Based on code:
+ Copyright (c) 1994 by Borland International
+ Modified by Sergio Sigala <ssigala@globalnet.it>
+ Modified by Salvador E. Tropea <set@ieee.org>, <set@users.sourceforge.net>
+ Copyright (c) 1999 by Andreas F. Gorup von Besanez <besanez@compuserve.de>
+
+ Covered by the GPL license.
+
+ Description:
+ This is a class derived from THelpFile to read Borland help files.
+
+***************************************************************************/
+
+#define Uses_ctype
+#define Uses_limits
+#define Uses_string
+#define Uses_stdlib
+#define Uses_sys_stat
+#define Uses_filelength
+#define Uses_TCollection
+#define Uses_TStreamableClass
+#define Uses_THelpFile
+#define Uses_fpstream
+#include <tv.h>
+#include "bhelp.h"
+
+char *read0String(fpstream & s)
+{
+ int l;
+ long p = s.tellg();
+
+ for (l = 1; s.readByte(); l++) ;
+ char *buffer = new char[l];
+
+ s.seekg(p);
+ s.readBytes(buffer, l);
+ return buffer;
+}
+
+// TBorlandHelpTopic
+
+const char *const TBorlandHelpTopic::name = "TBorlandHelpTopic";
+
+TBorlandHelpTopic::TBorlandHelpTopic(fpstream & s, char *comp)
+{
+ char type;
+ unsigned short datalength, refslength;
+
+ s >> type;
+ s >> datalength;
+ unsigned char *data = new unsigned char[datalength];
+ char *text = new char[datalength * 9];
+ char *curtext = text;
+
+ s.readBytes(data, datalength);
+
+ ushort noRefs;
+
+ s >> type;
+ s >> refslength;
+ s >> previous;
+ s >> next;
+ s >> noRefs;
+ setNumCrossRefs(0);
+ refslength -= 6;
+ ushort *refs = (ushort *)(new uchar[refslength]);
+ ushort *curref = refs;
+
+ s.readBytes(refs, refslength);
+
+ for (long k = 0; k < datalength * 2; k++)
+ {
+ unsigned char Nibble;
+
+ Nibble = (data[k / 2] >> ((k & 1) * 4)) & 0xf;
+ switch (Nibble)
+ {
+
+ case 0:
+ *curtext++ = 0;
+ break;
+
+ case 0xe: /* Rep */
+ {
+ ushort RepCount;
+
+ k++;
+ RepCount = ((data[k / 2] >> ((k & 1) * 4)) & 0xf) + 2;
+ k++;
+ Nibble = (data[k / 2] >> ((k & 1) * 4)) & 0xf;
+ if (Nibble < 0xe)
+ {
+ memset(curtext, comp[Nibble], RepCount);
+ curtext += RepCount;
+ }
+ else if (Nibble == 0xf)
+ {
+ k++;
+ Nibble = data[k / 2] >> ((k & 1) * 4);
+ k++;
+ memset(curtext,
+ Nibble | ((data[k / 2] >> ((k & 1) * 4)) << 4), RepCount);
+ curtext += RepCount;
+ }
+ break;
+ }
+
+ case 0xf: /* Raw */
+ k++;
+ Nibble = data[k / 2] >> ((k & 1) * 4);
+ k++;
+ *curtext++ = Nibble | ((data[k / 2] >> ((k & 1) * 4)) << 4);
+ break;
+
+ default:
+ *curtext++ = comp[Nibble];
+ break;
+ }
+ }
+
+ for (char *para = text; (para < curtext) && (*para != 1);
+ para += strlen(para) + 1)
+ {
+ for (char *ref = strchr(para, 2); ref; ref = strchr(ref, 2))
+ {
+ char *endref = strchr(ref + 1, 2) - 1;
+ int length = endref - ref;
+
+ TCrossRef cref;
+
+ cref.offset = ref - text + 1;
+ cref.length = length;
+ cref.ref = *curref++;
+ addCrossRef(cref);
+
+ memmove(ref, ref + 1, length);
+ memmove(endref, endref + 2, curtext - endref);
+
+ curtext -= 2;
+ }
+ TParagraph *paragraph = new TParagraph;
+
+ paragraph->text = strdup(para);
+ paragraph->size = strlen(para) + 1;
+ paragraph->wrap = False;
+ addParagraph(paragraph);
+ }
+ free(data);
+ free(text);
+ free(refs);
+}
+
+TStreamableClass RBorlandHelpTopic(TBorlandHelpTopic::name,
+ TBorlandHelpTopic::build,
+ __DELTA(TBorlandHelpTopic));
+
+// TBorlandHelpIndex
+
+const char *const TBorlandHelpIndex::name = "TBorlandHelpIndex";
+
+TBorlandHelpIndex::TBorlandHelpIndex(fpstream & s):THelpIndex()
+{
+ unsigned short length;
+ unsigned char *buffer;
+
+ s >> length;
+ buffer = new unsigned char[length];
+
+ s.readBytes(buffer, length);
+ size = *((unsigned short *) buffer);
+ index = new long[size];
+
+ buffer += 2;
+ for (int k = 0; k < size * 3; k += 3)
+ index[k/3] = ((buffer[k + 2] & 0x80) << 24) +
+ (buffer[k] + (buffer[k + 1] << 8) + ((buffer[k + 2] & 0x7f) << 16));
+}
+
+void *TBorlandHelpIndex::read(ipstream & is)
+{
+ // FIXME
+ return 0;
+}
+
+TStreamable *TBorlandHelpIndex::build()
+{
+ return new TBorlandHelpIndex(streamableInit);
+}
+
+TStreamableClass RBorlandHelpIndex(TBorlandHelpIndex::name,
+ TBorlandHelpIndex::build,
+ __DELTA(TBorlandHelpIndex));
+
+// TBorlandHelpFile
+
+TBorlandHelpFile::TBorlandHelpFile(fpstream & s):THelpFile(s)
+{
+ char *Stamp;
+ char FormatVersion;
+
+ modified=False;
+ stream->seekg(0);
+ Stamp = read0String(*stream);
+ stream->seekg(14, CLY_IOSCur);
+ *stream >> FormatVersion;
+ stream->seekg(1, CLY_IOSCur);
+
+ while (!stream->eof())
+ {
+ char type;
+ unsigned short length;
+ unsigned char *buffer=NULL;
+
+ *stream >> type;
+ if (type != 1)
+ {
+ *stream >> length;
+ buffer = (unsigned char *) malloc(length);
+ stream->readBytes(buffer, length);
+ }
+ switch (type)
+ {
+ case 0: /* FileHeader */
+ {
+ ushort *o = (ushort *) buffer;
+ options = o[0];
+ indexscreen = o[1];
+ height = buffer[6];
+ width = buffer[7];
+ margin = buffer[8];
+ break;
+ }
+
+ case 1: /* ConText */
+ index = new TBorlandHelpIndex(*stream);
+ break;
+
+ case 2: /* Text */
+ stream->seekg(-(length + 3), CLY_IOSCur);
+ return;
+
+ case 3: /* KeyWord */
+ stream->seekg(-(length + 3), CLY_IOSCur);
+ return;
+
+ case 4: /* Index */
+ {
+ char temp[41];
+ *temp = 0;
+ glossaryItems = *((ushort *) buffer);
+ glossary = new char *[glossaryItems];
+ char *g = (char *) buffer + 2;
+ for (int i = 0; i < glossaryItems; i++)
+ {
+ uchar lengthcode = *g++;
+ ushort carry = (lengthcode & 0xe0) >> 5;
+ ushort unique = lengthcode & 0x1f;
+ glossary[i] = new char[carry + unique + 3];
+ strncpy(temp + carry, g, unique);
+ temp[carry + unique] = 0;
+ g += unique;
+ strncpy(temp + carry + unique + 1, g, 2);
+ g += 2;
+ memcpy(glossary[i], temp, carry + unique + 3);
+ }
+ break;
+ }
+
+ case 5: /* Compression */
+ *compressiontable = 0;
+ memcpy(compressiontable + 1, buffer + 2, 13);
+ break;
+
+ case 6: /* IndexTags */
+ break;
+ }
+ if (type != 1)
+ free(buffer);
+ }
+}
+
+class TSearchResults : public TCollection
+{
+ public:
+ TSearchResults() : TCollection(0, 1) {};
+ virtual void *readItem( ipstream& ) { return 0; };
+ virtual void writeItem( void *, opstream& ) {};
+};
+
+TCollection *TBorlandHelpFile::search(char *s)
+{
+ char *ss = strdup(s);
+ if (!(options & 4)) strupr(ss);
+ int found = 0;
+ int length = strlen(s);
+ TCollection *coll = new TSearchResults();
+ for (int i = 0; i < glossaryItems; i++)
+ {
+ if (!strncmp(ss, glossary[i], length))
+ {
+ found = 1;
+ coll->insert(glossary[i]);
+ }
+ else if (found) break;
+ }
+ free(ss);
+ return coll;
+}
+
+THelpTopic *TBorlandHelpFile::getTopic(int i)
+{
+ long pos = index->position(i);
+
+ if (pos > 0)
+ {
+ stream->seekg(pos);
+ return new TBorlandHelpTopic(*stream, compressiontable);
+ }
+ else
+ return (invalidTopic());
+}