This is ArticleDisplay.m in view mode; [Download] [Up]
// ArticleDisplay.m -
#import "ArticleDisplay.h"
static const char *fieldNames[FIELD_COUNT] = {
"Date", "Followup-to", "Newsgroups", "Subject", "Summary", "Keywords",
"Organization", "From", "Reply-To"
};
@implementation ArticleDisplay
+ new
{
self = [super new];
return self;
}
- setupNNTP:(FILE *)newnntpFile
{
nntpFile = newnntpFile;
}
- clear
{
int fieldIndex;
for (fieldIndex=0; fieldIndex<FIELD_COUNT; fieldIndex++)
[field[fieldIndex] setStringValue:""];
[bodyText setText:""];
}
- readArticle
{
int inCode;
char inCodeText[BUFFER_SIZE];
int ch;
char aLine[BUFFER_SIZE];
int aLineLength, charIndex;
char fieldName[BUFFER_SIZE];
int fieldIndex;
BOOL found;
int newLines;
static char *textBuffer;
static int textBufferLines = 0;
int textBufferOffset;
if (selectedArticle == nil)
return self;
[bodyText setText:""];
// HEAD
fprintf(nntpFile, "head %ld\r\n", selectedArticle->number);
fflush(nntpFile);
fseek(nntpFile, (long)0, SEEK_END);
fscanf(nntpFile, "%d %[^\r]\r\n", &inCode, &inCodeText);
if (inCode != OK_HEAD)
printf("No way, fix me HEAD2.\n"); // fix
for (fieldIndex=0; fieldIndex<FIELD_COUNT; fieldIndex++)
bogusField[fieldIndex] = TRUE;
while ((ch = fgetc(nntpFile)) != '.') {
ungetc(ch, nntpFile);
fscanf(nntpFile, "%[^\r]\r\n", &aLine);
sscanf(aLine, "%[^:]:", fieldName);
for (found=FALSE,fieldIndex=0; (!found) && (fieldIndex<FIELD_COUNT);
fieldIndex++)
if (strcmp(fieldName, fieldNames[fieldIndex]) == 0) {
[field[fieldIndex] setStringValue:aLine];
bogusField[fieldIndex] = FALSE;
found = TRUE;
}
if (!found) {
if (strcmp(fieldName, "Lines") == 0) {
sscanf(aLine, "Lines: %d", &newLines);
}
}
}
for (fieldIndex=0; fieldIndex<FIELD_COUNT; fieldIndex++)
if (bogusField[fieldIndex]) {
[field[fieldIndex] setStringValue:""];
}
fgetc(nntpFile); // \r
fgetc(nntpFile); // \n
fseek(nntpFile, (long)0, SEEK_END);
// BODY
fprintf(nntpFile, "%s\r\n", (verbose?"article":"body"));
fflush(nntpFile);
fseek(nntpFile, (long)0, SEEK_END);
fscanf(nntpFile, "%d %[^\r]\r\n", &inCode, &inCodeText);
if (inCode != (verbose?OK_ARTICLE:OK_BODY))
printf("No way, fix me HEAD3.\n"); // fix
if (textBufferLines == 0)
textBuffer = calloc(newLines, BUFFER_SIZE);
else
textBuffer = realloc(textBuffer, newLines*BUFFER_SIZE);
textBufferLines = newLines;
textBufferOffset = 0;
while (((ch = fgetc(nntpFile)) != '.') || ((ch = fgetc(nntpFile)) != '\r')) {
ungetc(ch, nntpFile);
if (fscanf(nntpFile, "%[^\r]\r\n", &aLine) == 1)
aLineLength = strlen(aLine);
else
aLineLength = 0;
if (rot) {
for (charIndex=0; charIndex<aLineLength; charIndex++) {
if (islower(aLine[charIndex]))
aLine[charIndex] = (((aLine[charIndex] - 'a') + 13) % 26) + 'a';
if (isupper(aLine[charIndex]))
aLine[charIndex] = (((aLine[charIndex] - 'A') + 13) % 26) + 'A';
}
}
strncpy(&(textBuffer[textBufferOffset]), aLine, aLineLength);
textBuffer[textBufferOffset+aLineLength] = '\n';
textBufferOffset += aLineLength+1;
}
textBuffer[textBufferOffset] = '\0';
[bodyText setText:textBuffer];
fgetc(nntpFile); // \n
fseek(nntpFile, (long)0, SEEK_END);
return self;
}
- setArticle:sender
{
IconColumnCell *selectedCell = [sender selectedCell];
Article *newSelectedArticle = [selectedCell aux];
if (newSelectedArticle != selectedArticle) {
selectedArticle = newSelectedArticle;
if (selectedArticle != nil) {
if (!selectedArticle->seen) {
[sender cellToggleSeen:selectedCell];
[sender drawCell:selectedCell];
}
[self readArticle];
} else
[self clear];
}
return self;
}
- setVerbose:sender
{
verbose = !verbose;
// [sender setText:(verbose?"Hide Header":"Show Header")];
[self readArticle];
return self;
}
- setRot:sender
{
rot = !rot;
[self readArticle];
return self;
}
- setDateDisplay:anObject
{
field[DATE] = anObject;
return self;
}
- setFollowupToTextField:anObject
{
field[FOLLOWUP_TO] = anObject;
return self;
}
- setNewsgroupsTextField:anObject
{
field[NEWSGROUPS] = anObject;
return self;
}
- setSubjectTextField:anObject
{
field[SUBJECT] = anObject;
return self;
}
- setSummaryTextField:anObject
{
field[SUMMARY] = anObject;
return self;
}
- setKeywordsTextField:anObject
{
field[KEYWORDS] = anObject;
return self;
}
- setOrganizationTextField:anObject
{
field[ORGANIZATION] = anObject;
return self;
}
- setFromTextField:anObject
{
field[FROM] = anObject;
return self;
}
- setReplyToTextField:anObject
{
field[REPLY_TO] = anObject;
return self;
}
- setBodyText:anObject
{
bodyText = [anObject docView]; // starts as "ScrollText"
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.