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;
Unmarshaling of a single value
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];
};
Unmarshaling of SEQUENCE of xxx from the Item into a LIST for Cedar
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];
};
Now for lists
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];
};
SizeOf PROCs
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];
};
Now SizeOf lists
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;
};
IntoItem PROCs
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];
};
Now the lists
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];
};
}.