(FILECREATED " 7-Feb-86 00:46:12" {QV}<NOTECARDS>1.3K>RHTPATCH024.;19 63747  

      changes to:  (FNS NC.ReadPropList)
		   (VARS RHTPATCH024COMS)

      previous date: " 4-Feb-86 11:10:43" {QV}<NOTECARDS>1.3K>RHTPATCH024.;18)


(* Copyright (c) 1986 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT RHTPATCH024COMS)

(RPAQQ RHTPATCH024COMS ((* * Stuff for copying cards from one notefile to another, or to the same. 
			     All belongs in NCDATABASE, I guess.)
			  (GLOBALVARS NC.CopyCardsLinksHashArraySize NC.CopyBrowserHashArraySize)
			  (INITVARS (NC.CopyCardsLinksHashArraySize 100)
				    (NC.CopyBrowserHashArraySize 100))
			  (RECORDS IndexLocs)
			  (FNS NC.CopyCards NC.PutNoteCardToStream NC.GetNoteCardFromStream 
			       NC.MakeHashKeyFromCard)
			  (FNS NC.FixUpLinksInCardCopy NC.FixUpBrowserCardCopy 
			       NC.BrowserCopyConvertGraphNodeID)
			  (* * This also new for NCDATABASE. Belongs with other similar fns like 
			     NC.UIDRemProp, etc.)
			  (FNS NC.UIDGetPropList)
			  (* * New functions for NCUTILITIES)
			  (FNS NC.CoerceToNoteFileStream)
			  (* * Changes from NCDATABASE)
			  (FNS NC.GetMainCardData NC.GetLinks NC.GetTitle NC.GetPropList NC.GetType)
			  (FNS NC.PutMainCardData NC.PutLinks NC.PutRegion NC.PutTitle NC.PutPropList)
			  (FNS NC.ReadCardPartHeader NC.ReadIdentifier NC.ReadRegion 
			       NC.ReadListOfLinks NC.ReadUID NC.ReadDate NC.ReadCardType NC.ReadTitle 
			       NC.ReadPropList)
			  (FNS NC.WriteCardPartHeader NC.WriteIdentifier NC.WriteRegion 
			       NC.WriteListOfLinks NC.WriteUID NC.WriteDate NC.WriteCardType 
			       NC.WriteTitle NC.WritePropList)
			  (* * Changes for NCTEXTCARD)
			  (FNS NC.GetTextSubstance NC.PutTextSubstance)
			  (* * Changes for NCGRAPHCARD)
			  (FNS NC.GetGraphSubstance NC.PutGraphSubstance)
			  (* * Changes for NCSKETCHCARD)
			  (FNS NC.GetSketchSubstance NC.PutSketchSubstance)
			  (* * Changes for NCLISTCARD)
			  (FNS NC.ListCardGetFn NC.ListCardPutFn)
			  (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS
				    (ADDVARS (NLAMA)
					     (NLAML)
					     (LAMA)))))
(* * Stuff for copying cards from one notefile to another, or to the same. All belongs in 
NCDATABASE, I guess.)

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.CopyCardsLinksHashArraySize NC.CopyBrowserHashArraySize)
)

(RPAQ? NC.CopyCardsLinksHashArraySize 100)

(RPAQ? NC.CopyBrowserHashArraySize 100)
[DECLARE: EVAL@COMPILE 

(DATATYPE IndexLocs (MainCardDataLoc LinksLoc TitleLoc PropListLoc))
]
(/DECLAREDATATYPE (QUOTE IndexLocs)
		  (QUOTE (POINTER POINTER POINTER POINTER))
		  (QUOTE ((IndexLocs 0 POINTER)
			  (IndexLocs 2 POINTER)
			  (IndexLocs 4 POINTER)
			  (IndexLocs 6 POINTER)))
		  (QUOTE 8))
