<> <> <> <<>> <> <<>> 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.