<> <> <> <<>> <> <<>> DIRECTORY PBasics USING [ByteBlt, charsPerWord, RawBytes, UnsafeBlock], Rope USING [ROPE], YggRep USING [Bits, BitsRep]; YggBitsImpl: CEDAR PROGRAM IMPORTS PBasics EXPORTS YggRep ~ BEGIN ROPE: TYPE ~ Rope.ROPE; <> BytesFromBits: PUBLIC PROC [bits: YggRep.Bits, startByte: CARD, block: PBasics.UnsafeBlock] ~ { <> WITH bits SELECT FROM rBits: REF YggRep.BitsRep => TRUSTED { nBytes: CARD; IF startByte >= rBits.validBytes THEN ERROR; IF rBits.validBytes < startByte + CARD[block.count] THEN ERROR; nBytes _ PBasics.ByteBlt[ from: [blockPointer: LOOPHOLE[rBits, LONG 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 # CARD[block.count] THEN ERROR; }; ENDCASE => ERROR; }; BitsFromBits: PUBLIC PROC [bits: YggRep.Bits] RETURNS [copy: YggRep.Bits] ~ { <> IF bits = NIL THEN RETURN[NIL]; WITH bits SELECT FROM rBits: REF YggRep.BitsRep => TRUSTED { bitsCopy: REF YggRep.BitsRep; IF rBits.length < rBits.validBytes THEN ERROR; copy _ bitsCopy _ NEW[YggRep.BitsRep[rBits.length]]; TRUSTED { nBytes: CARD; nBytes _ PBasics.ByteBlt[ from: [blockPointer: LOOPHOLE[rBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes], to: [blockPointer: LOOPHOLE[bitsCopy, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes] ]; IF nBytes # rBits.validBytes THEN ERROR; bitsCopy.validBytes _ rBits.validBytes; }; }; ENDCASE => ERROR; }; <<>> <<>> SizeOfBits: PUBLIC PROC [bits: YggRep.Bits] RETURNS [size: CARD] ~ { <> IF bits = NIL THEN RETURN[0]; WITH bits SELECT FROM rBits: REF YggRep.BitsRep => { RETURN[rBits.validBytes]; }; ENDCASE => ERROR; }; <<>> <<>> SetSizeOfBits: PUBLIC PROC [bits: YggRep.Bits, size: CARD] RETURNS [newRef: BOOL _ FALSE, newBits: YggRep.Bits _ NIL] ~ { <> IF bits = NIL THEN { wordLen: INT; newBitsR: REF YggRep.BitsRep; newRef _ TRUE; wordLen _ (((size + PBasics.charsPerWord) - 1)/PBasics.charsPerWord); -- round up to words newBitsR _ newBits _ NEW[YggRep.BitsRep[PBasics.charsPerWord * wordLen]]; newBitsR.validBytes _ size; RETURN[TRUE, newBits]; }; WITH bits SELECT FROM rBits: REF YggRep.BitsRep => { wordLen: INT; newBitsR: REF YggRep.BitsRep; IF size <= rBits.length THEN {rBits.validBytes _ size; RETURN [FALSE, NIL]; }; wordLen _ (((size + PBasics.charsPerWord) - 1)/PBasics.charsPerWord); -- round up to words wordLen _ IF wordLen < 20 THEN wordLen _ wordLen + 1 ELSE wordLen + wordLen/20; newBitsR _ newBits _ NEW[YggRep.BitsRep[PBasics.charsPerWord * wordLen]]; TRUSTED { nBytes: CARD; nBytes _ PBasics.ByteBlt[ from: [blockPointer: LOOPHOLE[rBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes], to: [blockPointer: LOOPHOLE[newBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes] ]; IF nBytes # rBits.validBytes THEN ERROR; newBitsR.validBytes _ size; }; RETURN[TRUE, newBits]; }; ENDCASE => ERROR; }; <<>> <<>> BytesToBits: PUBLIC PROC [bits: YggRep.Bits, startByte: CARD, block: PBasics.UnsafeBlock] RETURNS [newRef: BOOL _ FALSE, newBits: YggRep.Bits _ NIL] ~ { <> IF bits = NIL THEN { nBits: REF YggRep.BitsRep _ NIL; wordLen: INT; wordLen _ ((startByte + CARD[block.count] - 1 + PBasics.charsPerWord)/PBasics.charsPerWord); -- round up to words wordLen _ IF wordLen < 20 THEN wordLen _ wordLen + 1 ELSE wordLen + wordLen/20; nBits _ NEW[YggRep.BitsRep[PBasics.charsPerWord * wordLen]]; TRUSTED { nBytes: CARD; nBytes _ PBasics.ByteBlt[ from: [blockPointer: block.base, startIndex: block.startIndex, stopIndexPlusOne: block.startIndex + block.count], to: [blockPointer: LOOPHOLE[nBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: startByte, stopIndexPlusOne: startByte + block.count] ]; IF INT[nBytes] # block.count THEN ERROR; nBits.validBytes _ startByte + block.count; }; RETURN[TRUE, nBits]; }; WITH bits SELECT FROM rBits: REF YggRep.BitsRep => { IF startByte + CARD[block.count] <= rBits.length THEN { -- it fits in the current object nBytes: INT; TRUSTED {nBytes _ PBasics.ByteBlt[ from: [blockPointer: LOOPHOLE[block.base], startIndex: block.startIndex, stopIndexPlusOne: block.startIndex + block.count], to: [blockPointer: LOOPHOLE[rBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: startByte, stopIndexPlusOne: startByte + block.count] ]; }; IF nBytes # block.count THEN ERROR; rBits.validBytes _ MAX[rBits.validBytes, startByte + CARD[block.count]]; RETURN[FALSE, NIL]; } ELSE { nBits: REF YggRep.BitsRep _ NIL; wordLen: INT; wordLen _ ((startByte + CARD[block.count] - 1 + PBasics.charsPerWord)/PBasics.charsPerWord); -- round up to words wordLen _ IF wordLen < 20 THEN wordLen _ wordLen + 1 ELSE wordLen + wordLen/20; nBits _ NEW[YggRep.BitsRep[PBasics.charsPerWord * wordLen]]; TRUSTED { nBytes: CARD; nBytes _ PBasics.ByteBlt[ from: [blockPointer: LOOPHOLE[rBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes], to: [blockPointer: LOOPHOLE[nBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: 0, stopIndexPlusOne: rBits.validBytes] ]; IF nBytes # rBits.validBytes THEN ERROR; nBytes _ PBasics.ByteBlt[ from: [blockPointer: block.base, startIndex: block.startIndex, stopIndexPlusOne: block.startIndex + block.count], to: [blockPointer: LOOPHOLE[nBits, LONG POINTER] + SIZE[YggRep.BitsRep[0]], startIndex: startByte, stopIndexPlusOne: startByte + block.count] ]; IF INT[nBytes] # block.count THEN ERROR; nBits.validBytes _ startByte + block.count; }; RETURN[TRUE, nBits]; }; }; ENDCASE => ERROR; }; <<>> <<>> END.