{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;\f1\fmodern Courier;}
\paperw11440
\paperh9000
\margl120
\margr120
{\colortbl;\red0\green0\blue0;}
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\ulnone\fs24\fc0\cf0 #import <appkit/appkit.h>\
#import "PVlink.h"\
#import "ArchieApp.h"\
#import "ObjectList.h"\
\
#import <objc/NXStringTable.h>\
\
@implementation PVlink\
\

\b0\i\fs28 /*\\ ---------------------- Initialization Methods ---------------------- \\*/
\b\i0\fs24 \
- initVLINK:(VLINK) v\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker250 \markername initVLINK:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  Initializes a PVlink object from the information\
		in the Prospero VLINK structure. 
\fc1\cf1 Parsing is based on\
		the parseHostAndFilename() proceedure of archie.c in the\
		XArchie distribution.;
\fc0\cf0 \
	
\i0\ul Args:
\i\ulnone \
		v: The Prospero VLINK we are to represent;\
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\fc0\cf0 PATTRIB link;\
int y, m, d, hr, min, size;\
char host[MAX_VPATH], location[MAX_VPATH], filename[MAX_VPATH], mode[11];\
void parseHostAndFilename(VLINK , char *, char *, char *);\
\
	parseHostAndFilename(v, host, location, filename);\
	strcat(location, "/");\
	strcat(location, filename);\
	
\b0\i /* Parse v->lattrib */
\b\i0 \
	link = v->lattrib;\
	size = 0;\
	while( link )\
	\{\
		if( strcmp(SIZE, link->aname) == 0 )\
			size = atoi(link->value.ascii);\
		else if( strcmp(MODES, link->aname) == 0 )\
			strncpy(mode, link->value.ascii,10);\
		else if( strcmp(DATE, link->aname) == 0 )\
		\{\
			sscanf(link->value.ascii,"%4d%2d%2d%2d%2d",\
				&y, &m, &d, &hr, &min);\
		\}\
		link = link->next;\
	\}\
	mode[10] = '\\0';\
	[super init: location mode: mode size: size day: d month: m year: y\
		hour: hr min: min];\
	[super setSourceHost: host];\
	
\b0\i\fc1\cf1 /* Save the Prospero host and filename for later use */
\b\i0\fc0\cf0 \
	vlinkHostname = NXCopyStringBuffer(v->host);\
	vlinkFilename = NXCopyStringBuffer(v->filename);\
\
	return self;\
\} 
\b0\i\fc1\cf1 // End initVLINK:
\b\i0\fc0\cf0 \
\
- setListing: (VLINK) entries\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker1577 \markername setListing:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  A ObjectList of PVlink objects corresponding to entries;\
	
\i0\ul Description:
\i\ulnone  This method parses the linked list of VLINK structs\
		given by entries into a ObjectList of corresponding PVlink objects and\
		assigns the list to our listing instance variable. This\
		list represents the contents of a Prospero directory.
\fc1\cf1 ;
\fc0\cf0 \
	
\i0\ul Args:
\i\ulnone \
		entries: A linked list of VLINKs for our directory contents;\
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\fc0\cf0 VLINK next;\
id vlink;\
\
	if( listing != nil )\
		[listing empty];\
	else\
		listing = [[ObjectList alloc] initCount: 0];\
\
	while( entries != NULL )\
	\{\
		vlink = [[PVlink alloc]  initVLINK: entries];\
		if(vlink == nil)\
		\{\
			[listing free];\
			return nil;\
		\}\
		[listing addObject: vlink];\
		next = entries->next;\
		entries = next;\
	\}\
	dirLoading = NO;\
\
	return listing;\
\} 
\b0\i // End setListing:
\b\i0 \
\
- free\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker2399 \markername free;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  [super free];\
	
\i0\ul Description:
\i\ulnone  This method frees the variables we allocate
\fc1\cf1 ;
\fc0\cf0 \
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\fc0\cf0 	free(vlinkHostname);\
	free(vlinkFilename);\
\
	return [super free];\