(DEFINEQ

(NC.CopyCards
  (LAMBDA (Cards DestNoteFileOrFileBox RootCards QuietFlg)   (* rht: "30-Jan-86 19:04")

          (* * Create copies of cards in Cards. If DestNoteFileOrFileBox is a notefile, then destination will be the contents
	  box in that notefile, else the FileBox's notefile. RootCards should be NIL or a subset of Cards.
	  If NIL, then file all Cards in the dest filebox. Otherwise, just file RootCards in that filebox and assume others 
	  are linked somehow to the RootCards. Links between cards in Cards are copied, but links from or to outside cards 
	  aren't.)



          (* * Currently all Cards must be in same notefile, but this perhaps could be relaxed if could prevent possibility 
	  of two cards in different notefiles having the same UID.)


    (LET ((NumCards (LENGTH Cards))
	  SourceNoteFile DestNoteFile BoxToFileIn TempStream CardHashArray LinksHashArray 
	  CurrentLinkLabels NewLinkLabels NewCardsAndLocsOnStream)

          (* * Make sure the arguments are valid.)


         (if (NULL Cards)
	     then (NC.ReportError "NC.CopyCards" "Improper Cards arg: NIL"))
                                                             (* All Cards to copy must live in same notefile.)
         (SETQ SourceNoteFile (fetch (Card NoteFile) of (CAR Cards)))
         (if (NOT (AND (type? NoteFile SourceNoteFile)
			     (OPENP (fetch (NoteFile Stream) of SourceNoteFile))))
	     then (NC.ReportError "NC.CopyCards" SourceNoteFile " not an open notefile."))
         (if (NOT (for Card in Cards always (NC.SameNoteFileP (fetch (Card NoteFile)
									     of Card)
									  SourceNoteFile)))
	     then (NC.ReportError "NC.CopyCards" 
				      "All cards in Cards arg don't live in the same notefile."))
                                                             (* Compute dest notefile and dest filebox.)
         (if (type? NoteFile DestNoteFileOrFileBox)
	     then (SETQ DestNoteFile DestNoteFileOrFileBox)
		    (SETQ BoxToFileIn (fetch (NoteFile TableOfContentsCard) of DestNoteFile))
	   elseif (NCP.FileBoxP DestNoteFileOrFileBox)
	     then (SETQ BoxToFileIn DestNoteFileOrFileBox)
		    (SETQ DestNoteFile (fetch (Card NoteFile) of BoxToFileIn))
	   else (NC.ReportError "NC.CopyCards" (CONCAT "Arg not notefile or filebox: " 
							     DestNoteFileOrFileBox)))
         (if (NOT (AND (type? NoteFile DestNoteFile)
			     (OPENP (fetch (NoteFile Stream) of DestNoteFile))))
	     then (NC.ReportError "NC.CopyCards" DestNoteFile " not an open notefile."))
         (if (LDIFFERENCE RootCards Cards)
	     then (NC.ReportError "NC.CopyCards" 
				      "RootCards argument not subset of Cards argument."))
         (if (NULL RootCards)
	     then (SETQ RootCards Cards))

          (* * Now get to work.)


         (SETQ TempStream (OPENSTREAM (QUOTE {NODIRCORE})
					  (QUOTE BOTH)))
         (SETQ CurrentLinkLabels (NC.RetrieveLinkLabels DestNoteFile))
         (SETQ NewLinkLabels (TCONC NIL))
         (SETQ LinksHashArray (HASHARRAY NC.CopyCardsLinksHashArraySize NIL
					     (FUNCTION NC.MakeHashKey)
					     (FUNCTION NC.SameUIDP)))
         (SETQ CardHashArray (HASHARRAY NumCards NIL (FUNCTION NC.MakeHashKeyFromCard)
					    (FUNCTION NC.SameCardP)))

          (* * Create new cards in DestNoteFile for each card. Make these cards by copying original cards to a temp stream.
	  Keep track of UID mappings between original cards and card copies using CardHashArray.)


         (OR QuietFlg (NC.PrintMsg NIL T "Copying cards: creating empty copies." (CHARACTER
					 13)
				       "Processing item " 1 " out of " NumCards "..." (CHARACTER
					 13)))
         (SETQ NewCardsAndLocsOnStream
	   (for Card in Cards as i from 1 bind NewCard WasActiveFlg HadStatusNILFlg 
							 IndexLocs
	      eachtime (BLOCK)
	      collect (OR QuietFlg (if (ZEROP (REMAINDER i 100))
					   then (NC.PrintMsg NIL T 
							  "Copying cards: creating empty copies."
								 (CHARACTER 13)
								 "Processing item " i " out of " 
								 NumCards "..." (CHARACTER 13))))
			(if (NOT (SETQ WasActiveFlg (NC.ActiveCardP Card)))
			    then (NC.GetNoteCard Card))
			(if (SETQ HadStatusNILFlg (NULL (fetch (Card Status) of Card)))
			    then                           (* Have to have Status slot ACTIVE in order that Put 
							     to stream won't break.)
				   (replace (Card Status) of Card with (QUOTE ACTIVE)))
			(SETQ IndexLocs (NC.PutNoteCardToStream Card NIL T TempStream))
			(if HadStatusNILFlg
			    then (replace (Card Status) of Card with NIL))
			(if (NOT WasActiveFlg)
			    then (NC.DeactivateCard Card))
                                                             (* Make new empty card for copy.)
			(SETQ NewCard (NC.GetNewCard DestNoteFile)) 
                                                             (* Map old cards to card copies.)
			(PUTHASH Card NewCard CardHashArray)
			(CONS NewCard IndexLocs)))

          (* * For each card, get it off the temp stream, fix its links, fix browser info if necessary, and write it down to 
	  the dest notefile.)


         (SETFILEPTR TempStream 0)
         (OR QuietFlg (NC.PrintMsg NIL T "Copying cards: fixing links and browser cards."
				       (CHARACTER 13)
				       "Processing item " 1 " out of " NumCards "..." (CHARACTER
					 13)))
         (for NewCardAndLocsOnStream in NewCardsAndLocsOnStream as i from 1 eachtime
										     (BLOCK)
	    do (OR QuietFlg (if (ZEROP (REMAINDER i 100))
				    then (NC.PrintMsg NIL T 
						 "Copying cards: fixing links and browser cards."
							  (CHARACTER 13)
							  "Processing item " i " out of " NumCards 
							  "..."
							  (CHARACTER 13))))
		 (LET ((NewCard (CAR NewCardAndLocsOnStream))
		       (IndexLocs (CDR NewCardAndLocsOnStream)))
                                                             (* Have to make status active for Get fns to work.)
		      (NC.SetStatus NewCard (QUOTE ACTIVE))
		      (NC.GetNoteCardFromStream NewCard TempStream IndexLocs)
		      (NC.FixUpLinksInCardCopy NewCard CardHashArray LinksHashArray 
						 CurrentLinkLabels NewLinkLabels)
		      (if (NC.IsSubTypeOfP (NC.FetchType NewCard)
					       (QUOTE Browser))
			  then (NC.FixUpBrowserCardCopy NewCard CardHashArray))
		      (NC.PutNoteCard NewCard)))

          (* * Link RootCards under filebox in DestNotefile.)


         (OR QuietFlg (NC.PrintMsg NIL T "Copying cards: filing " (LENGTH RootCards)
				       " new cards in "
				       (NC.FetchTitle BoxToFileIn)
				       "..."
				       (CHARACTER 13)))
         (NC.FileBoxCollectChildren NIL BoxToFileIn (for RootCard in RootCards eachtime
										      (BLOCK)
							 collect (GETHASH RootCard CardHashArray))
				      T)

          (* * Put out any new link labels to the dest notefile.)


         (AND (SETQ NewLinkLabels (CDAR NewLinkLabels))
		(NC.StoreLinkLabels DestNoteFile (APPEND NewLinkLabels CurrentLinkLabels)))
         (OR QuietFlg (NC.PrintMsg NIL T "Done." (CHARACTER 13))))))

(NC.PutNoteCardToStream
  (LAMBDA (Card UpdateUpdateListFlg UseOldDateFlg Stream)    (* rht: "28-Jan-86 14:12")

          (* * Put all the card parts of Card down to Stream and return an IndexLocs record containing locations of each of 
	  the card parts just written down.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET (MainCardDataLoc LinksLoc TitleLoc PropListLoc)
		       (SETQ MainCardDataLoc (GETFILEPTR Stream))
		       (NC.PutMainCardData Card UpdateUpdateListFlg UseOldDateFlg Stream)
		       (SETQ LinksLoc (GETFILEPTR Stream))
		       (NC.PutLinks Card UseOldDateFlg Stream)
		       (SETQ TitleLoc (GETFILEPTR Stream))
		       (NC.PutTitle Card UseOldDateFlg Stream)
		       (SETQ PropListLoc (GETFILEPTR Stream))
		       (NC.PutPropList Card UseOldDateFlg Stream)
		       (create IndexLocs
				 MainCardDataLoc ← MainCardDataLoc
				 LinksLoc ← LinksLoc
				 TitleLoc ← TitleLoc
				 PropListLoc ← PropListLoc)))))

(NC.GetNoteCardFromStream
  (LAMBDA (Card Stream IndexLocs)                            (* rht: "28-Jan-86 14:17")

          (* * Like NC.GetNoteCard except gets card from given Stream instead of its notefile. Uses IndexLocs record to know 
	  where to look for card parts.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (SETFILEPTR Stream (fetch (IndexLocs MainCardDataLoc) of IndexLocs))
		  (NC.GetMainCardData Card Stream)
		  (SETFILEPTR Stream (fetch (IndexLocs LinksLoc) of IndexLocs))
		  (NC.GetLinks Card Stream)
		  (SETFILEPTR Stream (fetch (IndexLocs TitleLoc) of IndexLocs))
		  (NC.GetTitle Card Stream)
		  (SETFILEPTR Stream (fetch (IndexLocs PropListLoc) of IndexLocs))
		  (NC.GetPropList Card Stream)
		  (NC.ActivateCard Card)
		  Card)))

(NC.MakeHashKeyFromCard
  (LAMBDA (Card)                                             (* rht: "28-Jan-86 15:54")

          (* * Create a hash key from the card's UID.)


    (NC.MakeHashKey (fetch (Card UID) of Card))))
)
(DEFINEQ

(NC.FixUpLinksInCardCopy
  (LAMBDA (CardCopy CardHashArray LinksHashArray CurrentLinkLabels NewLinkLabels)
                                                             (* rht: "28-Jan-86 15:08")

          (* * For all the links from or to CardCopy, change other endpoint's card according to mapping table in 
	  CardHashArray. If other endpoint is a card not found in the hash array, then drop that link altogether.
	  The mapping from old link UIDs to new ones is in LinksHashArray. Any new link labels not in CurrentLinkLabels get 
	  TCONC'ed onto NewLinkLabels.)


    (LET ((CardCopyType (NC.FetchType CardCopy))
	  DelReferencesFn CollectReferencesFn)
         (SETQ DelReferencesFn (NC.DelReferencesFn CardCopyType))
         (SETQ CollectReferencesFn (NC.CollectReferencesFn CardCopyType))

          (* * Fix all the From links.)


         (NC.SetFromLinks CardCopy (for Link in (NC.FetchFromLinks CardCopy) eachtime
										      (BLOCK)
					bind SourceCard OldLinkUID
					when (SETQ SourceCard (GETHASH (fetch (Link 
										       SourceCard)
										of Link)
									     CardHashArray))
					collect (replace (Link DestinationCard) of Link
						     with CardCopy)
						  (replace (Link SourceCard) of Link
						     with SourceCard)
						  (replace (Link UID) of Link
						     with (OR (GETHASH (SETQ OldLinkUID
									       (fetch (Link UID)
										  of Link))
									     LinksHashArray)
								  (PUTHASH OldLinkUID (NC.MakeUID)
									     LinksHashArray)))
                                                             (* Keep track of link labels in case any are new.)
						  (OR (FMEMB (SETQ LinkLabel
								   (fetch (Link Label)
								      of Link))
								 CurrentLinkLabels)
							(NC.SystemLinkLabelP LinkLabel)
							(FMEMB LinkLabel (CAR NewLinkLabels))
							(TCONC NewLinkLabels LinkLabel))
						  Link))

          (* * Do it all again for the To links.)


         (NC.SetToLinks CardCopy (for Link in (NC.FetchToLinks CardCopy) eachtime (BLOCK)
				      bind DestCard OldLinkUID when (SETQ DestCard
									  (GETHASH
									    (fetch (Link 
										  DestinationCard)
									       of Link)
									    CardHashArray))
				      collect (replace (Link SourceCard) of Link with 
											 CardCopy)
						(replace (Link DestinationCard) of Link
						   with DestCard)
						(replace (Link UID) of Link
						   with (OR (GETHASH (SETQ OldLinkUID
									     (fetch (Link UID)
										of Link))
									   LinksHashArray)
								(PUTHASH OldLinkUID (NC.MakeUID)
									   LinksHashArray)))
                                                             (* Keep track of link labels in case any are new.)
						(OR (FMEMB (SETQ LinkLabel (fetch
								   (Link Label) of Link))
							       CurrentLinkLabels)
						      (NC.SystemLinkLabelP LinkLabel)
						      (FMEMB LinkLabel (CAR NewLinkLabels))
						      (TCONC NewLinkLabels LinkLabel))
						Link))

          (* * Now fix the links inside imageobj's in the card's substance.)


         (AND CollectReferencesFn (for Link in (CAR (APPLY* CollectReferencesFn CardCopy))
				       do (if (SETQ DestCard (GETHASH (fetch (Link 
										  DestinationCard)
										 of Link)
									      CardHashArray))
						then (replace (Link SourceCard) of Link
							  with CardCopy)
						       (replace (Link DestinationCard)
							  of Link with DestCard)
						       (replace (Link UID) of Link
							  with (OR (GETHASH
									 (SETQ OldLinkUID
									   (fetch (Link UID)
									      of Link))
									 LinksHashArray)
								       (PUTHASH OldLinkUID
										  (NC.MakeUID)
										  LinksHashArray)))
                                                             (* Keep track of link labels in case any are new.)
						       (OR (FMEMB (SETQ LinkLabel
									(fetch (Link Label)
									   of Link))
								      CurrentLinkLabels)
							     (NC.SystemLinkLabelP LinkLabel)
							     (FMEMB LinkLabel (CAR NewLinkLabels))
							     (TCONC NewLinkLabels LinkLabel))
					      else (APPLY* DelReferencesFn CardCopy Link)))))))

(NC.FixUpBrowserCardCopy
  (LAMBDA (BrowserCard CardsHashArray)                       (* rht: "29-Jan-86 13:04")

          (* * Fix up the parts of the new browser card copy. Need to fix roots and graphnodes.)


    (LET ((Graph (NC.FetchSubstance BrowserCard))
	  (GraphNodeIDHashArray (HASHARRAY NC.CopyBrowserHashArraySize NIL (FUNCTION 
					       NC.MakeHashKey)
					     (FUNCTION NC.SameUIDP))))

          (* * Fix up browser roots.)


         (NC.SetBrowserRoots BrowserCard (for Card in (NC.FetchBrowserRoots BrowserCard)
					      collect (GETHASH Card CardsHashArray)))

          (* * Fix up graph nodes.)


         (for GraphNode in (fetch (GRAPH GRAPHNODES) of Graph) eachtime (BLOCK)
	    do (replace (GRAPHNODE NODEID) of GraphNode with (
								 NC.BrowserCopyConvertGraphNodeID
								       (fetch (GRAPHNODE NODEID)
									  of GraphNode)
								       GraphNodeIDHashArray))
		 (replace (GRAPHNODE TONODES) of GraphNode
		    with (for NodeID in (fetch (GRAPHNODE TONODES) of GraphNode)
			      collect (if (EQ (CAR NodeID)
						    LINKPARAMS)
					    then (RPLACA (CDR NodeID)
							     (NC.BrowserCopyConvertGraphNodeID
							       (CADR NodeID)
							       GraphNodeIDHashArray))
						   (AND (LISTGET NodeID (QUOTE NODEID))
							  (LISTPUT NodeID (QUOTE NODEID)
								     (
								 NC.BrowserCopyConvertGraphNodeID
								       (LISTGET NodeID
										  (QUOTE NODEID))
								       GraphNodeIDHashArray)))
						   (AND (LISTGET NodeID (QUOTE DESTNODEID))
							  (LISTPUT NodeID (QUOTE DESTNODEID)
								     (
								 NC.BrowserCopyConvertGraphNodeID
								       (LISTGET NodeID
										  (QUOTE DESTNODEID)
										  )
								       GraphNodeIDHashArray)))
						   NodeID
					  else (NC.BrowserCopyConvertGraphNodeID NodeID 
									     GraphNodeIDHashArray))))
		 (replace (GRAPHNODE FROMNODES) of GraphNode
		    with (for NodeID in (fetch (GRAPHNODE FROMNODES) of GraphNode)
			      collect (if (EQ (CAR NodeID)
						    LINKPARAMS)
					    then (RPLACA (CDR NodeID)
							     (NC.BrowserCopyConvertGraphNodeID
							       (CADR NodeID)
							       GraphNodeIDHashArray))
						   NodeID
					  else (NC.BrowserCopyConvertGraphNodeID NodeID 
									     GraphNodeIDHashArray)))))
      )))

(NC.BrowserCopyConvertGraphNodeID
  (LAMBDA (NodeID GraphNodeIDHashArray)                      (* rht: "29-Jan-86 13:04")

          (* * Convert a graph node ID using the given hash array.)


    (if (LISTP NodeID)
	then (LIST (OR (GETHASH (CAR NodeID)
					GraphNodeIDHashArray)
			     (PUTHASH (CAR NodeID)
					(NC.MakeBrowserNodeUID)
					GraphNodeIDHashArray)))
      else (OR (GETHASH NodeID GraphNodeIDHashArray)
		   (PUTHASH NodeID (NC.MakeBrowserNodeUID)
			      GraphNodeIDHashArray)))))
)
(* * This also new for NCDATABASE. Belongs with other similar fns like NC.UIDRemProp, etc.)

(DEFINEQ

(NC.UIDGetPropList
  (LAMBDA (UID)                                              (* rht: " 1-Feb-86 14:27")

          (* * Return the user data field of UID.)


    (fetch (UID UserData) of UID)))
)
(* * New functions for NCUTILITIES)

(DEFINEQ

(NC.CoerceToNoteFileStream
  (LAMBDA (CardOrNoteFileOrStream)                           (* rht: "23-Jan-86 17:40")

          (* * Get stream from whatever it is.)


    (COND
      ((STREAMP CardOrNoteFileOrStream))
      ((type? NoteFile CardOrNoteFileOrStream)
	(fetch (NoteFile Stream) of CardOrNoteFileOrStream))
      ((type? Card CardOrNoteFileOrStream)
	(fetch (NoteFile Stream) of (fetch (Card NoteFile) of CardOrNoteFileOrStream))))))
)
(* * Changes from NCDATABASE)

(DEFINEQ

(NC.GetMainCardData
  (LAMBDA (Card OverrideStream)                              (* rht: "28-Jan-86 15:05")

          (* Get a note card from the database. If IncludeDeletedCardsFlg is NIL, then return immediately if card is deleted 
	  or free. Otherwise, get dekleted but not free cards.)



          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * rht 11/10/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader and put in code to read Start and End pointers before calling
	  card type's getfn.)



          (* * kirk 27Nov85 abstracted this function out of NC.GetNoteCard)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET (Stream CardType Substance Region Length)
		       (if (EQ (fetch (Card Status) of Card)
				   (QUOTE ACTIVE))
			   then 

          (* * Only reposition the file if OverrideStream argument was NIL. Otherwise assume we're positioned within 
	  OverrideStream)


				  (if (STREAMP OverrideStream)
				      then (SETQ Stream OverrideStream)
				    else (SETQ Stream (NC.CoerceToNoteFileStream Card))
					   (SETFILEPTR Stream (fetch (Card MainLoc) of Card)))

          (* * Read the header info)


				  (NC.SetItemDate Card (NC.ReadCardPartHeader Card 
										NC.ItemIdentifier 
										  Stream
										  (STREAMP 
										   OverrideStream)))

          (* * read card type and region)


				  (SETQ CardType (NC.ReadCardType Stream))
				  (SETQ Region (NC.ReadRegion Stream)) 

          (* * Read the length of substance, then call the substance get fn)


				  (SETQ Length (NC.ReadPtr Stream 3))
				  (SETQ Substance (APPLY* (NC.GetSubstanceFn CardType)
							      Card Length Stream))

          (* * Setup ID with appropriate properties for retrieved card)


				  (NC.SetType Card CardType)
				  (NC.SetRegion Card Region)
				  (NC.SetSubstance Card Substance)
				  Card)))))

(NC.GetLinks
  (LAMBDA (Card OverrideStream)                              (* rht: "28-Jan-86 15:04")

          (* * rht 1/31/85: Now reads pointers from index array.)



          (* * rht 2/9/85: Now fixes display formats on links read in.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * fkr 11/8/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET (Stream)
		       (if (EQ (fetch (Card Status) of Card)
				   (QUOTE ACTIVE))
			   then 

          (* * Only reposition the file if OverrideStream argument was NIL. Otherwise assume we're positioned within 
	  OverrideStream)


				  (if (STREAMP OverrideStream)
				      then (SETQ Stream OverrideStream)
				    else (SETQ Stream (NC.CoerceToNoteFileStream Card))
					   (SETFILEPTR Stream (fetch (Card LinksLoc)
								   of Card)))

          (* * Read the header and set the date)


				  (NC.SetLinksDate Card (NC.ReadCardPartHeader Card 
									       NC.LinksIdentifier 
										   Stream
										   (STREAMP 
										   OverrideStream)))

          (* * Read the links)


				  (NC.SetToLinks Card (NC.ReadListOfLinks Stream))
				  (NC.SetFromLinks Card (NC.ReadListOfLinks Stream))
				  (NC.SetGlobalLinks Card (NC.ReadListOfLinks Stream))
				  (NC.SetLinksDirtyFlg Card NIL)
				  Card)))))

(NC.GetTitle
  (LAMBDA (Card OverrideStream)                              (* rht: "28-Jan-86 15:04")
                                                             (* Retrieve title for card specified by Card from the 
							     database specified by DatabaseStream)

          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * kirk 10/28/85 Now returns NIL if Status not ACTIVE)



          (* * fkr 10/29/85: Fixed to use new numeric ID format.)



          (* * rht 11/10/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET (Stream Title)
		       (if (EQ (fetch (Card Status) of Card)
				   (QUOTE ACTIVE))
			   then 

          (* * Only reposition the file if OverrideStream argument was NIL. Otherwise assume we're positioned within 
	  OverrideStream)


				  (if (STREAMP OverrideStream)
				      then (SETQ Stream OverrideStream)
				    else (SETQ Stream (NC.CoerceToNoteFileStream Card))
					   (SETFILEPTR Stream (fetch (Card TitleLoc)
								   of Card)))
				  (NC.SetTitleDate Card (NC.ReadCardPartHeader Card 
									      NC.TitlesIdentifier 
										   Stream
										   (STREAMP 
										   OverrideStream)))
				  (NC.SetTitle Card (SETQ Title (NC.ReadTitle Stream)))
				  Title)))))

