SampleArraysImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Eric Nickell, January 6, 1986 3:39:51 pm PST
DIRECTORY
AIS, FS, Rope, SampleArrays, SampleMapOps;
SampleArraysImpl: CEDAR PROGRAM
IMPORTS AIS, FS, Rope, SampleMapOps
EXPORTS SampleArrays
~ BEGIN
OPEN SampleArrays;
ROPE: TYPE ~ Rope.ROPE;
Error: PUBLIC ERROR [error: ErrorDesc] ~ CODE;
GetSamples: PUBLIC PROC [buffer: Buffer, start: NAT ← 0, count: NAT ← maxCount,
sa: SampleArray, i: NAT, s, f: NAT ← 0, ds: NAT ← 0, df: NAT ← 1] ~ {
SampleMapOps.Get[buffer: buffer, start: start, count: count, sampleMap: sa.layer[i].sm, s: s, f: f, ds: ds, df: df];
};
! BoundsFault if any index into sa is out of range
PutSamples: PUBLIC PROC [buffer: Buffer, start: NAT ← 0, count: NAT ← maxCount,
sa: SampleArray, i: NAT, s, f: NAT ← 0, ds: NAT ← 0, df: NAT ← 1, function: Function ← nullFunction] ~ {
SampleMapOps.Put[buffer: buffer, start: start, count: count, sampleMap: sa.layer[i].sm, s: s, f: f, ds: ds, df: df, function: function];
};
! BoundsFault if any index into sa is out of range
Join3Maps: PUBLIC PROC [sm1, sm2, sm3: SampleMapEntry] RETURNS [SampleArray] ~ {
sa: SampleArray ~ NEW[SampleArrayRep[3]];
sa.layer[0] ← sm1;
sa.layer[1] ← sm2;
sa.layer[2] ← sm3;
sa.sSize ← sa.layer[0].sm.sSize;
sa.fSize ← sa.layer[0].sm.fSize;
FOR i: NAT IN [0..3) DO
IF sa.sSize#sa.layer[i].sm.sSize OR sa.fSize#sa.layer[0].sm.fSize THEN Error[[$incompatibleJoin, "Sample maps not of consistent sSize and fSize"]];
ENDLOOP;
RETURN [sa];
};
FromAIS: PUBLIC PROC [name: ROPE] RETURNS [SampleArray] ~ {
sm: SampleMapEntry ~ MapFromAIS[name];
sa: SampleArray ~ NEW[SampleArrayRep[1]];
sa.layer[0] ← sm;
sa.sSize ← sa.layer[0].sm.sSize;
sa.fSize ← sa.layer[0].sm.fSize;
RETURN [sa];
};
MapFromAIS: PUBLIC PROC [name: ROPE] RETURNS [SampleMapEntry] ~ {
fref: AIS.FRef ~ AIS.OpenFile[name: name];
wref: AIS.WRef ~ AIS.OpenWindow[f: fref];
sSize: NAT ~ fref.raster.scanCount;
fSize: NAT ~ fref.raster.scanLength;
sm: SampleMap ~ SampleMapOps.Create[sSize: sSize, fSize: fSize, bitsPerSample: fref.raster.bitsPerPixel];
check: [0..0] ~ sm.base.bit;  --Better be zero
ptr: LONG POINTER ← sm.base.word;
words: CARDINAL ~ sm.bitsPerLine/16;
FOR scan: NAT IN [0 .. sSize) DO
TRUSTED {AIS.UnsafeReadLine[w: wref, buffer: [length: fSize, addr: ptr], line: scan]};
TRUSTED {ptr ← ptr+words};
ENDLOOP;
RETURN [[sm: sm, class: $AIS, data: fref]];
};
CreateAISFromMap: PUBLIC PROC [sm: SampleMap, name: ROPE] ~ {
raster: AIS.Raster ~ NEW[AIS.RasterPart ← [
scanCount: sm.sSize,
scanLength: sm.fSize,
scanMode: dr,
bitsPerPixel: sm.bitsPerSample,
linesPerBlock: -1,
paddingPerBlock: 0
]];
fref: AIS.FRef ~ AIS.CreateFile[name: name, raster: raster];
sme: SampleMapEntry ~ [sm: sm, class: $AIS, data: fref];
sa: SampleArray ~ NEW[SampleArrayRep[1]];
sa.sSize ← sm.sSize;
sa.fSize ← sm.fSize;
sa[0] ← sme;
Save[sa];
};
Join3AIS: PUBLIC PROC [name1, name2, name3: ROPE] RETURNS [SampleArray] ~ {
sm1: SampleMapEntry ~ MapFromAIS[name1];
sm2: SampleMapEntry ~ MapFromAIS[name2];
sm3: SampleMapEntry ~ MapFromAIS[name3];
RETURN [Join3Maps[sm1, sm2, sm3]];
};
HackOffVersionPart: PROC [name: ROPE] RETURNS [result: ROPE] ~ {
RETURN [Rope.Substr[base: name, len: Rope.Index[s1: name, s2: "!"]]];
};
HackOffExtension: PROC [name: ROPE] RETURNS [result: ROPE] ~ {
result ← HackOffVersionPart[name];
RETURN [Rope.Substr[base: result, len: Rope.Index[s1: result, s2: "."]]];
};
ROPESEQ: TYPE ~ RECORD [SEQUENCE n: NAT OF ROPE];
FileNameRoot: PUBLIC PROC [sa: SampleArray] RETURNS [root: ROPE] ~ {
AllCharsTheSame: PROC [i: INT] RETURNS [BOOLTRUE] ~ {
char: CHAR ~ Rope.Fetch[base: ropes[0], index: i];
FOR layer: NAT IN [1..ropes.n) DO
IF Rope.Fetch[base: ropes[layer], index: i]#char THEN RETURN [FALSE];
ENDLOOP;
};
length: INTINT.LAST;
matches: INT ← 0;
ropes: REF ROPESEQNEW[ROPESEQ[sa.n]];
FOR i: NAT IN [0..ropes.n) DO
ropes[i] ← HackOffExtension[BackingFileOf[sa[i]]];
length ← MIN[length, Rope.Length[base: ropes[i]]];
ENDLOOP;
WHILE matches<length AND AllCharsTheSame[matches] DO
matches ← matches+1;
ENDLOOP;
length ← MIN[length, matches];
root ← Rope.Substr[base: ropes[0], len: length];
IF Rope.Fetch[base: root, index: length-1]='- THEN root ← Rope.Substr[base: root, len: length-1];
};
BackingFileOf: PUBLIC PROC [sme: SampleMapEntry] RETURNS [backingFileName: ROPE] ~ {
RETURN [FS.GetName[file: NARROW[sme.data, AIS.FRef].file].fullFName];
};
Save: PUBLIC PROC [sa: SampleArray] ~ {
FOR layer: NAT IN [0..sa.n) DO
sme: SampleMapEntry ~ sa.layer[layer];
IF sme.class#$AIS THEN LOOP;
TRUSTED {
old: AIS.FRef ~ NARROW[sme.data];
fileName: ROPE ~ HackOffVersionPart[FS.GetName[file: old.file].fullFName];
new: AIS.FRef ~ AIS.CreateFile[name: fileName, raster: old.raster];
wref: AIS.WRef ~ AIS.OpenWindow[f: new];
sSize: NAT ~ new.raster.scanCount;
fSize: NAT ~ new.raster.scanLength;
check: [0..0] ~ sme.sm.base.bit;  --Better be zero
ptr: LONG POINTER ← sme.sm.base.word;
words: CARDINAL ~ sme.sm.bitsPerLine/16;
FOR scan: NAT IN [0 .. sSize) DO
AIS.UnsafeWriteLine[w: wref, buffer: [length: fSize, addr: ptr], line: scan];
ptr ← ptr+words;
ENDLOOP;
AIS.CloseWindow[w: wref];
AIS.CloseFile[f: new];
};
ENDLOOP;
};
END.