Warning: session_start(): open(/var/lib/php/sessions/sess_hmu75mh312epr6k0vupftanthk, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
sclass CleanFluidTextFile implements Runnable {
srecord Entry(S text, SS params) {
long targetIndex;
S actualText() { ret unquote(text); }
}
int maxRefLength = 8;
bool verbose;
Reader reader;
Writer writer;
new Map relocationMap;
long maxFileSize() {
ret rangeOfNHexNumberWithNDigits(maxRefLength);
}
public void run() ctex {
Producer p = javaTok_onReader(reader);
new StringBuilder buf;
new L entries;
S t;
p.next(); // skip initial white space
while ((t = p.next()) != null) {
if (isMLS(t)) {
S header = getAndClearStringBuilder(buf);
entries.add(new Entry(t, parseEqualsCommaProperties(header)));
p.next(); // skip white space
} else
buf.append(t); // part of entry header
}
//pnlStruct(entries);
// make a map and pessimistically assign byte indices to all entries
for (Entry e : entries)
mapPut(relocationMap, e.params.get("i"), e);
makeIndices(entries);
// rewrite references
for (Entry e : entries)
if (hasReferences(e))
e.text = replaceRefs(e, r -> lookupInRelocationMap(r));
// write out
long idx = 0; // index into file
for (Entry e : entries) {
assertEquals(idx, e.targetIndex);
e.params.put("i", renderReference(e.targetIndex));
S line = entryToString(e, idx);
if (verbose)
print("> " + line);
writer.write(line);
idx += lUtf8(line);
}
}
S lookupInRelocationMap(S ref) {
Entry e = relocationMap.get(ref);
//print("lookupInRelocationMap: " + ref + " => " + e);
ret e == null ? null : renderReference(e.targetIndex);
}
S renderReference(long idx) {
ret takeLast(maxRefLength, longToHex(idx));
}
void makeIndices(L entries) {
long idx = 0; // index into file
for (Entry e : entries) {
e.targetIndex = idx;
idx += pessimisticEntryLength(e);
}
}
S entryToString(Entry e, long idx) {
ret entryToString(e, renderReference(idx));
}
S entryToString(Entry e, S idx) {
SS params = litorderedmap(
i := idx,
l := intToHex_flexLength(l(e.text)));
mapPutAll_noOverwrite(params, e.params);
ret renderEqualsCommaProperties(params) + " " + e.text + "\n";
}
S dummyRef() {
ret rep('0', maxRefLength);
}
bool hasReferences(Entry e) {
ret eq(e.params.get("refs"), quote("at *"));
}
int pessimisticEntryLength(Entry e) {
Entry e2 = e;
if (hasReferences(e)) {
e2 = cloneObject(e);
e2.text = replaceRefs(e, r -> dummyRef());
}
ret l(entryToString(e2, dummyRef()));
}
S replaceRefs(Entry e, IF1 f) {
LS tok = javaTok(e.actualText());
for (int i : jfindAll(tok, "at *")) {
S x = f.get(tok.get(i+2));
if (nempty(x))
tok.set(i+2, x);
}
ret multiLineQuote(join(tok));
}
}