====== std.iso — ISO 9660-Images lesen und schreiben ====== ''std.iso'' liest und schreibt ISO 9660-Images (Level 1) ohne externe Abhängigkeiten. Der Reader traversiert den vollständigen Verzeichnisbaum per BFS und gibt vollständige Pfade zurück (''subdir/DATEI.TXT''). Der Writer erzeugt ein gültiges bootfähiges ISO-Image mit flachem Root-Verzeichnis. → [[lyx_-_programmiersprache:units|Standard Library]] · [[lyx_-_programmiersprache:units:zip|std.zip]] · [[lyx_-_programmiersprache:units:tar|std.tar]] **Image-Layout (festes Schema):** Sektor 0–15 System Area (leer) Sektor 16 PVD — Primary Volume Descriptor (Volume-ID: "LYXISO") Sektor 17 VDST — Volume Descriptor Set Terminator Sektor 18–19 Path Table (L-Type + M-Type) Sektor 20 Root-Verzeichnis Sektor 21+ Dateidaten **Einschränkungen:** * Sektorgröße: 2048 Bytes (ISO 9660 Standard) * Max. 4096 Dateieinträge, max. 256 Verzeichnisse (Lesen) * Writer: nur flaches Root-Verzeichnis — keine Unterverzeichnisse * Dateinamen (Writer): max. 36 Zeichen, nur ''A–Z 0–9 _ .'' — ungültige Zeichen werden zu ''_'', Kleinbuchstaben zu Großbuchstaben * Kein Joliet, kein Rock Ridge, kein El Torito Boot-Record ---- ===== Konstanten ===== ^ Konstante ^ Wert ^ Bedeutung ^ | ''ISO_SECTOR'' | 2048 | Sektorgröße in Bytes | | ''ISO_MAX_ENTRIES'' | 4096 | Maximale Dateieinträge pro Image | | ''ISO_MAX_DIRS'' | 256 | Maximale Verzeichnisse (BFS-Queue beim Lesen) | | ''ISO_MAX_PATH'' | 512 | Maximale Pfadlänge in Bytes | | ''ISO_ERR_OK'' | 0 | Kein Fehler | | ''ISO_ERR_NOTISO'' | 1 | Keine gültige ISO 9660-Datei (PVD-Signatur fehlt) | | ''ISO_ERR_IO'' | 2 | I/O-Fehler beim Lesen oder Schreiben | | ''ISO_ERR_CORRUPT'' | 3 | Image beschädigt | | ''ISO_ERR_FULL'' | 4 | ISO_MAX_ENTRIES erreicht | | ''ISO_ERR_NAMETOOLONG'' | 5 | Dateiname > 36 Zeichen oder leer | ---- ===== Lesen (IsoReader) ===== ^ Funktion ^ Rückgabe ^ Beschreibung ^ | ''IsoOpen(path)'' | ''int64'' Handle oder 0 | Öffnet ISO-Image, traversiert vollständigen Verzeichnisbaum (BFS) | | ''IsoClose(handle)'' | ''void'' | Gibt Handle und alle Ressourcen frei | | ''IsoCount(handle)'' | ''int64'' | Anzahl der Dateieinträge (keine Verzeichnisse) | | ''IsoName(handle, idx)'' | ''int64'' pchar | Vollständiger Pfad des idx-ten Eintrags (interner Puffer — nicht free'n) | | ''IsoSize(handle, idx)'' | ''int64'' | Dateigröße in Bytes | | ''IsoRead(handle, idx, outBuf, maxLen)'' | ''int64'' Bytes oder -1 | Liest Dateiinhalt in outBuf | | ''IsoFind(handle, name)'' | ''int64'' Index oder -1 | Sucht Eintrag nach exaktem Pfad | Der Reader gibt vollständige Pfade zurück, inklusive Verzeichnisnamen: ''BOOT/GRUB/GRUB.CFG'' oder ''DATA/LOG.TXT''. Verzeichniseinträge selbst erscheinen nicht in der Liste — nur reguläre Dateien. import std.iso; import std.alloc; import std.io; fn IsoInhaltLesen(pfad: pchar): void { var img: int64 := IsoOpen(pfad as int64); if img == 0 then { PrintLn("Kein gültiges ISO 9660-Image"c); return; } var n: int64 := IsoCount(img); Print("Dateien: "c); PrintLn(IntToStr(n)c); var i: int64 := 0; while i < n do { Print(IsoName(img, i) as pchar); Print(" "c); PrintLn(IntToStr(IsoSize(img, i))c); i := i + 1; } // Datei nach Pfad suchen und lesen var idx: int64 := IsoFind(img, "BOOT/GRUB/GRUB.CFG"c as int64); if idx >= 0 then { var sz: int64 := IsoSize(img, idx); var buf: int64 := alloc(sz + 1); IsoRead(img, idx, buf, sz); poke8(buf + sz, 0); PrintLn(buf as pchar); free(buf, sz + 1); } IsoClose(img); } ---- ===== Schreiben (IsoWriter) ===== ^ Funktion ^ Rückgabe ^ Beschreibung ^ | ''IsoWriterNew()'' | ''int64'' Writer-Handle | Erstellt neuen leeren Writer | | ''IsoWriterAdd(w, name, data, dataLen)'' | ''int64'' Fehlercode | Fügt Datei hinzu; Name wird automatisch normalisiert | | ''IsoWriterSave(w, path)'' | ''int64'' Fehlercode | Schreibt vollständiges ISO 9660-Image | | ''IsoWriterFree(w)'' | ''void'' | Gibt Writer frei (nicht die data-Puffer — diese gehören dem Aufrufer) | ''IsoWriterAdd'' normalisiert den Dateinamen automatisch: Kleinbuchstaben → Großbuchstaben, ungültige Zeichen → ''_''. Das Version-Suffix '';1'' wird beim Schreiben angehängt und erscheint im Reader als Teil des Namens. import std.iso; import std.alloc; fn IsoErstellen(): void { var w: int64 := IsoWriterNew(); var readme: pchar := "Lyx ISO 9660 Image\n"c; IsoWriterAdd(w, "README.TXT"c as int64, readme as int64, 19); // Kleinbuchstaben und Sonderzeichen werden normalisiert: // "boot-config.txt" → "BOOT_CONFIG.TXT" im Image var cfg: pchar := "boot=default\n"c; IsoWriterAdd(w, "boot-config.txt"c as int64, cfg as int64, 13); var rc: int64 := IsoWriterSave(w, "ausgabe.iso"c as int64); if rc == ISO_ERR_NAMETOOLONG then { PrintLn("Dateiname zu lang (max. 36 Zeichen)"c); } else if rc != ISO_ERR_OK then { PrintLn("Fehler beim Speichern"c); } IsoWriterFree(w); } **Hinweis zu data-Puffern:** ''IsoWriterAdd'' kopiert die Daten **nicht** — es speichert nur den Zeiger. Die Puffer müssen bis zum Aufruf von ''IsoWriterSave'' gültig bleiben. ''IsoWriterFree'' gibt nur die Name-Strings frei, nicht die data-Zeiger. ---- ===== Dateinamen-Normalisierung ===== ISO 9660 Level 1 erlaubt nur einen eingeschränkten Zeichensatz: ^ Eingabe ^ Im Image ^ | ''readme.txt'' | ''README.TXT'' | | ''boot-config.cfg'' | ''BOOT_CONFIG.CFG'' | | ''mein datei.bin'' | ''MEIN_DATEI.BIN'' | | ''sehr-langer-dateiname-über-36-zeichen.txt'' | ''ISO_ERR_NAMETOOLONG'' (Fehler) | Gültige Zeichen: ''A–Z'', ''0–9'', ''_'', ''.'' — alles andere wird zu ''_''. ---- ===== Speicherverwaltung ===== ^ Handle ^ Freigabe ^ | ''IsoOpen'' → Reader-Handle | ''IsoClose(handle)'' | | ''IsoWriterNew'' → Writer-Handle | ''IsoWriterFree(w)'' | | ''IsoName'' → interner Puffer | **nicht free'n** — gehört dem Handle | | ''outBuf'' in ''IsoRead'' | Aufrufer allokiert, Aufrufer gibt frei | | ''data''-Zeiger in ''IsoWriterAdd'' | Aufrufer verwaltet — bis ''IsoWriterSave'' gültig halten | Letzte Aktualisierung: 2026-06-13