32Diagnosen, Quellpositionen, Limits & Threads
Jedes ZplRenderResult hat Diagnostics: ZplDiagnostic mit stabilem Code, Schweregrad, Meldung, Befehl und Position (Offset, Zeile, Spalte). Warnings bleibt erhalten und enthält die Meldungen aller Warnungen und Fehler.
Online ausprobieren auf zplCloud.com: ZPL-Linter
| Code | Schwere | Bedeutung |
|---|---|---|
ZPL1001 | Error | Befehl mit fehlerhaften Parametern ignoriert (Rest des Etiketts wird gerendert) |
ZPL1002 | Warning | Feld konnte nicht gezeichnet werden (z. B. ungültige Barcode-Daten) |
ZPL1003 | Warning | Barcode-Daten länger als jede Symbologie fassen kann |
ZPL1101 | Warning | ^GF größer als das Etikett oder MaxGraphicBytes |
ZPL1102 | Warning | ^GF-Daten nicht dekodierbar |
ZPL1103 | Warning | ^XG/^IM verweist auf nicht gespeicherte Grafik |
ZPL1201 | Warning | ^A@-Schrift nicht gefunden – Schrift A wird verwendet, wie am Zebra |
ZPL1301 | Warning | FieldValues-Schlüssel ohne passendes ^FN (INVALID_FIELD_VALUE_KEY) |
ZPL2001 | Info | Akzeptiert, ohne Wirkung aufs Bild (^FE, ^FA, RFID-Operationen außer Schreiben) |
Mit TraceElements trägt jedes Element SourceOffset/SourceLength (sein ^FO…^FS-Block); jeder geparste ZplCommand hat Offset/Length, ZplParser.LineColumn rechnet um. Fehlende ^A@-Schriften liefert auf Wunsch der Callback FontProvider.
var renderer = new ZplRenderer(new ZplRenderSettings
{
TraceElements = true,
FontProvider = name => name == "E:BRAND.TTF" ? File.ReadAllBytes("fonts/Brand.ttf") : null,
});
foreach (var result in renderer.Render(zpl))
{
foreach (ZplDiagnostic d in result.Diagnostics) // z. B. "ZPL1201 warning (3:12): …"
Console.WriteLine($"{d.Code} {d.Severity} {d.Command} Zeile {d.Line}, Spalte {d.Column}: {d.Message}");
foreach (var e in result.Elements) // ^FO…^FS-Bereich im Quelltext
Console.WriteLine(zpl.Substring(e.SourceOffset, e.SourceLength));
result.Bitmap.Dispose();
}
Limits für fremde Eingaben & Thread-Sicherheit
Standardwerte: MaxLabelSide 32000, MaxLabelDots 64 Mio., MaxQuantity 10000, MaxLabels 100000, MaxGraphicBytes 32 MB (auch Z64-Entpackgrenze gegen Zip-Bomben), MaxFieldDataLength 1 Mio., ZplResourceStore.MaxTotalBytes 256 MB. ZplRenderer/EplRenderer halten Druckerzustand und sind nicht thread-sicher – ein Renderer pro Thread; ZplResourceStore, FontManager, ZplCaches, PropertyPath und konfigurierte LabelBindings sind es. ConcurrencyTests vergleicht SHA-256 aller Ausgaben von 16 Threads mit dem Einzel-Thread-Lauf; samples/FuzzRunner füttert den Parser mit Zufalls- und mutierten Eingaben, samples/LeakTest rendert 1 Mio. Etiketten und protokolliert Heap und RSS. Details: THREADING.md, DIAGNOSTICS.md.
var shared = new ZplResourceStore(); // thread-safe, von vielen Renderern teilbar
var safe = new ZplRenderSettings
{
MaxLabelSide = 8000, MaxLabelDots = 16_000_000, MaxQuantity = 100,
MaxLabels = 1000, MaxGraphicBytes = 4 * 1024 * 1024, MaxFieldDataLength = 10_000,
};
Parallel.For(0, 8, _ =>
{
var r = new ZplRenderer(safe) { Store = shared }; // ein Renderer pro Thread
r.ProcessCommands(untrusted);
});

