DIRECTORY Basics USING [ByteBlt, charsPerWord, RawBytes, UnsafeBlock], Rope USING [ROPE], YggRep USING [Bits, BitsRep]; YggBitsImpl: CEDAR PROGRAM IMPORTS Basics EXPORTS YggRep ~ BEGIN ROPE: TYPE ~ Rope.ROPE; BytesFromBits: PUBLIC PROC [bits: YggRep.Bits, startByte: CARD, block: Basics.UnsafeBlock] ~ { WITH bits SELECT FROM rBits: REF YggRep.BitsRep => TRUSTED { nBytes: CARD; IF rBits.length >= startByte + block.count THEN ERROR; nBytes _ Basics.ByteBlt[ from: [blockPointer: LOOPHOLE[rBits, POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: startByte, stopIndexPlusOne: startByte+block.count], to: [blockPointer: LOOPHOLE[block.base], startIndex: block.startIndex, stopIndexPlusOne: block.startIndex + block.count] ]; IF nBytes # block.count THEN ERROR; }; ENDCASE => ERROR; }; SizeOfBits: PUBLIC PROC [bits: YggRep.Bits] RETURNS [size: CARD] ~ { WITH bits SELECT FROM rBits: REF YggRep.BitsRep => { RETURN[rBits.length]; }; ENDCASE => ERROR; }; SetSizeOfBits: PUBLIC PROC [bits: YggRep.Bits, size: CARD] RETURNS [newRef: BOOL _ FALSE, newBits: YggRep.Bits _ NIL] ~ { WITH bits SELECT FROM rBits: REF YggRep.BitsRep => { newBits: REF YggRep.BitsRep _ NIL; wordLen: INT; IF size <= rBits.length THEN {rBits.validBytes _ size; RETURN [FALSE, NIL]; }; wordLen _ ((rBits.length - 1 + Basics.charsPerWord)/Basics.charsPerWord); -- round up to words wordLen _ IF wordLen < 20 THEN wordLen _ wordLen + 1 ELSE wordLen + wordLen/20; rBits _ NEW[YggRep.BitsRep[Basics.charsPerWord * wordLen]]; TRUSTED { nBytes: CARD; nBytes _ Basics.ByteBlt[ from: [blockPointer: LOOPHOLE[rBits, POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes], to: [blockPointer: LOOPHOLE[newBits, POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes] ]; IF nBytes # rBits.validBytes THEN ERROR; newBits.validBytes _ size; }; RETURN[TRUE, newBits]; }; ENDCASE => ERROR; }; BytesToBits: PUBLIC PROC [bits: YggRep.Bits, startByte: CARD, block: Basics.UnsafeBlock] RETURNS [newRef: BOOL _ FALSE, newBits: YggRep.Bits _ NIL] ~ { WITH bits SELECT FROM rBits: REF YggRep.BitsRep => { IF startByte + block.count <= rBits.length THEN { -- it fits in the current object nBytes: CARD; TRUSTED {nBytes _ Basics.ByteBlt[ from: [blockPointer: LOOPHOLE[block.base], startIndex: block.startIndex, stopIndexPlusOne: block.startIndex + block.count], to: [blockPointer: LOOPHOLE[rBits, POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: startByte, stopIndexPlusOne: startByte + block.count] ]; }; IF nBytes # rBits.validBytes THEN ERROR; rBits.validBytes _ MAX[rBits.validBytes, startByte + block.count]; RETURN[FALSE, NIL]; } ELSE { newBits: REF YggRep.BitsRep _ NIL; wordLen: INT; wordLen _ ((rBits.length - 1 + Basics.charsPerWord)/Basics.charsPerWord); -- round up to words wordLen _ IF wordLen < 20 THEN wordLen _ wordLen + 1 ELSE wordLen + wordLen/20; rBits _ NEW[YggRep.BitsRep[Basics.charsPerWord * wordLen]]; TRUSTED { nBytes: CARD; nBytes _ Basics.ByteBlt[ from: [blockPointer: LOOPHOLE[rBits, POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes], to: [blockPointer: LOOPHOLE[newBits, POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes] ]; IF nBytes # rBits.validBytes THEN ERROR; nBytes _ Basics.ByteBlt[ from: [blockPointer: block.base, startIndex: block.startIndex, stopIndexPlusOne: block.startIndex + block.count], to: [blockPointer: LOOPHOLE[newBits, POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: startByte, stopIndexPlusOne: startByte + block.count] ]; IF nBytes # rBits.validBytes THEN ERROR; newBits.validBytes _ startByte + block.count; }; RETURN[TRUE, newBits]; }; }; ENDCASE => ERROR; }; END. YggBitsImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Bob Hagmann April 13, 1988 4:03:18 pm PDT This module implements the Bits datatype. Exported procedures Fetch some bytes from an "uninterpreted bytes" object Size in bytes of an "uninterpreted bytes" object. Set the size in bytes of an "uninterpreted bytes" object. If this grows the object, the new bytes are uninitalized. This may grow the object and change its representation. All callers must look at the newRef and newBits return values. If newRef is TRUE, then the old bits object is no longer valid. The caller is responsible for updating the data structure from which it obtained the bits. Store some bytes into an uninterpreted bytes" object. This may grow the object and change its representation. All callers must look at the newRef and newBits return values. If newRef is TRUE, then the old bits object is no longer valid. The caller is responsible for updating the data structure from which it obtained the bits. Κ=˜code•Mark outsideHeaderšœ™Kšœ<™