\} 
\b0\i // End free
\b\i0 \
\

\b0\i\fs28\fc1\cf1 /*\\ -------------------- Info Methods -------------------- \\*/
\b\i0\fs24\fc0\cf0 \
- (const char *) vlinkHostname\
\{ 
\f1\b0\i // 
{\f0\b\i0{\NeXTHelpMarker2694 \markername vlinkHostname;}
¬}\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\ulnone\fs24\fc0\cf0 \
	return vlinkHostname;\
\}\
- (const char *) vlinkFilename\
\{ 
\f1\b0\i // 
{\f0\b\i0{\NeXTHelpMarker2757 \markername vlinkFilename;}
¬}\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\ulnone\fs24\fc0\cf0 \
	return vlinkFilename;\
\}\
\
- writeInfo:(NXStream *) stream\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker2821 \markername writeInfo:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  This method writes a simple description of the\
		PVlink we represent to the argument stream
\fc1\cf1 ;
\fc0\cf0 \
	
\i0\ul Args:
\i\ulnone \
		stream: The NXStream to write the info to;\
*/
\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\b\i0\fc0\cf0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\fc0\cf0 char *type, *date_string;\
\
	date_string = [super fullStringDate];\
	date_string += 4;	// Skip past day of week\
	type = ([self isDirectory] == YES ? "DIR" : "FILE");\
	NXPrintf(stream, "%s\\t%s\\t%d\\t%s\\t%s\\n", type, fileMode, fileSize,\
		date_string, [self sourceName]);\
\
	return self;\
\} 
\b0\i // End writeInfo:
\b\i0 \
\

\b0\i\fs28\fc1\cf1 /*\\ --------------------- ObjectArchival Methods --------------------- \\*/
\b\i0\fs24\fc0\cf0 \
static inline char *ClassName() \{ return "VLINK"; \}\
static inline long ArchiveVersion()\
\{\
long version;\
	version = 1000 * VLINK_VERS + 10 * VLINK_SUBVERS + VLINK_TYPE;\
	return version;\
\}\
\
- readFromTStream:(NXTypedStream *) stream\
\{\

\pard\tx180\tx360\tx540\tx720\tx900\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker3640 \markername readFromTStream:;}
¬}\pard\tx180\tx360\tx540\tx720\tx900\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self if successful, nil on failure;\
	
\i0\ul Description:
\i\ulnone  This method unarchives a PVlink object description from the\
		typed stream that was previously save by the 
\b writeToTStream:
\b0  method.\
		The receiving PVlink object must have been allocated and inited using\
		
\b [
\fc1\cf1 [PVlink a
\fc0\cf0 lloc] init]
\b0  or 
\b [
\fc1\cf1 [PVlink a
\fc0\cf0 lloc] 
\fc1\cf1 initFromTStream
\fc0\cf0 :]
\b0 .\
		If the object is sucessfully read from the stream, self is returned.\
		If an exception occurs the object is freed and nil is returned.;\
	
\i0\ul Args:
\i\ulnone  \
		stream: The typed stream from which to read the object;\
*/
\f0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b\i0\fc0\cf0 const char *className;\
BOOL hasListing;\
long version;\
void *data1 = NULL, *data2 = NULL;\
\
NX_DURING\

\f1\b0\fs20 [self debug: SUPER_DEBUG method: _cmd, "class = %s; superclass = %s\\n",\
	[[self class] name], [[self superclass] name]];\
[self debug: SUPER_DEBUG method: _cmd, "\\tinstance = %s\\n", ClassName()];
\f0\b\fs24 \
\
	
\b0\i /* Unarchive our File superclass */
\b\i0 \
	[super readFromTStream: stream];\
\
	
\b0\i /* First read the class name & archive version info */
\b\i0 \
	NXReadTypes(stream, "*i", &className, &version);\
	if( strcmp(className, ClassName()) != 0 )\
	\{\
		NXAllocErrorData(strlen(className)+1, &data1);\
		NXAllocErrorData(strlen(ClassName())+1, &data2);\
		strcpy(data1, className);\
		strcpy(data2, ClassName());\
		NX_RAISE(eWrongClassName, data1, data2);\
	\}\