(NC.GetPropList
  (LAMBDA (Card OverrideStream)                              (* rht: "28-Jan-86 15:04")
                                                             (* Retrieve the prop list for card specified by ID 
							     from the database specified by DatabaseStream)

          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * rht 11/10/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET (Stream Props)
		       (if (EQ (fetch (Card Status) of Card)
				   (QUOTE ACTIVE))
			   then 

          (* * set the fileptr to the beginning of the data, read the header, then read the prop list)



          (* * Only reposition the file if OverrideStream argument was NIL. Otherwise assume we're positioned within 
	  OverrideStream)


				  (if (STREAMP OverrideStream)
				      then (SETQ Stream OverrideStream)
				    else (SETQ Stream (NC.CoerceToNoteFileStream Card))
					   (SETFILEPTR Stream (fetch (Card PropListLoc)
								   of Card)))
				  (NC.SetPropListDate Card (NC.ReadCardPartHeader Card 
									       NC.PropsIdentifier 
										      Stream
										      (STREAMP
											
										   OverrideStream)))
				  (NC.SetPropList Card (SETQ Props (NC.ReadPropList Stream)))
				  Props)))))

(NC.GetType
  (LAMBDA (Card OverrideStream)                              (* rht: "28-Jan-86 15:05")
                                                             (* Retrieve the NoteCardType of card specified by 
							     NoteCardID from the database specified by 
							     DatabaseStream)

          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 7/9/85: Now gets date if notefile has newer data format.)



          (* * kirk 10/18/85; Now returns NIL if status not ACTIVE)



          (* * fkr 10/29/85: Fixed to use new numeric ID format. Also added NC.SetTitle call.)



          (* * rht 11/10/85 Updated to handle new Card scheme and NoteFile objects.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now passes extra arg to NC.ReadCardPartHeader indicating that when we're overriding the notefile 
	  stream, you shouldn't force UIDs on stream and in card to match.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET (Stream CardType)
		       (if (EQ (fetch (Card Status) of Card)
				   (QUOTE ACTIVE))
			   then 

          (* * Only reposition the file if OverrideStream argument was NIL. Otherwise assume we're positioned within 
	  OverrideStream)


				  (if (STREAMP OverrideStream)
				      then (SETQ Stream OverrideStream)
				    else (SETQ Stream (NC.CoerceToNoteFileStream Card))
					   (SETFILEPTR Stream (fetch (Card MainLoc) of Card)))
				  (NC.SetItemDate Card (NC.ReadCardPartHeader Card 
										NC.ItemIdentifier 
										  Stream
										  (STREAMP 
										   OverrideStream)))
				  (NC.SetType Card (SETQ CardType (NC.ReadCardType Stream)))
				  CardType)))))
)
(DEFINEQ

(NC.PutMainCardData
  (LAMBDA (Card UpdateUpdateListFlg UseOldDateFlg OverrideStream)
                                                             (* rht: "23-Jan-86 21:04")

          (* * Write note card specified by ID to the database specified by Database stream)



          (* * rht 7/9/85: Now puts out date after identifier. If UseOldDateFlg is non-nil, then use old date, otherwise use 
	  current date.)



          (* * rht 11/10/85: Updated to handle NoteFile and Card scheme.)



          (* * fgh 11/20/85 Added call to NC.WriteCardPartHeader and the mechanism to write the start and end pointers of the
	  substance before calling the card type's putfn.)



          (* * kirk 29Nov85 Renamed from NC.PutNoteCard)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET ((Stream (OR (STREAMP OverrideStream)
				      (NC.CoerceToNoteFileStream Card)))
			DataLoc CardType StartSubstanceLoc)

          (* * Record update date on update list if necessary.)


		       (AND UpdateUpdateListFlg (NC.UpdateUpdateList Card))

          (* * First write out the card part header)


		       (SETFILEPTR Stream (SETQ DataLoc (GETEOFPTR Stream)))
		       (NC.WriteCardPartHeader Card NC.ItemIdentifier (COND
						   (UseOldDateFlg (NC.FetchItemDate Card))
						   (T (NC.SetItemDate Card (DATE))))
						 Stream)

          (* * write out the type and region)


		       (NC.WriteCardType Stream (SETQ CardType (NC.RetrieveType Card)))
		       (NC.WriteRegion Card Stream)

          (* * Write out the dummy length pointer for the actual substance)


		       (SETQ StartSubstanceLoc (GETFILEPTR Stream))
		       (NC.WritePtr Stream 0 3)

          (* * Write out the substance of the card.)


		       (APPLY* (NC.PutSubstanceFn CardType)
				 Card Stream)

          (* * Update the length pointer at beginning of substance Subtract three so that length is the length of the actual 
	  substance and doesn't include the length pointer maintained here.)


		       (SETFILEPTR Stream StartSubstanceLoc)
		       (NC.WritePtr Stream (DIFFERENCE (DIFFERENCE (GETEOFPTR Stream)
								       StartSubstanceLoc)
							 3)
				    3)

          (* * Update the length field at the beginning of the card info)


		       (SETFILEPTR Stream DataLoc)
		       (NC.WritePtr Stream (DIFFERENCE (GETEOFPTR Stream)
							 DataLoc)
				    3)
		       (SETFILEPTR Stream -1)

          (* * Now update the Index to reflect the new data just written. Done last in case the substance putting bombed for 
	  some reason.)



          (* * Only update if no OverrideStream.)


		       (if (NOT (STREAMP OverrideStream))
			   then (replace (Card Status) of Card with (QUOTE ACTIVE))
				  (NC.SetMainLoc Card DataLoc))
		   Card))))

(NC.PutLinks
  (LAMBDA (Card UseOldDateFlg OverrideStream)                (* rht: "23-Jan-86 21:04")

          (* * Put the link data for ID onto the database file.)



          (* * rht 1/30/85: Changed to use index array instead of file.)



          (* * rht 7/9/85: Now puts out date after identifier. If UseOldDateFlg is non-nil, then use old date, otherwise use 
	  current date.)



          (* * rht 11/10/85: Updated to handle NoteFile and CardID scheme.)



          (* * fgh 11/20/85 Added call to NC.WriteCardPartHeader and the mechanism to write the start and end pointers of the
	  substance before calling the card type's putfn.)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET ((Stream (OR (STREAMP OverrideStream)
				      (NC.CoerceToNoteFileStream Card)))
			DataLoc)

          (* * Check to make sure this is an active note card.)


		       (AND (NEQ (fetch (Card Status) of Card)
				     (QUOTE ACTIVE))
			      (NC.ReportError "NC.PutLinks" (CONCAT (NC.FetchTitle Card)
									
								   " is not an active note card.")))

          (* * Write the links data at the end of the database file.)


		       (SETFILEPTR Stream (SETQ DataLoc (GETEOFPTR Stream)))
		       (NC.WriteCardPartHeader Card NC.LinksIdentifier (COND
						   (UseOldDateFlg (NC.FetchLinksDate Card))
						   (T (NC.SetLinksDate Card (DATE))))
						 Stream)
		       (NC.WriteListOfLinks Stream (NC.FetchToLinks Card))
		       (NC.WriteListOfLinks Stream (NC.FetchFromLinks Card))
		       (NC.WriteListOfLinks Stream (NC.FetchGlobalLinks Card))

          (* * Update the length field at the beginning of the card info)


		       (SETFILEPTR Stream DataLoc)
		       (NC.WritePtr Stream (DIFFERENCE (GETEOFPTR Stream)
							 DataLoc)
				    3)
		       (SETFILEPTR Stream -1)

          (* * Now update the index to point to the link data just written. Done last in case writing of links doesn't 
	  complete okay.)



          (* * Only update if no OverrideStream.)


		       (if (NOT (STREAMP OverrideStream))
			   then (NC.SetLinksLoc Card DataLoc)
				  (NC.SetLinksDirtyFlg Card))
		   Card))))

