<<>> <> <> <> <> <> <<>> <> <<>> DIRECTORY IO, IOTioga, MailBasics, MailBasicsItemTypes, MailBasicsMoreItemTypes, MailMessage, MailRetrieve, MailUtils, NodeProps, Rope, TextEdit, Tioga, TiogaAccess, TiogaIO, UserProfile USING [Boolean]; MailRetrieveOneImpl: CEDAR MONITOR IMPORTS IO, IOTioga, MailRetrieve, MailUtils, NodeProps, Rope, TextEdit, TiogaAccess, TiogaIO, UserProfile EXPORTS MailMessage ~ BEGIN STREAM: TYPE ~ IO.STREAM; ROPE: TYPE ~ Rope.ROPE; <> ReadOneMessageX: PUBLIC PROC [handle: MailRetrieve.Handle, timeStamp: MailBasics.Timestamp, sender: ROPE, stream: IO.STREAM ¬ NIL] RETURNS [m, formatting: ROPE ¬ NIL, bodyLength, formatLen, formatPos: INT ¬ 0] ~ { [m, formatting, bodyLength, formatLen, formatPos] ¬ DoReadOne[FALSE, handle, timeStamp, sender, stream] }; ReadOneMessage: PUBLIC PROC [handle: MailRetrieve.Handle, timeStamp: MailBasics.Timestamp, sender: ROPE, stream: IO.STREAM ¬ NIL] RETURNS [m, formatting: ROPE ¬ NIL, bodyLength, formatLen, formatPos: INT ¬ 0] ~ { [m, formatting, bodyLength, formatLen, formatPos] ¬ DoReadOne[TRUE, handle, timeStamp, sender, stream] }; DoReadOne: PROC [deleteLeadingCR: BOOL, handle: MailRetrieve.Handle, timeStamp: MailBasics.Timestamp, sender: ROPE, stream: IO.STREAM ¬ NIL] RETURNS [m, formatting: ROPE ¬ NIL, bodyLength, formatLen, formatPos: INT ¬ 0] ~ { ENABLE MailRetrieve.Failed => { GOTO failed }; header, plainText, formattedHeader, bodies: ROPE ¬ NIL; sysMessage, attachments, unknowns: ROPE ¬ NIL; buttonRope: ROPE ¬ NIL; buttonType: MailBasics.ItemType; MakeButton: PROC[type: MailBasics.ItemType] ~ { IF UserProfile.Boolean["MailUser.MakeButtonForSerializedFile", FALSE] THEN { buttonRope _ MailRetrieve.GetItemAsRope[handle]; buttonType _ type } ELSE bodies _ bodies.Concat[MailRetrieve.GetItemAsRope[handle] ]; }; DO item: MailBasics.ItemHeader ~ MailRetrieve.NextItem[handle]; SELECT item.type FROM MailBasicsItemTypes.envelope => { NULL; }; MailBasicsItemTypes.header => header ¬ MailRetrieve.GetItemAsRope[handle]; MailBasicsItemTypes.plainTextForFormatting => plainText ¬ MailRetrieve.GetItemAsRope[handle]; MailBasicsItemTypes.formattedHeader => formattedHeader ¬ MailRetrieve.GetItemAsRope[handle]; MailBasicsItemTypes.systemMessage => sysMessage ¬ sysMessage.Concat[MailRetrieve.GetItemAsRope[handle] ]; MailBasicsItemTypes.ia5Note, MailBasicsItemTypes.text, MailBasicsItemTypes.multinationalNote => bodies ¬ bodies.Concat[MailRetrieve.GetItemAsRope[handle] ]; MailBasicsMoreItemTypes.hasAttachment => MakeButton[item.type]; MailBasicsItemTypes.fullFormatting => formatting ¬ formatting.Concat[MailRetrieve.GetItemAsRope[handle] ]; MailBasicsItemTypes.tioga1 => formatting ¬ formatting.Concat[MailRetrieve.GetItemAsRope[handle] ]; <<>> MailBasicsItemTypes.gGW => { NULL }; < { NULL };>> < { NULL };>> < { NULL };>> < { NULL };>> < { NULL }; -- we may use this someday>> < { NULL };>> MailBasicsItemTypes.lastItem => { EXIT }; ENDCASE => unknowns ¬ unknowns.Concat[IO.PutFR["\r\r==>Discarded ItemType: %g (length %g bytes)<==\r", [rope[MailUtils.RopeFromItemType[item.type]]], [integer[item.length]] ] ]; ENDLOOP; <> { next: ROPE; <> IF formatting # NIL THEN unknowns ¬ NIL; SELECT TRUE FROM attachments # NIL => { next ¬ attachments; attachments ¬ NIL }; unknowns # NIL => { next ¬ unknowns; unknowns ¬ NIL }; ENDCASE => { next ¬ bodies; bodies ¬ NIL }; SELECT TRUE FROM sysMessage # NIL => { foo: ROPE ¬ IO.PutFR["Date: %g\rSender: %g\r", [time[MailUtils.GetTimeFromPostmark[timeStamp]]], [rope[sender]] ]; pos: INT ¬ sysMessage.Find["Report-Type: DL name:"]; dlOK: BOOL ¬ FALSE; IF pos # -1 THEN { pos2: INT ¬ sysMessage.Find[" (", pos]; IF pos2 # -1 THEN { foo ¬ foo.Cat["Subject: Report for dl: ", sysMessage.Substr[pos, pos2-pos+1], "\r"]; dlOK ¬ TRUE; }; }; IF NOT dlOK THEN foo ¬ foo.Concat["Subject: Delivery / Non-Delivery Report information\r"]; foo ¬ foo.Cat[sysMessage, "\r"]; IF stream # NIL THEN stream.PutRope[foo] ELSE m ¬ foo.Cat[sysMessage, "\r"]; bodyLength ¬ foo.Length[]; IF header # NIL THEN header ¬ IO.PutFR1["---------- Original-Header:\r%g\r----------\r", [rope[header]] ]; bodies ¬ header.Concat[bodies]; formatting ¬ NIL; -- won't be correct so toss }; plainText # NIL => { -- don't want headers in this case ch: CHAR ~ plainText.Fetch[0]; IF deleteLeadingCR THEN IF ( ch = '\r ) OR ( ch = '\l ) THEN plainText ¬ plainText.Substr[1]; -- tioga stuff IF stream # NIL THEN stream.PutRope[plainText] ELSE m ¬ plainText; bodyLength ¬ plainText.Length[]; next ¬ NIL; -- kill multinationalnote part of message }; ENDCASE => { hL: INT = header.Length[]; numCRs: INT ¬ 0; IF header # NIL THEN { IF header.Fetch[hL-2] = '\r THEN numCRs ¬ numCRs + 1; IF header.Fetch[hL-1] = '\r THEN numCRs ¬ numCRs + 1; IF ( next # NIL ) AND ( next.Fetch[0] = '\r ) THEN numCRs ¬ numCRs + 1; IF numCRs < 2 THEN header ¬ header.Concat["\r"]; IF stream # NIL THEN stream.PutRope[header] ELSE m ¬ header; bodyLength ¬ header.Length[]; }; }; IF stream # NIL THEN stream.PutRope[next] ELSE m ¬ m.Concat[next]; bodyLength ¬ bodyLength + next.Length[]; IF attachments # NIL THEN { IF stream # NIL THEN stream.PutRope[attachments] ELSE m ¬ m.Concat[attachments]; bodyLength ¬ bodyLength + attachments.Length[]; }; IF unknowns # NIL THEN { IF stream # NIL THEN stream.PutRope[unknowns] ELSE m ¬ m.Concat[unknowns]; bodyLength ¬ bodyLength + unknowns.Length[]; }; IF bodies # NIL THEN { IF stream # NIL THEN stream.PutRope[bodies] ELSE m ¬ m.Concat[bodies]; bodyLength ¬ bodyLength + bodies.Length[]; }; }; IF buttonRope # NIL THEN { props: IOTioga.PropList; out: STREAM; reader: TiogaAccess.Reader; root: Tioga.Node; posSlash, posAfter: INT; fullRope: ROPE; cr: ROPE ~ "\r"; pair: TiogaIO.Pair; IF formatting # NIL THEN ERROR MailRetrieve.Failed[$malformedMsg, "a message has both a buttonRope and formatting"]; out _ IOTioga.CreateTiogaAccessStream[]; out.PutRope[m]; posSlash _ Rope.Find[buttonRope, "/"]; posAfter _ Rope.Find[buttonRope, "(", posSlash]; out.PutRope[buttonRope.Substr[0, posSlash]]; props _ IOTioga.PropPut[NIL, $Postfix, thePostfixValue]; props _ IOTioga.PropPut[props, $ButtonData, theButtonDataValue]; IOTioga.SetCharProps[out, props]; out.PutRope[Rope.Substr[buttonRope, posSlash, posAfter-posSlash-1]]; IOTioga.SetCharProps[out, NIL]; out.PutRope[Rope.Substr[buttonRope, posAfter-1]]; root _ TiogaAccess.WriteNode[IOTioga.WriterFromStream[out]]; TextEdit.PutProp[node: root, name: $NewlineDelimiter, value: cr]; pair ¬ TiogaIO.ToPair[root]; m ¬ pair.contents; formatting ¬ pair.formatting; }; IF stream # NIL THEN { stream.PutRope[m]; bodyLength ¬ bodyLength + m.Length[]; }; IF ( formatting # NIL ) AND ( stream # NIL ) THEN { formatPos ¬ stream.GetIndex[]; stream.PutRope[formatting]; formatLen ¬ formatting.Length[] }; IF stream # NIL THEN stream.PutChar['\r]; RETURN; EXITS failed => RETURN[NIL, NIL, -1, -1, -1]; }; theButtonDataRope: ROPE ~ "Poppy1 Class: PopUpButton MessageHandler: CommandTool Menu: ( ( \" \" > > \"Display ViewPoint Document\" \"Execute CVV.command\") ( > \"Deserialize\" \"Deserialize file\") ( \"\\\"\">> \"Stuff filename\" \"Stuff filename at the current insertion point\") () () () ( > \"Delete\" \"Delete file\") ) Feedback: ( (MouseMoved ) )"; theButtonDataValue: REF ~ NodeProps.DoSpecs[$ButtonData, theButtonDataRope]; thePostfixRope: ROPE ~ "1.0 outlineBoxBearoff 1.0 outlineBoxThickness"; thePostfixValue: REF ~ NodeProps.DoSpecs[$Postfix, thePostfixRope]; END.