\
	
\b0\i /* Unarchive our instance variables */
\b\i0 \
	switch( version )\
	\{\
		case VLINK_VERSION_0:\
		case VLINK_VERSION_1:\
			NXReadType(stream, "*", &vlinkHostname);\
			NXReadType(stream, "*", &vlinkFilename);\
\
			if( version < FILE_VERSION_1 )\
			\{	
\b0\i /* Early versions of PVlink did not store their listing entries in the\
					File instance variable.  So, the next archive item should be a bool\
					flag indicating if we have a listing varible in the archive */
\b\i0 \
				NXReadType(stream, "c", &hasListing);\
				if( hasListing == YES )\
				\{\
				List *tmpList;\
				File *tmpObj;\
						tmpList = [[List alloc] initFromTStream: stream];\

\b0\i 						/* Create an ObjectList and transfer the elements from the List */
\b\i0 \
						listing =  [[ObjectList alloc] initCount: 0 sortAlgorithm: eShellSort\
							typeID: eStringType keyMethod: @selector(sourceName)];\
						while( (tmpO
\fc1\cf1 bj = [tmpList removeObjectAt: 0]) != nil )\
							[
\fc0\cf0 listing
\fc1\cf1  insertObject: tmpObj];
\fc0\cf0 \
						[tmpList free];\
				\}\
			\}\
			break;\
\
		default:\
			NXAllocErrorData(strlen([[self class] name])+1, &data1);\
			NXAllocErrorData(sizeof(long), &data2);\
			strcpy(data1, [[self class] name]);\
			*((long *) data2) = version;\
			NX_RAISE(eBadObjVersion, data1, data2);\
			break;\
	\}\
NX_HANDLER\
	NX_RERAISE();\
NX_ENDHANDLER\
\
	return self;\
\} 
\b0\i // End readFromTStream:
\b\i0 \
\
- writeToTStream:(NXTypedStream *) stream\
\{\

\pard\tx180\tx360\tx540\tx720\tx900\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker6268 \markername writeToTStream:;}
¬}\pard\tx180\tx360\tx540\tx720\tx900\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self if successful, nil on failure;\
	
\i0\ul Description:
\i\ulnone  This method archives a PVlink object description to the\
		typed stream.  If the object is sucessfully written to the stream,\
		 self is returned.  If an exception occurs it is rerasied.;\
	
\i0\ul Args:
\i\ulnone  \
		stream: The typed stream to write the object to;\
*/
\f0 \

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\b\i0\fc0\cf0 const char *className;\
long version;\
\
NX_DURING\

\f1\b0\fs20 [self debug: SUPER_DEBUG method: _cmd, "class = %s; superclass = %s\\n",\
	[[self class] name], [[self superclass] name]];\
[self debug: SUPER_DEBUG method: _cmd, "\\tinstance = %s\\n", ClassName()];
\f0\b\fs24 \
\
	
\b0\i /* Archive our superclass */
\b\i0 \
	[super writeToTStream: stream];\
\
	
\b0\i /* Archive the class name & version */
\b\i0 \
	className = ClassName();\
	version = ArchiveVersion();\
	NXWriteTypes(stream, "*i", &className, &version);\
\
	
\b0\i\fc1\cf1 /* Archive our instance variables */
\b\i0\fc0\cf0 \
	NXWriteType(stream, "*", &vlinkHostname);\
	NXWriteType(stream, "*", &vlinkFilename);\
\
NX_HANDLER\
	NX_RERAISE();\
NX_ENDHANDLER\
\
	return self;\
\} 
\b0\i // End writeToTStream:
\b\i0 \
\
@end\

\b0\i /* RCS Information:\
	$Author: me $;\
	$Date: 94/01/08 14:41:05 $;\
	$Source: /usr1/me/NeXTSrc/Archie/RCS/PVlink.m,v $;\
	$Revision: 1.1 $;\
*/\

}
