<<>> <> <> <> <> <<>> DIRECTORY Basics USING [Card16FromH, HFromCard16, HWORD, LongNumber, Word16], CHNameP2V0 USING [Name], CHOpsP2V3 USING [ItemObject], CrRPC USING [MarshalledRopeHWords], RefText USING [AppendChar, ObtainScratch, ReleaseScratch], Rope USING [FromRefText, Fetch, Length, ROPE], XNS USING [Address], XNSCHItemOps USING [ErrorType], XNSCH USING [Item, Name]; <> XNSCHItemOpsImpl: CEDAR PROGRAM IMPORTS Basics, CrRPC, RefText, Rope EXPORTS XNSCHItemOps = { ROPE: TYPE = Rope.ROPE; Name: TYPE = XNSCH.Name; Address: TYPE = XNS.Address; Item: TYPE = XNSCH.Item; RopeList: TYPE = LIST OF ROPE; NameList: TYPE = LIST OF Name; AddressList: TYPE = LIST OF Address; Error: PUBLIC ERROR [reason: XNSCHItemOps.ErrorType] = CODE; <> <<>> BoolFromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [bool: BOOL, nextPos: CARDINAL] = { IF item = NIL OR index >= item.length THEN Error[itemLength]; RETURN[item[index] # 0, index+1]; }; Int16FromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [int: INT16, nextPos: CARDINAL] = { IF item = NIL OR index >= item.length THEN Error[itemLength]; RETURN[item[index], index+1]; }; Int32FromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [int: INT32, nextPos: CARDINAL] = { n: Basics.LongNumber; IF item = NIL OR index+1 >= item.length THEN Error[itemLength]; n.hi ¬ item[index]; n.lo ¬ item[index+1]; RETURN[n.li, index+2]; }; Card16FromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [card: CARD16, nextPos: CARDINAL] = { IF item = NIL OR index >= item.length THEN Error[itemLength]; RETURN[LOOPHOLE[item[index]], index+1]; }; Card32FromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [card: CARD32, nextPos: CARDINAL] = { n: Basics.LongNumber; IF item = NIL OR index+1 >= item.length THEN Error[itemLength]; n.hi ¬ item[index]; n.lo ¬ item[index+1]; RETURN[n.lc, index+2]; }; RopeFromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [rope: ROPE, nextPos: CARDINAL] = { buf: Basics.Word16; text: REF TEXT; cnt: CARDINAL; IF item = NIL OR index >= item.length THEN Error[itemLength]; cnt ¬ item.body[index]; IF (CARD[item.length-index-1]*BYTES[Basics.HWORD]) < cnt THEN Error[itemLength]; text ¬ RefText.ObtainScratch[cnt]; nextPos ¬ index+1; DO IF cnt = 0 THEN EXIT; buf.card ¬ item.body[nextPos]; nextPos ¬ nextPos+1; text ¬ RefText.AppendChar[text, LOOPHOLE[buf.hi]]; cnt ¬ cnt-1; IF cnt = 0 THEN EXIT; text ¬ RefText.AppendChar[text, LOOPHOLE[buf.lo]]; cnt ¬ cnt-1; ENDLOOP; rope ¬ Rope.FromRefText[text]; RefText.ReleaseScratch[text]; }; NameFromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [name: Name, nextPos: CARDINAL] = { [name.organization, nextPos] ¬ RopeFromItem[item, index]; [name.domain, nextPos] ¬ RopeFromItem[item, nextPos]; [name.object, nextPos] ¬ RopeFromItem[item, nextPos]; }; adrHWords: CARDINAL = BITS[XNS.Address]/BITS[Basics.HWORD]; AddressFromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [address: XNS.Address, nextPos: CARDINAL] = { buf: PACKED ARRAY [0..adrHWords) OF Basics.HWORD; IF item = NIL OR item.length < adrHWords+index THEN Error[itemLength]; FOR i: CARDINAL IN [0..adrHWords) DO buf[i] ¬ Basics.HFromCard16[item.body[index+i]]; ENDLOOP; RETURN[LOOPHOLE[buf], index+adrHWords]; }; <> <<>> RopeListFromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [ropes: RopeList, nextPos: CARDINAL] = { count: INTEGER; thisRope: ROPE; lastRope: RopeList; [count, nextPos] ¬ Int16FromItem[item, index]; THROUGH [0..count) DO [thisRope, nextPos] ¬ RopeFromItem[item, nextPos]; IF ropes = NIL THEN lastRope ¬ ropes ¬ LIST[thisRope] ELSE lastRope ¬ lastRope.rest ¬ LIST[thisRope]; ENDLOOP; }; NameListFromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [names: NameList, nextPos: CARDINAL] = { count: INTEGER; thisName: Name; lastName: NameList; [count, nextPos] ¬ Int16FromItem[item, index]; THROUGH [0..count) DO [thisName, nextPos] ¬ NameFromItem[item, nextPos]; IF names = NIL THEN lastName ¬ names ¬ LIST[thisName] ELSE lastName ¬ lastName.rest ¬ LIST[thisName]; ENDLOOP; }; AddressListFromItem: PUBLIC PROC [item: Item, index: CARDINAL ¬ 0] RETURNS [addresses: AddressList, nextPos: CARDINAL] = { count: INTEGER; thisAddress: Address; lastAddress: AddressList; [count, nextPos] ¬ Int16FromItem[item, index]; THROUGH [0..count) DO [thisAddress, nextPos] ¬ AddressFromItem[item, nextPos]; IF addresses = NIL THEN lastAddress ¬ addresses ¬ LIST[thisAddress] ELSE lastAddress ¬ lastAddress.rest ¬ LIST[thisAddress]; ENDLOOP; }; <<>> <<"Simple" Marshaling PROCs:>> CreateNewItem: PUBLIC PROC [size: CARDINAL, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item] = { oldLength: CARDINAL ¬ IF item = NIL THEN 0 ELSE item.length; newLength: CARDINAL ¬ MAX[oldLength, index+size]; newItem ¬ NEW[CHOpsP2V3.ItemObject[newLength]]; FOR i: CARDINAL IN [0..oldLength) DO newItem.body[i] ¬ item.body[i]; ENDLOOP; FOR i: CARDINAL IN [oldLength..newItem.length) DO newItem.body[i] ¬ 0; ENDLOOP; }; <<>> ItemFromBool: PUBLIC PROC [bool: BOOL, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfBool[], index, item]; nextPos ¬ BoolIntoItem[newItem, bool, index]; }; ItemFromInt16: PUBLIC PROC [int: INT16, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfInt16[], index, item]; nextPos ¬ Int16IntoItem[newItem, int, index]; }; ItemFromInt32: PUBLIC PROC [int: INT32, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfInt32[], index, item]; nextPos ¬ Int32IntoItem[newItem, int, index]; }; ItemFromCard16: PUBLIC PROC [card: CARD16, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfCard16[], index, item]; nextPos ¬ Card16IntoItem[newItem, card, index]; }; ItemFromCard32: PUBLIC PROC [card: CARD32, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfCard32[], index, item]; nextPos ¬ Card32IntoItem[newItem, card, index]; }; ItemFromAddress: PUBLIC PROC [address: Address, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfAddress[], index, item]; nextPos ¬ AddressIntoItem[newItem, address, index]; }; ItemFromRope: PUBLIC PROC [rope: ROPE, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfRope[rope], index, item]; nextPos ¬ RopeIntoItem[newItem, rope, index]; }; ItemFromName: PUBLIC PROC [name: Name, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfName[name], index, item]; nextPos ¬ NameIntoItem[newItem, name, index]; }; <> ItemFromAddressList: PUBLIC PROC [addresses: AddressList, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfAddressList[addresses], index, item]; nextPos ¬ AddressListIntoItem[newItem, addresses, index]; }; ItemFromRopeList: PUBLIC PROC [ropes: RopeList, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfRopeList[ropes], index, item]; nextPos ¬ RopeListIntoItem[newItem, ropes, index]; }; ItemFromNameList: PUBLIC PROC [names: NameList, index: CARDINAL ¬ 0, item: Item ¬ NIL] RETURNS [newItem: Item, nextPos: CARDINAL] = { newItem ¬ CreateNewItem[SizeOfNameList[names], index, item]; nextPos ¬ NameListIntoItem[newItem, names, index]; }; <> SizeOfBool: PUBLIC PROC RETURNS [size: CARDINAL] = { RETURN[1]; }; SizeOfInt16: PUBLIC PROC RETURNS [size: CARDINAL] = { RETURN[1]; }; SizeOfInt32: PUBLIC PROC RETURNS [size: CARDINAL] = { RETURN[2]; }; SizeOfCard16: PUBLIC PROC RETURNS [size: CARDINAL] = { RETURN[1]; }; SizeOfCard32: PUBLIC PROC RETURNS [size: CARDINAL] = { RETURN[2]; }; SizeOfRope: PUBLIC PROC [rope: ROPE] RETURNS [size: CARDINAL] = { RETURN[CrRPC.MarshalledRopeHWords[rope]]; }; SizeOfName: PUBLIC PROC [name: Name] RETURNS [size: CARDINAL] = { RETURN[ CrRPC.MarshalledRopeHWords[name.organization] + CrRPC.MarshalledRopeHWords[name.domain] + CrRPC.MarshalledRopeHWords[name.object] ]; }; SizeOfAddress: PUBLIC PROC RETURNS [size: CARDINAL] = { RETURN[adrHWords]; }; <> SizeOfRopeList: PUBLIC PROC [ropes: RopeList] RETURNS [size: CARDINAL] = { size ¬ SizeOfCard16[]; -- this holds the length of the SEQUENCE WHILE ropes # NIL DO size ¬ size + SizeOfRope[ropes.first]; ropes ¬ ropes.rest; ENDLOOP; }; SizeOfNameList: PUBLIC PROC [names: NameList] RETURNS [size: CARDINAL] = { size ¬ SizeOfCard16[]; -- this holds the length of the SEQUENCE WHILE names # NIL DO size ¬ size + SizeOfName[names.first]; names ¬ names.rest; ENDLOOP; }; SizeOfAddressList: PUBLIC PROC [addresses: AddressList] RETURNS [size: CARDINAL] = { size ¬ SizeOfCard16[]; -- this holds the length of the SEQUENCE WHILE addresses # NIL DO size ¬ size + SizeOfAddress[]; addresses ¬ addresses.rest; ENDLOOP; }; <> BoolIntoItem: PUBLIC PROC [item: Item, bool: BOOL, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { IF item = NIL OR item.length <= index THEN Error[itemLength]; item.body[index] ¬ IF bool THEN 1 ELSE 0; RETURN[index+1]; }; Int16IntoItem: PUBLIC PROC [item: Item, int: INT16, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { IF item = NIL OR item.length <= index THEN Error[itemLength]; item.body[index] ¬ int; RETURN[index+1]; }; Int32IntoItem: PUBLIC PROC [item: Item, int: INT32, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { n: Basics.LongNumber; IF item = NIL OR item.length <= index+1 THEN Error[itemLength]; n.li ¬ int; item[index] ¬ n.hi; item[index+1] ¬ n.lo; RETURN[index+2]; }; Card16IntoItem: PUBLIC PROC [item: Item, card: CARD16, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { IF item = NIL OR item.length <= index THEN Error[itemLength]; item.body[index] ¬ card; RETURN[index+1]; }; Card32IntoItem: PUBLIC PROC [item: Item, card: CARD32, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { n: Basics.LongNumber; IF item = NIL OR item.length <= index+1 THEN Error[itemLength]; n.lc ¬ card; item[index] ¬ n.hi; item[index+1] ¬ n.lo; RETURN[index+2]; }; RopeIntoItem: PUBLIC PROC [item: Item, rope: ROPE, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { buf: Basics.Word16; ropeLen: INT = Rope.Length[rope]; iFrom: INT ¬ 0; IF item = NIL OR item.length <= index+SizeOfRope[rope]-1 THEN Error[itemLength]; item.body[index] ¬ ropeLen; index ¬ index + 1; DO IF iFrom >= ropeLen THEN EXIT; buf.hi ¬ ORD[Rope.Fetch[rope, iFrom]]; iFrom ¬ iFrom+1; buf.lo ¬ IF iFrom < ropeLen THEN ORD[Rope.Fetch[rope, iFrom]] ELSE 0; iFrom ¬ iFrom+1; item.body[index] ¬ buf.card; index ¬ index + 1; ENDLOOP; RETURN[index]; }; NameIntoItem: PUBLIC PROC [item: Item, name: Name, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { nextPos ¬ RopeIntoItem[item, name.organization, index]; nextPos ¬ RopeIntoItem[item, name.domain, nextPos]; nextPos ¬ RopeIntoItem[item, name.object, nextPos]; }; AddressIntoItem: PUBLIC PROC [item: Item, address: Address, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { buf: PACKED ARRAY [0..adrHWords) OF Basics.HWORD ¬ LOOPHOLE[address]; FOR i: CARDINAL IN [0..adrHWords) DO item.body[index] ¬ Basics.Card16FromH[buf[i]]; index ¬ index + 1; ENDLOOP; RETURN[index]; }; <> RopeListIntoItem: PUBLIC PROC [item: Item, ropes: RopeList, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { countIndex: CARDINAL ¬ index; count: CARDINAL ¬ 0; nextPos ¬ Card16IntoItem[item, 0, index]; WHILE ropes # NIL DO nextPos ¬ RopeIntoItem[item, ropes.first, nextPos]; count ¬ count + 1; ropes ¬ ropes.rest; ENDLOOP; [] ¬ Card16IntoItem[item, count, countIndex]; }; NameListIntoItem: PUBLIC PROC [item: Item, names: NameList, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { countIndex: CARDINAL ¬ index; count: CARDINAL ¬ 0; nextPos ¬ Card16IntoItem[item, 0, index]; WHILE names # NIL DO nextPos ¬ NameIntoItem[item, names.first, nextPos]; count ¬ count + 1; names ¬ names.rest; ENDLOOP; [] ¬ Card16IntoItem[item, count, countIndex]; }; AddressListIntoItem: PUBLIC PROC [item: Item, addresses: AddressList, index: CARDINAL ¬ 0] RETURNS [nextPos: CARDINAL] = { countIndex: CARDINAL ¬ index; count: CARDINAL ¬ 0; nextPos ¬ Card16IntoItem[item, 0, index]; WHILE addresses # NIL DO nextPos ¬ AddressIntoItem[item, addresses.first, nextPos]; count ¬ count + 1; addresses ¬ addresses.rest; ENDLOOP; [] ¬ Card16IntoItem[item, count, countIndex]; }; }.