Inhaltsverzeichnis

std.edi.partner

Handelspartner-Profile für AS2- und SFTP-Transportkanäle. Die Unit ist ein Metadaten-Registry — kein Netzwerktreiber. Sie definiert, wie Nachrichten an einen Partner übertragen werden (Protokoll, Host, Pfad, vereinbarte Nachrichtentypen, Sicherheitsoptionen).

Das Wire-Format ist Pipe-delimitierter Text (eine Zeile pro Partner):

protocol|partnerID|ourID|host|port|path|msgTypes|options
AS2|ACME-GmbH|MINE-Corp|as2.acme.com|4080|/as2|ORDERS,INVOIC|0
SFTP|ACME-FTP|MINE-Corp|sftp.acme.com|22|/edi/in|REMADV,ORDERS|1

import std.edi.partner;
import std.alloc;
import std.string;

fn Feld(p: int64, l: int64): pchar {
    var b: int64 := alloc(l + 1);
    var i: int64 := 0;
    while (i < l) { poke8(b + i, peek8(p + i)); i := i + 1; }
    poke8(b + l, 0);
    return b as pchar;
}

fn main(): int64 {
    var p: int64 := alloc(EDI_PART_SIZE);
    var i: int64 := 0;
    while (i < EDI_PART_SIZE) { poke8(p + i, 0); i := i + 1; }

    poke64(p + EDI_PART_PROTOCOL,   EDI_PART_PROTO_AS2);
    poke64(p + EDI_PART_PARTNERID,  "PARTNER-AS2-ID"c as int64);
    poke64(p + EDI_PART_PARTNERLEN, 14);
    poke64(p + EDI_PART_OURID,      "MEINE-AS2-ID"c as int64);
    poke64(p + EDI_PART_OURIDLEN,   12);
    poke64(p + EDI_PART_HOST,       "edi.partner.example"c as int64);
    poke64(p + EDI_PART_HOSTLEN,    19);
    poke64(p + EDI_PART_PORT,       443);
    poke64(p + EDI_PART_PATH,       "/as2/inbound"c as int64);
    poke64(p + EDI_PART_PATHLEN,    12);
    poke64(p + EDI_PART_MSGTYPES,   EDI_PART_MSG_ORDERS + EDI_PART_MSG_INVOIC + EDI_PART_MSG_DESADV);
    poke64(p + EDI_PART_OPTIONS,    EDI_PART_OPT_SIGN + EDI_PART_OPT_ENCRYPT);

    PrintLn(StrConcat("gueltig: ", IntToStr(EdiPartnerValidate(p))));

    var out: int64 := alloc(1024);
    var n: int64 := EdiPartnerWrite(p, out, 1024);
    Print(Feld(out, n));            // Zeile endet bereits mit \n

    // Zeile wieder einlesen
    var p2: int64 := alloc(EDI_PART_SIZE);
    if (EdiPartnerRead(out, n, p2) == 1) {
        PrintLn(StrConcat("Host: ", Feld(peek64(p2 + EDI_PART_HOST), peek64(p2 + EDI_PART_HOSTLEN))));
        PrintLn(StrConcat("Port: ", IntToStr(peek64(p2 + EDI_PART_PORT))));
        PrintLn(StrConcat("ORDERS erlaubt: ", IntToStr(EdiPartnerSupports(p2, EDI_PART_MSG_ORDERS))));
        PrintLn(StrConcat("CUSTOMS erlaubt: ", IntToStr(EdiPartnerSupports(p2, EDI_PART_MSG_CUSTOMS))));
    }

    // Registry: mehrere Zeilen, Suche nach Partner-ID
    var parts: int64 := alloc(4 * EDI_PART_SIZE);
    var cnt: int64 := EdiPartnerListRead(out, n, parts, 4);
    // EdiPartnerFind liefert einen ZEIGER auf den Datensatz, keinen Index - 0 = nicht gefunden
    var rec: int64 := EdiPartnerFind(parts, cnt, "PARTNER-AS2-ID"c, 14);
    if (rec != 0) {
        PrintLn(StrConcat("Registry-Eintraege: ", IntToStr(cnt)));
        PrintLn(StrConcat("Pfad des Treffers: ", Feld(peek64(rec + EDI_PART_PATH), peek64(rec + EDI_PART_PATHLEN))));
    } else {
        PrintLn("Partner nicht gefunden");
    }
    return 0;
}

gueltig: 1
AS2|PARTNER-AS2-ID|MEINE-AS2-ID|edi.partner.example|443|/as2/inbound|ORDERS,INVOIC,DESADV|3
Host: edi.partner.example
Port: 443
ORDERS erlaubt: 1
CUSTOMS erlaubt: 0
Registry-Eintraege: 1
Pfad des Treffers: /as2/inbound

Das Speicherformat ist eine pipe-getrennte Zeile je Partner: Protokoll, Partner-ID, eigene ID, Host, Port, Pfad, Nachrichtentypen (Klartext, kommagetrennt), Optionen als Zahl. Eine Registry ist damit eine gewöhnliche Textdatei, die sich von Hand pflegen lässt.

import std.edi.partner;