(NC.PutRegion
  (LAMBDA (Card)                                             (* rht: "23-Jan-86 21:04")

          (* * rht 1/31/85: Now reads pointers from index array rather than file.)



          (* * rht 11/12/85: Updated to handle new Notefile and cardID format.)



          (* * fgh 11/20/85 Added call to NC.ReadCardPartHeader)



          (* * rht 1/23/86: Changed to use NC.CoerceToNoteFileStream)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET ((Stream (NC.CoerceToNoteFileStream Card)))

          (* * Check to make sure this is an active note card.)


		       (AND (NEQ (fetch (Card Status) of Card)
				     (QUOTE ACTIVE))
			      (NC.ReportError "NC.PutRegion" (CONCAT (NC.FetchTitle Card)
									 
								   " is not an active note card.")))
		       (SETFILEPTR Stream (fetch (Card MainLoc) of Card))
		       (NC.ReadCardPartHeader Card NC.ItemIdentifier Stream)
		       (NC.ReadCardType Stream)
		       (NC.WriteRegion Card Stream)
		   Card))))

(NC.PutTitle
  (LAMBDA (Card UseOldDateFlg OverrideStream)                (* rht: "23-Jan-86 21:04")

          (* * Put the title of card ID onto DatabaseStream)



          (* * rht 7/9/85: Now puts out date after identifier. If UseOldDateFlg is non-nil, then use old date, otherwise use 
	  current date.)



          (* * rht 11/10/85: Updated to handle NoteFile and CardID scheme.)



          (* * fgh 11/20/85 Added call to NC.WriteCardPartHeader and the mechanism to write the start and end pointers of the
	  substance before calling the card type's putfn.)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET ((Stream (OR (STREAMP OverrideStream)
				      (NC.CoerceToNoteFileStream Card)))
			DataLoc)

          (* * Check to make sure this is an active note card.)


		       (AND (NEQ (fetch (Card Status) of Card)
				     (QUOTE ACTIVE))
			      (NC.ReportError "NC.PutTitle" (CONCAT (NC.FetchTitle Card)
									
								   " is not an active note card.")))

          (* * First write out the title.)


		       (SETFILEPTR Stream (SETQ DataLoc (GETEOFPTR Stream)))
		       (NC.WriteCardPartHeader Card NC.TitlesIdentifier (COND
						   (UseOldDateFlg (NC.FetchTitleDate Card))
						   (T (NC.SetTitleDate Card (DATE))))
						 Stream)
		       (NC.WriteTitle Stream (NC.FetchTitle Card))

          (* * Update the length field at the beginning of the card info)


		       (SETFILEPTR Stream DataLoc)
		       (NC.WritePtr Stream (DIFFERENCE (GETEOFPTR Stream)
							 DataLoc)
				    3)
		       (SETFILEPTR Stream -1)

          (* * Now update the Index to reflect the new data just written. Done last in case the substance putting bombed for 
	  some reason.)



          (* * Only update if no OverrideStream.)


		       (if (NOT (STREAMP OverrideStream))
			   then (NC.SetTitleLoc Card DataLoc)
				  (NC.SetTitleDirtyFlg Card))
		   Card))))

