zplCore.comzplCore.com

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

CodeSchwereBedeutung
ZPL1001ErrorBefehl mit fehlerhaften Parametern ignoriert (Rest des Etiketts wird gerendert)
ZPL1002WarningFeld konnte nicht gezeichnet werden (z. B. ungültige Barcode-Daten)
ZPL1003WarningBarcode-Daten länger als jede Symbologie fassen kann
ZPL1101Warning^GF größer als das Etikett oder MaxGraphicBytes
ZPL1102Warning^GF-Daten nicht dekodierbar
ZPL1103Warning^XG/^IM verweist auf nicht gespeicherte Grafik
ZPL1201Warning^A@-Schrift nicht gefunden – Schrift A wird verwendet, wie am Zebra
ZPL1301WarningFieldValues-Schlüssel ohne passendes ^FN (INVALID_FIELD_VALUE_KEY)
ZPL2001InfoAkzeptiert, 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);
});