Appendix A. Implementation Hints (Implementierungshinweise)
Die normativen Abschnitte zur Expansion beschreiben jeden Operator mit einem separaten Expansionsprozess zur deskriptiven Klarheit. In tatsächlichen Implementierungen erwarten wir, dass die Ausdrücke von links nach rechts unter Verwendung eines gemeinsamen Algorithmus verarbeitet werden, der nur geringe Prozessvariationen pro Operator aufweist. Dieser nicht-normative Anhang beschreibt einen solchen Algorithmus.
Initialisieren Sie eine leere Ergebniszeichenkette und ihren Nicht-Fehlerzustand.
Scannen Sie die Vorlage und kopieren Sie Literale in die Ergebniszeichenkette (wie in Abschnitt 3.1), bis ein Ausdruck durch ein "{" angezeigt wird, ein Fehler durch das Vorhandensein eines Nicht-Literal-Zeichens außer "{" angezeigt wird oder die Vorlage endet. Wenn sie endet, geben Sie die Ergebniszeichenkette und ihren aktuellen Fehler- oder Nicht-Fehlerzustand zurück.
- Wenn ein Ausdruck gefunden wird, scannen Sie die Vorlage bis zum nächsten
"}"und extrahieren Sie die Zeichen zwischen den Klammern. - Wenn die Vorlage vor einem
"}"endet, hängen Sie dann das"{"und die extrahierten Zeichen an die Ergebniszeichenkette an und kehren mit einem Fehlerstatus zurück, der anzeigt, dass der Ausdruck fehlerhaft ist.
Untersuchen Sie das erste Zeichen des extrahierten Ausdrucks auf einen Operator.
- Wenn der Ausdruck endete (d.h. ist ""), ein unbekannter oder nicht implementierter Operator gefunden wird oder das Zeichen nicht im varchar-Satz ist (Abschnitt 2.3), dann hängen Sie
"{", den extrahierten Ausdruck und"}"an die Ergebniszeichenkette an, merken Sie sich, dass das Ergebnis in einem Fehlerzustand ist, und kehren dann zum Scannen des Rests der Vorlage zurück. - Wenn ein bekannter und implementierter Operator gefunden wird, speichern Sie den Operator und springen zum nächsten Zeichen, um die varspec-Liste zu beginnen.
- Andernfalls speichern Sie den Operator als NUL (einfache Zeichenkettenexpansion).
Verwenden Sie die folgende Wertetabelle, um das Verarbeitungsverhalten nach Ausdruckstyp-Operator zu bestimmen. Der Eintrag für "first" ist die Zeichenkette, die zuerst an das Ergebnis angehängt werden soll, wenn eine der Variablen des Ausdrucks definiert ist. Der Eintrag für "sep" ist das Trennzeichen, das vor jeder zweiten (oder nachfolgenden) definierten Variablenexpansion an das Ergebnis angehängt werden soll. Der Eintrag für "named" ist ein boolescher Wert dafür, ob die Expansion den Variablen- oder Schlüsselnamen enthält, wenn kein Explode-Modifikator gegeben ist. Der Eintrag für "ifemp" ist eine Zeichenkette, die an den Namen angehängt werden soll, wenn sein entsprechender Wert leer ist. Der Eintrag für "allow" gibt an, welche Zeichen innerhalb der Wertexpansion unkodiert erlaubt sind: (U) bedeutet, dass jedes Zeichen, das nicht im nicht reservierten Satz ist, kodiert wird; (U+R) bedeutet, dass jedes Zeichen, das nicht in der Vereinigung von (unreserved / reserved / pct-encoding) ist, kodiert wird; und für beide Fälle wird jedes nicht erlaubte Zeichen zuerst als seine Oktettsequenz in UTF-8 kodiert und dann wird jedes solche Oktett als prozentkodiertes Triplet kodiert.
┌──────────────────────────────────────────────────────────────┐
│ NUL + . / ; ? & #│
├──────────────────────────────────────────────────────────────┤
│ first │ "" "" "." "/" ";" "?" "&" "#"│
│ sep │ "," "," "." "/" ";" "&" "&" "," │
│ named │ false false false false true true true false│
│ ifemp │ "" "" "" "" "" "=" "=" "" │
│ allow │ U U+R U U U U U U+R │
└──────────────────────────────────────────────────────────────┘
Mit der obigen Tabelle im Hinterkopf verarbeiten Sie die Variablenliste wie folgt:
Für jedes varspec extrahieren Sie einen Variablennamen und optionalen Modifikator aus dem Ausdruck, indem Sie die Variablenliste scannen, bis ein Zeichen gefunden wird, das nicht im varname-Satz ist, oder das Ende des Ausdrucks erreicht wird.
- Wenn es das Ende des Ausdrucks ist und der varname leer ist, kehren Sie zum Scannen des Rests der Vorlage zurück.
- Wenn es nicht das Ende des Ausdrucks ist und das zuletzt gefundene Zeichen einen Modifikator anzeigt ("" oder ":"), merken Sie sich diesen Modifikator. Wenn es ein Explode ("") ist, scannen Sie das nächste Zeichen. Wenn es ein Präfix (":") ist, fahren Sie fort, die nächsten ein bis vier Zeichen für die als Dezimalzahl dargestellte max-length zu scannen, und dann, wenn es immer noch nicht das Ende des Ausdrucks ist, scannen Sie das nächste Zeichen.
- Wenn es nicht das Ende des Ausdrucks ist und das zuletzt gefundene Zeichen kein Komma (",") ist, hängen Sie
"{", den gespeicherten Operator (falls vorhanden), den gescannten varname und Modifikator, den verbleibenden Ausdruck und"}"an die Ergebniszeichenkette an, merken Sie sich, dass das Ergebnis in einem Fehlerzustand ist, und kehren dann zum Scannen des Rests der Vorlage zurück.
Suchen Sie den Wert für den gescannten Variablennamen und dann
- Wenn der varname unbekannt ist oder einer Variable mit einem undefinierten Wert entspricht (Abschnitt 2.3), dann springen Sie zum nächsten varspec.
- Wenn dies die erste definierte Variable für diesen Ausdruck ist, hängen Sie die first-Zeichenkette für diesen Ausdruckstyp an die Ergebniszeichenkette an und merken Sie sich, dass es getan wurde. Andernfalls hängen Sie die sep-Zeichenkette an die Ergebniszeichenkette an.
- Wenn der Wert dieser Variable eine Zeichenkette ist, dann
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- wenn der Wert leer ist, hängen Sie die ifemp-Zeichenkette an die Ergebniszeichenkette an und springen zum nächsten varspec;
- andernfalls hängen Sie "=" an die Ergebniszeichenkette an.
- wenn ein Präfix-Modifikator vorhanden ist und die Präfixlänge kleiner ist als die Wertzeichenkettenlänge in Anzahl von Unicode-Zeichen, hängen Sie diese Anzahl von Zeichen vom Anfang der Wertzeichenkette an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, wobei Sie darauf achten, Mehroktett- oder prozentkodierte Triplettzeichen, die einen einzelnen Unicode-Codepunkt darstellen, nicht zu teilen;
- andernfalls hängen Sie den Wert an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben.
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- andernfalls, wenn kein Explode-Modifikator gegeben ist, dann
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- wenn der Wert leer ist, hängen Sie die ifemp-Zeichenkette an die Ergebniszeichenkette an und springen zum nächsten varspec;
- andernfalls hängen Sie "=" an die Ergebniszeichenkette an; und
- wenn der Wert dieser Variable eine Liste ist, hängen Sie jedes definierte Listenmitglied an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit einem Komma (","), das zwischen jedem definierten Listenmitglied an das Ergebnis angehängt wird;
- wenn der Wert dieser Variable ein assoziatives Array oder eine andere Form einer gepaarten (name, value) Struktur ist, hängen Sie jedes Paar mit einem definierten Wert an die Ergebniszeichenkette als "name,value" an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit einem Komma (","), das zwischen jedem definierten Paar an das Ergebnis angehängt wird.
- wenn named true ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an, und
- andernfalls, wenn ein Explode-Modifikator gegeben ist, dann
- wenn named true ist, dann für jedes definierte Listenmitglied oder Array (name, value) Paar mit einem definierten Wert, tun Sie:
- wenn dies nicht das erste definierte Mitglied/Wert ist, hängen Sie die sep-Zeichenkette an die Ergebniszeichenkette an;
- wenn dies eine Liste ist, hängen Sie den varname an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an;
- wenn dies ein Paar ist, hängen Sie den name an die Ergebniszeichenkette unter Verwendung desselben Kodierungsprozesses wie für Literale an;
- wenn das Mitglied/Wert leer ist, hängen Sie die ifemp-Zeichenkette an die Ergebniszeichenkette an; andernfalls hängen Sie "=" und das Mitglied/Wert an die Ergebniszeichenkette an, nachdem Sie alle Mitglied/Wert-Zeichen, die nicht im allow-Satz sind, prozentkodiert haben.
- andernfalls, wenn named false ist, dann
- wenn dies eine Liste ist, hängen Sie jedes definierte Listenmitglied an die Ergebniszeichenkette an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit der sep-Zeichenkette, die zwischen jedem definierten Listenmitglied an das Ergebnis angehängt wird.
- wenn dies ein Array von (name, value) Paaren ist, hängen Sie jedes Paar mit einem definierten Wert an die Ergebniszeichenkette als "name=value" an, nachdem Sie alle Zeichen, die nicht im allow-Satz sind, prozentkodiert haben, mit der sep-Zeichenkette, die zwischen jedem definierten Paar an das Ergebnis angehängt wird.
- wenn named true ist, dann für jedes definierte Listenmitglied oder Array (name, value) Paar mit einem definierten Wert, tun Sie:
Wenn die Variablenliste für diesen Ausdruck erschöpft ist, kehren Sie zum Scannen des Rests der Vorlage zurück.