(NC.PutPropList
  (LAMBDA (Card UseOldDateFlg OverrideStream)                (* rht: "23-Jan-86 21:03")

          (* * Put the prop list for ID onto the database file.)



          (* * rht 1/30/85: Changed to use index array instead of file.)



          (* * rht 7/9/85: Now puts out date after identifier. If UseOldDateFlg is non-nil, then use old date, otherwise use 
	  current date.)



          (* * rht 11/10/85: Updated to handle NoteFile and Card scheme.)



          (* * fgh 11/20/85 Added call to NC.WriteCardPartHeader and the mechanism to write the start and end pointers of the
	  substance before calling the card type's putfn.)



          (* * rht 1/23/86: Now takes optional OverrideStream arg. This, if given, overrides stream of card's notefile.)


    (WITH.MONITOR (NC.FetchMonitor (fetch (Card NoteFile) of Card))
		  (LET ((Stream (OR (STREAMP OverrideStream)
				      (NC.CoerceToNoteFileStream Card)))
			DataLoc)

          (* * Check to make sure this is an active note card.)


		       (AND (NEQ (fetch (Card Status) of Card)
				     (QUOTE ACTIVE))
			      (NC.ReportError "NC.PutPropList" (CONCAT (NC.FetchTitle Card)
									   
								   " is not an active note card.")))

          (* * Write the proplist at the end of the database file.)


		       (SETFILEPTR Stream (SETQ DataLoc (GETEOFPTR Stream)))
		       (NC.WriteCardPartHeader Card NC.PropsIdentifier (COND
						   (UseOldDateFlg (NC.FetchPropListDate Card))
						   (T (NC.SetPropListDate Card (DATE))))
						 Stream)
		       (NC.WritePropList Stream (NC.FetchPropList Card))

          (* * Update the length field at the beginning of the card info)


		       (SETFILEPTR Stream DataLoc)
		       (NC.WritePtr Stream (DIFFERENCE (GETEOFPTR Stream)
							 DataLoc)
				    3)
		       (SETFILEPTR Stream -1)

          (* * Now update the index to point to the proplist just written. Done last in case writing of proplist doesn't 
	  complete okay.)



          (* * Only update if no OverrideStream.)


		       (if (NOT (STREAMP OverrideStream))
			   then (NC.SetPropListLoc Card DataLoc)
				  (NC.SetPropListDirtyFlg Card))
		   Card))))
)
(DEFINEQ

(NC.ReadCardPartHeader
  (LAMBDA (Card Identifier Stream Don'tCheckForIDMismatchFlg)
                                                             (* rht: "28-Jan-86 15:01")

          (* * Read the header for a card part and return the date from the header)



          (* * kirk 22Dec85 added NoteFile local)



          (* * rht 1/23/86: Now takes optional stream arg. This, if given, overrides stream of card's notefile.)



          (* * rht 1/28/86: Now takes Don'tCheckForIDMismatchFlg arg. If non-nil, then don't force UID on stream to match UID
	  of card.)


    (OR (STREAMP Stream)
	  (SETQ Stream (NC.CoerceToNoteFileStream Card)))
    (LET (VersionNumber Date ActualID CardUID)

          (* * Skip the length info)


         (NC.ReadPtr Stream 3)

          (* * Read the identifier and the version)


         (if (NOT (SETQ VersionNumber (NC.ReadIdentifier Stream Identifier)))
	     then (NC.ReportError "NC.ReadCardPartHeader" (CONCAT (NC.FetchTitle Card)
									
								  " Error while reading NoteFile"
									" -- incorrect identifier.")))
         (if (GEQ VersionNumber 1)
	     then (SETQ Date (NC.ReadDate Stream)))
         (SETQ ActualID (NC.ReadUID Stream))
         (if (AND (NOT Don'tCheckForIDMismatchFlg)
		      (NOT (NC.SameUIDP ActualID (SETQ CardUID (fetch (Card UID)
									of Card)))))
	     then (NC.ReportError "NC.ReadCardPartHeader" (CONCAT 
						 "ID mismatch while reading item.  Expected ID: "
									CardUID "   Found ID: " 
									ActualID)))
     Date)))

(NC.ReadIdentifier
  (LAMBDA (NoteFileOrStream Identifier)                      (* rht: "23-Jan-86 18:16")
                                                             (* Return T if next item on databaseStream is the 
							     identifier specified by Identifier)

          (* * rht 2/4/85: A horrible hack for the case of titles identifier. This is because a previous typo was causing 
	  NOBIND to get written for titles identifiers.)



          (* * rht 7/9/85: Now checks for new data format. This is indicated by identifiers with the last two #'s clipped 
	  off. Then comes the one-byte version number of the data format. If identifier is not clipped then it's old style 
	  and there is no version number. Return version number if there is one, 0 if old style, and NIL if can't match 
	  identifier.)



          (* * fkr 11/8/85 Changed to handle NoteFile object.)



          (* * rht 11/24/85: No longer worries about the screwy NOBIND Titles identifier. Also assumes Identifier is already 
	  clipped.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (if (AND (EQ (READ Stream NC.OrigReadTable)
			    Identifier)
		      (NUMBERP (PROGN                    (* First char is separator.
							     Next is one-byte version number.)
					  (READC Stream)
					  (NC.ReadPtr Stream 1))))
	   else NIL))))

(NC.ReadRegion
  (LAMBDA (NoteFileOrStream)                                 (* rht: "23-Jan-86 18:16")

          (* * fkr 11/885: Now takes NoteFile arg. No more ID arg.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (CREATEREGION (NC.ReadPtr Stream 2)
			 (NC.ReadPtr Stream 2)
			 (NC.ReadPtr Stream 2)
			 (NC.ReadPtr Stream 2)))))

(NC.ReadListOfLinks
  (LAMBDA (NoteFileOrStream)                                 (* rht: "23-Jan-86 18:15")

          (* * Read a list of link records from the notefile. Create a datatype instance for each.)



          (* * rht 11/14/85: Now uses NC.CardFromUID to get Card object from hash array.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (PROG1 (bind Link while (SETQ Link (NC.ReadLink Stream)) collect Link)

          (* * Read past the end of list identifier)


		  (READ Stream)
		  (BIN Stream)))))

(NC.ReadUID
  (LAMBDA (NoteFileOrStream)                                 (* rht: "23-Jan-86 18:15")

          (* * Get a UID off of the file. Since UIDs are BIGNUMs less than {EXPT 2 112} just read their 112 bits from the 
	  file.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (PROG1 (create UID
			    UID0 ←(BIN16 Stream)
			    UID1 ←(BIN16 Stream)
			    UID2 ←(BIN16 Stream)
			    UID3 ←(BIN16 Stream)
			    UID4 ←(BIN16 Stream)
			    UID5 ←(BIN16 Stream)
			    UID6 ←(BIN16 Stream))

          (* * skip past CR following UID)


		  (BIN Stream)))))

(NC.ReadDate
  (LAMBDA (NoteFileOrStream)                                 (* rht: "23-Jan-86 18:15")

          (* * Read a date string from Stream. All dates have the same length, so can use that as a check.
	  I'm allowing null date since we may be compacting an old style (non-dated) notefile. Thus we won't give it a 
	  misleadingly new date.)



          (* * rht 11/11/85: Now handles new notefile object.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream))
	  Date)

          (* * Read Date)


         (SETQ Date (READ Stream))

          (* * Read past CR)


         (BIN Stream)
         (COND
	   ((OR (NULL Date)
		  (EQ (NCHARS Date)
			NC.DateStringLength))
	     Date)
	   (T (NC.ReportError "NC.GetDate" (CONCAT Date " is not a proper date."))
	      NIL)))))

(NC.ReadCardType
  (LAMBDA (NoteFileOrStream)                                 (* rht: "23-Jan-86 18:14")

          (* * Get a card type off of the file.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (PROG1 (READ Stream)

          (* * read past CR)


		  (BIN Stream)))))

(NC.ReadTitle
  (LAMBDA (NoteFileOrStream)                                 (* rht: "23-Jan-86 18:13")

          (* * Get a title off of the file.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (READ (NC.CoerceToNoteFileStream NoteFileOrStream))))

(NC.ReadPropList
  (LAMBDA (NoteFileOrStream)                                 (* rht: " 6-Feb-86 21:51")

          (* * Get a prop list off of the file.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (READ (NC.CoerceToNoteFileStream NoteFileOrStream))))
)
(DEFINEQ

(NC.WriteCardPartHeader
  (LAMBDA (Card Identifier Date Stream)                      (* rht: "23-Jan-86 17:50")

          (* * write the header of a card part onto the NoteFile)



          (* * rht 1/23/86: Now takes optional stream arg. This, if given, overrides stream of card's notefile.)


    (OR (STREAMP Stream)
	  (SETQ Stream (NC.CoerceToNoteFileStream Card)))

          (* * leave space for the length information)


    (NC.WritePtr Stream 0 3)

          (* * write the card part identifier)


    (NC.WriteIdentifier Stream Identifier)

          (* * write the date)


    (NC.WriteDate Stream Date)

          (* * write the cards uid)


    (NC.WriteUID Stream (fetch (Card UID) of Card))))

(NC.WriteIdentifier
  (LAMBDA (NoteFileOrStream Identifier)                      (* rht: "23-Jan-86 17:45")
                                                             (* Put Identifier on DatabaseStream)

          (* * Now puts out new data format style. This consists of the identifier with the last two #'s clipped off followed
	  by the data format version byte.)



          (* * rht 11/12/85: Now handles new notefile format.)



          (* * rht 11/24/85: Assumes identifier is already clipped.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (PRINT Identifier Stream NC.OrigReadTable)
         (NC.WritePtr Stream NC.DataFormatVersionNumber 1))))

(NC.WriteRegion
  (LAMBDA (Card Stream)                                      (* rht: "27-Jan-86 19:12")

          (* * rht 10/3/85: Now checks first for a saved region (probably there because card got moved off screen).)



          (* * fkr 11/8/85: Changed to handle CardIDs and NoteFile objects.)



          (* * rht 1/23/86: Now takes optional stream arg. This, if given, overrides stream of card's notefile.)


    (OR (STREAMP Stream)
	  (SETQ Stream (NC.CoerceToNoteFileStream Card)))
    (LET (Window Region)
         (SETQ Window (NC.FetchWindow Card))
         (SETQ Region (OR (NC.FetchSavedRegion Card)
			      (AND Window (WINDOWPROP Window (QUOTE REGION)))
			      (NC.FetchRegion Card)
			      (NC.MakeDummyRegion Card)))
         (AND (NC.ActiveCardP Card)
		(NC.SetRegion Card Region))
         (NC.WritePtr Stream (fetch LEFT of Region)
		      2)
         (NC.WritePtr Stream (fetch BOTTOM of Region)
		      2)
         (NC.WritePtr Stream (fetch WIDTH of Region)
		      2)
         (NC.WritePtr Stream (fetch HEIGHT of Region)
		      2))))

(NC.WriteListOfLinks
  (LAMBDA (NoteFileOrStream Links)                           (* rht: "23-Jan-86 17:45")

          (* * Write the given links down to the notefile, coercing NoteFile object to NF-UID if necessary.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (for Link in Links when (type? Link Link) do (NC.WriteLink Link Stream))
         (NC.WritePtr Stream 0 1)
         (PRINT (QUOTE EndLinks)
		  Stream))))

(NC.WriteUID
  (LAMBDA (NoteFileOrStream UID)                             (* rht: "23-Jan-86 17:44")

          (* * Write a UID out to Stream. Since UIDs are BIGNUMs less than {EXPT 2 112} just write their 112 bits to the 
	  file.)



          (* * rht 11/12/85: Handles new notefile format.)


    (LET ((Stream (NC.CoerceToNoteFileStream NoteFileOrStream)))
         (AND (type? UID UID)
		(BOUT16 Stream (ffetch (UID UID0) of UID))
		(BOUT16 Stream (ffetch (UID UID1) of UID))
		(BOUT16 Stream (ffetch (UID UID2) of UID))
		(BOUT16 Stream (ffetch (UID UID3) of UID))
		(BOUT16 Stream (ffetch (UID UID4) of UID))
		(BOUT16 Stream (ffetch (UID UID5) of UID))
		(BOUT16 Stream (ffetch (UID UID6) of UID)))

          (* * End with a CR)


         (BOUT Stream 13))))

(NC.WriteDate
  (LAMBDA (NoteFileOrStream Date)                            (* rht: "23-Jan-86 17:43")

          (* * Write a date string out to Stream.)



          (* * rht 11/12/85: Handles new notefile format.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (PRINT Date (NC.CoerceToNoteFileStream NoteFileOrStream))))

(NC.WriteCardType
  (LAMBDA (NoteFileOrStream CardType)                        (* rht: "23-Jan-86 17:43")

          (* * Writes a card type down to notefile.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (PRINT CardType (NC.CoerceToNoteFileStream NoteFileOrStream))))

(NC.WriteTitle
  (LAMBDA (NoteFileOrStream Title)                           (* rht: "23-Jan-86 17:43")

          (* * Write a title out to Stream.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (PRINT Title (NC.CoerceToNoteFileStream NoteFileOrStream))))

(NC.WritePropList
  (LAMBDA (NoteFileOrStream PropList)                        (* rht: "23-Jan-86 17:50")

          (* * Write a prop list out to Stream.)



          (* * rht 1/23/86: Now takes notefile or stream as arg.)


    (PRINT PropList (NC.CoerceToNoteFileStream NoteFileOrStream))))
)
(* * Changes for NCTEXTCARD)

(DEFINEQ

(NC.GetTextSubstance
  (LAMBDA (Card Length Stream)                               (* rht: "23-Jan-86 21:21")
                                                             (* Get a text stream from the database file)

          (* * fgh 11/13/85 Updated to handle Card objects.)



          (* * fgh 11/20/85 NoteCards now passes down start and end pointer as args.)



          (* * fgh 11/21/85 Now passed Length instead of start and end ptrs.)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)


    (LET ((TempStream (OPENSTREAM (QUOTE {NODIRCORE})
				    (QUOTE BOTH)
				    (QUOTE NEW)))
	  TextStream StartPtr)

          (* * Copy text stream to a NODIRCORE file from the current location. Number of bytes copied should be Length minus 
	  the 4 bytes already read for OriginalLocation)


         (COPYBYTES Stream TempStream (SETQ StartPtr (GETFILEPTR Stream))
		      (PLUS StartPtr Length))

          (* * return an open textstream on the temp file)


         (SETQ TextStream (OPENTEXTSTREAM TempStream NIL NIL NIL (NC.MakeTEditPropsList)))
         (STREAMPROP TextStream (QUOTE NoteCardObject)
		       Card)
     TextStream)))

(NC.PutTextSubstance
  (LAMBDA (Card Stream)                                      (* rht: "23-Jan-86 21:21")
                                                             (* Put text substance from card ID on the database 
							     file)

          (* * rht 9/13/85: Now doesn't try to write piece table at all if substance has zero length.)



          (* * fgh 11/13/85 Updated to handle NoteFile, Card objects.)



          (* * fgh 11/20/85 removed code to handle start and end pointers)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)


    (LET ((Substance (NC.FetchSubstance Card))
	  (StartPtr (GETFILEPTR Stream)))

          (* * The write down the text stream)


         (COND
	   ((NOT (ZEROP (fetch (TEXTOBJ TEXTLEN) of (TEXTOBJ Substance))))
	     (TEDIT.PUT.PCTB (TEXTOBJ Substance)
			       Stream)))

          (* * fix up the file absolute pointerts to be file textstream relative pointers.)


         (if (TEDIT.FORMATTEDFILEP Substance)
	     then (SETFILEPTR Stream (IDIFFERENCE (SETQ EOFPtr (GETEOFPTR Stream))
							8))
		    (SETQ StartFormatPtr (\DWIN Stream))
		    (SETFILEPTR Stream (IDIFFERENCE EOFPtr 8))
		    (\DWOUT Stream (DIFFERENCE StartFormatPtr StartPtr)))

          (* * Set stream file ptr to eof.)


         (SETFILEPTR Stream -1))))
)
(* * Changes for NCGRAPHCARD)

(DEFINEQ

(NC.GetGraphSubstance
  (LAMBDA (Card Length Stream)                               (* rht: "23-Jan-86 21:17")

          (* * fgh 11/14/85 Updated to handle Card object.)



          (* * fgh 11/20/85 NoteCards now passes start and end ptrs down.)



          (* * fgh 11/21/85 Now passes length instead of start and end ptrs.)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)



          (* * Read the Graph)


    (HREAD Stream)))

(NC.PutGraphSubstance
  (LAMBDA (Card Stream)                                      (* rht: "23-Jan-86 21:20")
                                                             (* Put Graph in card ID onto DatabaseStream)

          (* * fgh 11/14/85 Updated to handle Card object.)



          (* * fgh 11/20/85 NoteCards now takes care of setting the start and end pointers for the substance.)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)


    (LET ((Graph (NC.FetchSubstance Card)))                (* Clean up BITMAPS in Graph data structure)
         (for GraphNode in (fetch GRAPHNODES of Graph) do (replace (GRAPHNODE 
										  NODELABELBITMAP)
								       of GraphNode with NIL))
                                                             (* Write data stucture)
         (HPRINT Graph Stream))))
)
(* * Changes for NCSKETCHCARD)

(DEFINEQ

(NC.GetSketchSubstance
  (LAMBDA (Card Length Stream)                               (* rht: "23-Jan-86 21:18")

          (* Get sketch substance from Database stream. Database stream is positioned. READ the global sketch description, 
	  the locasl sketch scale and region viewed. Also read in any cached bit maps for the MAPS system.)



          (* * fgh 11/14/85 Updated to handle Card and NoteFile objects.)



          (* * fgh 11/20/85 NoteCards now passes start and enptrs down.)



          (* * fgh 11/21/85 Now passed Length instead of start and end ptrs.)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)


    (LET (Sketch Scale RegionViewed)

          (* * Get the substance)


         (SETQ Sketch (HREAD Stream))
         (SETQ Scale (READ Stream))
         (SETQ RegionViewed (READ Stream))
         (while (EQ (READ Stream)
			(QUOTE ###CACHEDMAP###))
	    do (NC.GetCachedMap Stream))
         (LIST Sketch Scale RegionViewed))))

(NC.PutSketchSubstance
  (LAMBDA (Card Stream)                                      (* rht: "23-Jan-86 21:19")

          (* Put the sketch substance for card ID to the database. Store the global sketch descriptor, the scale and region 
	  viewed for ID and any cached bit maps.)



          (* * fgh 11/14/85 Updated to handle Card object.)



          (* * fgh 11/20/85 NoteCards now takes care of setting the start and end pointers for the substance.)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)


    (LET ((Substance (NC.FetchSubstance Card))
	  (Window (NC.FetchWindow Card))
	  SketchSpecs)
         (HPRINT Substance Stream NIL T)
         (PRINT (OR (AND Window (SCALE.FROM.SKW Window))
			(NC.FetchScale Card))
		  Stream)
         (PRINT (OR (AND Window (SK.REGION.VIEWED Window))
			(NC.FetchRegionViewed Card))
		  Stream)
         (COND
	   ((AND Window (SETQ SketchSpecs (LOCALSPECS.FROM.VIEWER Window)))
	     (MAPSKETCHSPECS SketchSpecs (FUNCTION NC.PutCachedMap)
			       Stream)))
         (PRINT (QUOTE ###ENDSKETCH###)
		  Stream))))
)
(* * Changes for NCLISTCARD)

(DEFINEQ

(NC.ListCardGetFn
  (LAMBDA (Card Length Stream)                               (* rht: "23-Jan-86 21:28")

          (* * Get the list substance from the disk)



          (* * fgh 11/20/85 NoteCards now passes start and end ptrs down.)



          (* * fgh 11/21/85 Now passes length instead of start and end ptrs.)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)


    (READ Stream)))

(NC.ListCardPutFn
  (LAMBDA (Card Stream)                                      (* rht: "23-Jan-86 21:28")
                                                             (* Put list substance)

          (* * fgh 11/20/85 NoteCards now takes care of setting the start and end pointers for the substance.)



          (* * rht 1/23/86: Now takes Stream as arg instead of computing from Card.)


    (PRINT (NC.FetchSubstance Card)
	     Stream)))
)
(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS 

(ADDTOVAR NLAMA )

(ADDTOVAR NLAML )

(ADDTOVAR LAMA )
)
(PUTPROPS RHTPATCH024 COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2767 12732 (NC.CopyCards 2777 . 10548) (NC.PutNoteCardToStream 10550 . 11600) (
NC.GetNoteCardFromStream 11602 . 12485) (NC.MakeHashKeyFromCard 12487 . 12730)) (12733 20573 (
NC.FixUpLinksInCardCopy 12743 . 17379) (NC.FixUpBrowserCardCopy 17381 . 19996) (
NC.BrowserCopyConvertGraphNodeID 19998 . 20571)) (20672 20900 (NC.UIDGetPropList 20682 . 20898)) (
20943 21451 (NC.CoerceToNoteFileStream 20953 . 21449)) (21488 32055 (NC.GetMainCardData 21498 . 24090)
 (NC.GetLinks 24092 . 26061) (NC.GetTitle 26063 . 28041) (NC.GetPropList 28043 . 30022) (NC.GetType 
30024 . 32053)) (32056 43390 (NC.PutMainCardData 32066 . 35200) (NC.PutLinks 35202 . 37688) (
NC.PutRegion 37690 . 38797) (NC.PutTitle 38799 . 41027) (NC.PutPropList 41029 . 43388)) (43391 50355 (
NC.ReadCardPartHeader 43401 . 45075) (NC.ReadIdentifier 45077 . 46594) (NC.ReadRegion 46596 . 47054) (
NC.ReadListOfLinks 47056 . 47728) (NC.ReadUID 47730 . 48386) (NC.ReadDate 48388 . 49331) (
NC.ReadCardType 49333 . 49742) (NC.ReadTitle 49744 . 50044) (NC.ReadPropList 50046 . 50353)) (50356 
55938 (NC.WriteCardPartHeader 50366 . 51144) (NC.WriteIdentifier 51146 . 51943) (NC.WriteRegion 51945
 . 53134) (NC.WriteListOfLinks 53136 . 53706) (NC.WriteUID 53708 . 54602) (NC.WriteDate 54604 . 54982)
 (NC.WriteCardType 54984 . 55306) (NC.WriteTitle 55308 . 55616) (NC.WritePropList 55618 . 55936)) (
55974 58732 (NC.GetTextSubstance 55984 . 57260) (NC.PutTextSubstance 57262 . 58730)) (58769 60211 (
NC.GetGraphSubstance 58779 . 59285) (NC.PutGraphSubstance 59287 . 60209)) (60249 62556 (
NC.GetSketchSubstance 60259 . 61339) (NC.PutSketchSubstance 61341 . 62554)) (62592 63533 (
NC.ListCardGetFn 62602 . 63058) (NC.ListCardPutFn 63060 . 63531)))))
STOP