Warning: session_start(): open(/var/lib/php/sessions/sess_rlu7oti6pllv6hl4j86ul4u8gs, 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); }
}
// set by user
int maxRefLength = 8;
bool verbose;
Reader reader;
Writer writer;
// set by class
new L entries;
new Map relocationMap;
long maxFileSize() {
ret rangeOfNHexNumberWithNDigits(maxRefLength);
}
public void run() ctex {
FluidTextFileEntry entry;
while ((entry = readFluidTextFileEntry(reader)) != null) {
entries.add(new Entry(entry.quotedContent, entry.params));
}
//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(e.targetIndex, idx);
e.params.put("i", renderReference(e.targetIndex));
S line = entryToString(e, idx);
if (verbose)
print(quote(line));
writer.write(line);
int l = lUtf8(line);
if (verbose)
print("Actual entry length: " + l);
idx += l;
}
}
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;
int l = pessimisticEntryLength(e);
idx += l;
if (verbose)
print("Pessimistic entry length: " + l);
}
}
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(lUtf8(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());
if (verbose)
print("Pessimistic: rewrote text to " + quote(e2.text));
}
S s = entryToString(e2, dummyRef());
if (verbose)
print(quote(s));
ret lUtf8(s);
}
S replaceRefs(Entry e, IF1 f) {
LS tok = javaTokWithUnifiedNumbersAndIdentifiers(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));
}
}