// Partner definieren
var partner: int64 := alloc(EDI_PART_SIZE);
poke64(partner + EDI_PART_PROTOCOL,   EDI_PART_PROTO_AS2);
poke64(partner + EDI_PART_PARTNERID,  "ACME-GmbH" as int64);
poke64(partner + EDI_PART_PARTNERLEN, 9);
poke64(partner + EDI_PART_OURID,      "MINE-Corp" as int64);
poke64(partner + EDI_PART_OURIDLEN,   9);
poke64(partner + EDI_PART_HOST,       "as2.acme.com" as int64);
poke64(partner + EDI_PART_HOSTLEN,    12);
poke64(partner + EDI_PART_PORT,       4080);
poke64(partner + EDI_PART_MSGTYPES,   EDI_PART_MSG_ORDERS + EDI_PART_MSG_INVOIC);
poke64(partner + EDI_PART_OPTIONS,    EDI_PART_OPT_SIGN + EDI_PART_OPT_MDN_SYNC);

// Prüfen ob Partner INVOIC unterstützt
if (EdiPartnerSupports(partner, EDI_PART_MSG_INVOIC) == 1) {
    PrintLn("INVOIC wird unterstützt");
}

free(partner, EDI_PART_SIZE);


Imports


Konstanten

Transport-Protokolle

Konstante Wert Bedeutung
EDI_PART_PROTO_AS2 1 AS2-Transport (HTTPS + MDN)
EDI_PART_PROTO_SFTP 2 SFTP-Transport

Nachrichtentypen (Bit-Maske)

Konstante Bit Nachrichtentyp
EDI_PART_MSG_ORDERS 1 Bestellungen (ORDERS/ORDRSP/ORDCHG)
EDI_PART_MSG_INVOIC 2 Rechnungen (INVOIC)
EDI_PART_MSG_DESADV 4 Lieferschein/Wareneingang (DESADV/RECADV)
EDI_PART_MSG_REMADV 8 Zahlungsavis (REMADV)
EDI_PART_MSG_ORDERS_RSP 16 Auftragsbestätigungen
EDI_PART_MSG_TRANSPORT 32 Transportnachrichten (IFTMIN etc.)
EDI_PART_MSG_CUSTOMS 64 Zollnachrichten (CUSCAR etc.)
EDI_PART_MSG_SEAFREIGHT 128 Seefrachtdaten (BAPLIE etc.)

AS2-Optionen (Bit-Maske)

Konstante Bit Bedeutung
EDI_PART_OPT_SIGN 1 Ausgehende Nachrichten signieren
EDI_PART_OPT_ENCRYPT 2 Ausgehende Nachrichten verschlüsseln
EDI_PART_OPT_MDN_SYNC 4 Synchrones MDN (Message Disposition Notification) anfordern
EDI_PART_OPT_COMPRESS 8 Payload komprimieren

Struct

EdiPartner (EDI_PART_SIZE = 96 Bytes)

Offset-Konstante Inhalt
EDI_PART_PROTOCOL Transportprotokoll (EDI_PART_PROTO_*)
EDI_PART_PARTNERID / EDI_PART_PARTNERLEN Partner-ID (AS2-ID oder SFTP-User)
EDI_PART_OURID / EDI_PART_OURIDLEN Eigene ID beim Partner
EDI_PART_HOST / EDI_PART_HOSTLEN Hostname
EDI_PART_PORT TCP-Port (AS2: typisch 4080, SFTP: 22)
EDI_PART_PATH / EDI_PART_PATHLEN URL-Pfad (AS2) oder SFTP-Verzeichnis
EDI_PART_MSGTYPES Bit-Maske der vereinbarten Nachrichtentypen
EDI_PART_OPTIONS Bit-Maske der AS2-Optionen

Funktionen

Signatur Beschreibung
EdiPartnerValidate(partner: int64): int64 Prüft Pflichtfelder (Protokoll, Partner-ID, Host). Gibt 0=ok, 1=Fehler.
EdiPartnerSupports(partner: int64, msgType: int64): int64 Prüft ob ein Nachrichtentyp-Bit gesetzt ist. Gibt 1=ja, 0=nein.
EdiPartnerWrite(partner: int64, out: int64, outMax: int64): int64 Serialisiert einen Partner als Pipe-delimited-Zeile. Gibt geschriebene Bytes zurück.
EdiPartnerRead(buf: int64, bufLen: int64, partner: int64): int64 Deserialisiert eine Partner-Zeile. Gibt 0=ok.
EdiPartnerListWrite(partners: int64, count: int64, out: int64, outMax: int64): int64 Schreibt mehrere Partner-Profile (eine Zeile pro Partner).
EdiPartnerListRead(buf: int64, bufLen: int64, partners: int64, maxCount: int64): int64 Liest mehrzeilige Partner-Datei; gibt Anzahl der gelesenen Profile.
EdiPartnerFind(partners: int64, count: int64, partnerID: int64, idLen: int64): int64 Sucht Partner-ID im Array; gibt Zeiger auf gefundenen EdiPartner oder 0.

Hinweise


Quelldatei

Unit Datei
std.edi.partner std/edi/partner.lyx

Letzte Aktualisierung: 2026-08-13 — Beispiel lauffähig gemacht und ausgeführt (lyxc 1.0.17K), Zeilenformat der Registry dokumentiert, EdiPartnerFind als Zeiger-Rückgabe klargestellt

Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die pub fn-Signaturen in aurum/std gehalten, 0 Abweichungen).