Dieses Kapitel behandelt folgende Themen:
In der Natural-Programmiersprache können Sie Unicode-Zeichenketten mit Format U und U-Konstanten angeben.
Format U
Im Format U können Sie Daten definieren, die Unicode-Zeichenketten enthalten. Das
Natural-Datenformat U ist intern UTF-16.
Siehe auch Format und Länge von Benutzervariablen im Leitfaden zur Programmierung.
U-Konstante
Sie können Unicode-Konstanten mit dem Präfix "U"
definieren. Zum Beispiel:
U'Äpfel'
Das Präfix "UH" kann benutzt werden, um Unicode-Konstanten in hexadezimalem Format zu definieren. Vier hexadezimale Ziffern stellen gemäß Unicode Standard eine UTF-16-Codeeinheit (Code Unit) dar. Daher muss die Gesamtlänge ein Vielfaches von Vier sein. Angenommen, Sie benötigen die hexadezimale Form von
U'Äpfel'
dann brauchen Sie die UTF-16-Codeeinheiten für "Ä", "p", "f", "e" und "l" (die sind "U+00C4", "U+0070", "U+0066", "U+0065" und "U+006C") und Sie müssen sie zu folgender hexadezimalen Zeichenkette zusammenfügen:
UH'00C4007000660065006C'
Siehe auch Unicode-Konstanten im Leitfaden zur Programmierung.
Das Datenformat U ist Endian-abhängig. Dies ist beim Übertragen (MOVE)
zwischen den Formaten B und U zu berücksichtigen.
Der Vorteil des Formats U (im Vergleich zum Format A) liegt darin, dass es beliebige
Zusammenfügungen von Zeichen aus verschiedenen Sprachen enthalten kann und dass es nicht
von der Standard-Codepage (Wert der Systemvariablen *CODEPAGE)
abhängig ist. Darüber hinaus vereinfacht das Format U den Austausch von Daten zwischen
unterschiedlichen Plattformen. Es sind keine Umwandlungen (z.B. von EBCDIC nach ASCII)
nötig.
Andererseits wird für Daten im Format U mehr Speicherplatz als bei Daten im Format verbraucht. Bei Sprachen, die in Einzel-Byte-Zeichencodierung dargestellt werden können, führt das Format U dazu, dass Zeichenketten doppelt so viel Platz belegen, wie früher erforderlich war. Bei ostasiatischen Sprachen dagegen ist der Speicherplatzverbrauch oft nicht größer.
Grundsätzlich gilt, dass das Format U in den meisten Statements benutzt werden kann, die
das Format A erlauben. Wenn aber ein Natural-Objektname als Operand eines Statements
gegeben ist (z.B. im CALLNAT-Statement), dann kann das Format U nicht benutzt werden,
weil Natural-Objekte das Format A haben. Informationen zu bestimmten Statements können Sie
der Statements-Dokumentation entnehmen.
Grundsätzlich können die Formate A und U zusammen in einem Statement benutzt werden, z.B.:
EXAMINE S FOR P WITH DELIMITER D REPLACE R
dabei ist S im Format U und P,
D und R sind im Format A.
Im obigen Beispiel werden die Variablen P,
D und R vor der tatsächlichen
Ausführung des EXAMINE-Statements temporär in das Zielformat U umgewandelt. Die
Umwandlung von Unicode nach Codepage oder umgekehrt erfordert den Aufruf einer
ICU-Funktion. Diese Umwandlung beansprucht zusätzliche Rechenzeit und zusätzlichen
Speicherplatz. Dieser Nachteil wird bei sehr großen Variablen noch größer. Um häufige
Umwandlungen zu vermeiden, wird deshalb empfohlen, innerhalb eines Statements nur ein
Format zu benutzen. Wenn alle Operanden im obigen Beispiel entweder im Format U oder im
Format A angegeben werden, entfällt die Notwendigkeit einer Umwandlung. Wenn Sie sich
jedoch dafür entscheiden, nur Operanden im Format U anzugeben, dann ist diese Variante
(artbedingt) langsamer, weil dieser Operandentyp mehr Ressourcen verbraucht. Ein Zeichen
wird dann mit 2 Bytes kodiert (anstelle von 1 Byte, das für das Format A benutzt
wird).
Bei einer Umwandlung (insbesondere vom Format U ins Format A) besteht immer das Risiko,
dass Zeichen nicht in der Ziel-Codepage dargestellt werden können. Angenommen Sie wollen
das Unicode-Zeichen "U+05D0" (hebräischer Buchstabe Alef) in
die Codepage IBM01140 (Englisch) umwandeln. Da dieses Zeichen in der Codepage IBM01140
nicht enthalten ist, wird entweder das Ersatzzeichen für diese Codepage benutzt oder der
Platzhalter, der bei der Definition der Codepage im Modul NATCONFG angegeben worden ist. Wenn der Profilparameter
CPCVERR auf
ON gesetzt ist, wird in diesem Fall eine Fehlermeldung ausgegeben, die
einen Umwandlungsfehler anzeigt. Die ursprüngliche Information geht auf jeden Fall
verloren.
Bei der Benutzung von Unicode sind insbesondere die folgenden Statements betroffen:
Normalisierung in Unicode: Ein Vorgang zum Entfernen alternativer Darstellungen von äquivalenten Zeichenfolgen aus Textdaten, um die Daten in eine Form umzuwandeln, die binär auf Äquivalenz verglichen werden kann. Im Unicode Standard sind verschiedene Normalisierungsformen definiert. Die Normalisierungsform, die sich bei der kanonischen Zerlegung einer Unicode-Zeichenkette ergibt, und die im Anschluss daran (wo möglich) erfolgende Ersetzung aller zerlegten Zeichenfolgen durch Primärkompositen wird "Normalization Form Composed" (NFC) genannt.
Natural nimmt an, dass alle Unicode-Daten im NFC-Format sind, um sicherzugehen, dass
String-Operationen ohne teilweise Trunkierung eines Unicode-Zeichens durchgeführt werden
können. Bei den Umwandlungsoperationen in Natural wird sichergestellt, dass die
resultierenden Unicode-Zeichenkette in NFC ist. Wenn Unicode-Daten von Außerhalb von
Natural empfangen werden und wenn nicht gewährleistet ist, dass die Daten NFC-Format
haben, kann das Natural-Statement MOVE
NORMALIZED angewendet werden.
Beispiel:
| Zeichenfolge | NFC |
|---|---|
| ê (U+00EA) | ê (U+00EA) |
| e (U+0065) + ^ (U+0302) | ê (U+00EA) |
Anmerkung
Wenn zwei oder mehr Zeichenketten im NFC-Format verkettet werden, kann es sein, dass
das Resultat nicht im NFC-Format ist.
Eine implizite Umwandlung zwischen Unicode und der Standard-Codepage (Wert der
Systemvariablen *CODEPAGE) wird durchgeführt, wenn
Zeichenketten mittels MOVE-Statement von Format U nach Format A oder umgekehrt
übertragen werden.
Weiterhin kann das MOVE
ENCODED-Statement zur Umwandlung zwischen verschiedenen Codepages
oder von einer beliebigen verfügbaren Codepage nach Unicode und umgekehrt benutzt
werden. Dies kann hilfreich sein, wenn Daten von Außerhalb von Natural kommen und wenn
diese Daten in einer Codepage, die ungleich zur Standard-Codepage ist, kodiert sind.
Aber Sie können dieses Statement sogar zur Umwandlung zwischen der Standard-Codepage und
Unicode benutzen, wenn Sie einen potenziellen Umwandlungsfehler mit der
GIVING-Klausel erhalten wollen; wenn CPCVERR auf ON gesetzt ist, wird in
diesem Fall das MOVE-Statement mit einem Laufzeitfehler stoppen.
Falls ein Zeichen nicht umgesetzt werden kann, hängt es von der Einstellung des
CPCVERR-Parameters ab, ob ein Ersatzzeichen für dieses Zeichen
benutzt wird oder ob die Umwandlung fehlschlägt.
Dieses Statement kann außerdem von U-Daten in das UTF-8-Format benutzt werden.
Anmerkung
Wenn Sie Daten in eine Codepage umwandeln, die ungleich der Standard-Codepage ist,
wird empfohlen, diese Daten nicht bei Ein- und Ausgaben zu benutzen. Ein- und Ausgaben
sind nur in der Standard-Codepage sinnvoll.
Ein "Graphem" ist das, was sich ein Benutzer normalerweise unter einem Zeichen vorstellt. In den meisten Fällen ist ein Unicode-Codepoint ein Graphem, aber ein Graphem kann auch aus mehreren Unicode-Codepoints bestehen.Zum Beispiel ist eine Folge von einem Basiszeichen und einem oder mehreren Kombinationszeichen ein Graphem.
Beispiel: "a" (U+0061) + "." (U+0323) + "^" (U+0302) definiert ein Graphem, das wie folgt angezeigt wird:
![]()
Anmerkung
Wenn eine Basis-/Kombinationszeichenfolge normalisiert wird, bedeutet dies nicht,
dass die Folge immer durch ein zusammengesetzes (precomposed) Zeichen ersetzt wird, da
nicht alle Zeichen im zusammengesetzten Format verfügbar sind.
Ein ergänzender Codepoint ist ein Unicode-Codepoint zwischen "U+10000" und "U+10FFFF". Ein ergänzender Codepoint wird in UTF-16 durch ein Surrogatpaar (Ersatzpaar) dargestellt, das aus zwei Codeeinheiten besteht, wobei der erste Wert des Paares eine "high-surrogate code unit" und der zweite eine "low-surrogate code unit" ist. Solche Zeichen sind im Allgemeinen selten, aber einige werden z.B. als Teil chinesischer und japanischer Personennamen verwendet, und daher ist die Unterstützung dieser Zeichen häufig für Regierungsanwendungen in ostasisatischen Ländern erforderlich.
Die Statements zur Behandlung von Zeichenketten, z.B. EXAMINE und die Option SUBSTRING arbeiten mit
UTF-16-Codeeinheiten. Es liegt in der Verantwortung des Benutzer, dass der Code keine
Grapheme oder Surrogatpaare trennt.
Die Klauseln CHARPOSITION und CHARLENGTH des
EXAMINE-Statement (siehe Syntax 3 - EXAMINE für
Unicode-Grapheme) können jedoch benutzt werden, um den Anfang
und die Länge (in UTF-16-Codeeinheiten) von Graphemen abzufragen. Die Ergebniswerte
können für SUBSTRING-Aufrufe verwendet werden. Mit diesen Klauseln ist es
möglich, eine Zeichenkette Graphem für Graphem zu durchsuchen.
Beispiel:
DEFINE DATA LOCAL 1 #UNICODE-STRING (U15) 1 #CODE-UNIT-INDEX (N4) 1 #CODE-UNIT-LEN (N4) 1 #GRAPHEME-NUMBER (N4) END-DEFINE MOVE U'' TO #UNICODE-STRING #GRAPHEME-NUMBER := 1 REPEAT EXAMINE FULL VALUE OF #UNICODE-STRING FOR CHARPOSITION #GRAPHEME-NUMBER GIVING POSITION IN #CODE-UNIT-INDEX GIVING LENGTH IN #CODE-UNIT-LEN DISPLAY #UNICODE-STRING #GRAPHEME-NUMBER #CODE-UNIT-INDEX #CODE-UNIT-LEN #GRAPHEME-NUMBER := #GRAPHEME-NUMBER + 1 WHILE #CODE-UNIT-INDEX NE 0 END-REPEAT END
Ausgabe des obigen Programms:
Page 1 05-12-15 09:33:49 #UNICODE-STRING #GRAPHEME-NUMBER #CODE-UNIT-INDEX #CODE-UNIT-LEN --------------- ---------------- ---------------- --------------1 1 1
2 2 2
3 4 1
4 5 3
5 8 1
6 9 3
7 12 1
8 13 3
9 0 0
Das zu parsende Dokument wird immer intern in UTF-8 gewandelt (wenn das Dokument noch nicht in UTF-8 kodiert ist).
Weitere Informationen siehe Beschreibung des Statements PARSE JSON.
Siehe auch Statements für den Internet-Zugriff und Parsing im Leitfaden zur Programmierung.
Das zu parsende Dokument wird immer intern in UTF-16 gewandelt (wenn das Dokument noch nicht in UTF-16 kodiert ist).
Weitere Informationen siehe Beschreibung des Statements PARSE XML.
Siehe auch Statements für den Internet-Zugriff und Parsing im Leitfaden zur Programmierung.
Bei der Übertragung von Daten mit dem REQUEST DOCUMENT-Statement erfolgt
normalerweise keine Codepage-Umwandlung. Wenn Sie wollen, dass die ausgehenden und/oder
eingehenden Daten in einer spezifischen Codepage zeichencodiert sind, können Sie die
Klausel DATA ALL und/oder die Klausel RETURN PAGE des
REQUEST DOCUMENT-Statements benutzen, um dies anzugeben.
Weitere Informationen siehe Beschreibung des Statements REQUEST DOCUMENT.
Siehe auch Statements für den Internet-Zugriff und Parsing im Leitfaden zur Programmierung.
Das DEFINE
PRINTER-Statement stellt eine CODEPAGE-Klausel zur
Verfügung, mit der für die Umwandlung von Druckreportdaten in eine Codepage ungleich der
Standard-Codepage (Wert der Systemvariablen *CODEPAGE gesorgt werden kann.
Der Austausch von Daten in U-Format via RPC wird unterstützt. Siehe Beschreibung des
CALLNAT-Statements.
Wenn Daten im Format U von einer Plattform mit Big-Endian-Zeichencodierung an eine Plattform mit Little-Endian-Zeichencodierung oder umgekehrt gesendet werden, wird die Zeichencodierung so angepasst, dass sie konform zur Zeichencodierung der empfangenden Plattform ist. Wenn zum Beispiel Daten in U-Format in Little-Endian-Zeichencodierung auf einer Plattform mit Big-Endian-Zeichencodierung ankommt, werden die Daten in Big-Endian-Zeichencodierung umgewandelt, bevor sie an das Programm übergeben werden. Wenn diese Daten wieder zurückgesendet werden, dann werden sie wieder in Little-Endian-Zeichencodierung zurückgewandelt.
In einer logischen Bedingung können Unicode-Operanden zusammen mit alphanumerischen und binären Operanden benutzt werden. Wenn nicht alle Operanden Unicode-Operanden (Format U) sind, werden der zweite alle folgenden Operanden in das Format des ersten Operanden umgewandelt. Wenn ein binäre Operand (Format B) als zweiter oder nachfolgender Operand angegeben ist, muss die Länge des Operanden gerade sein. Es wird angenommen, dass der binäre Operand Unicode-Codepoints enthält.
Wenn der erste Operand ein Unicode-Operand ist (Format U) und der Vergleich daher als Unicode-Vergleich durchgeführt wird, wird der Unicode-Algorithmus benutzt. Der ICU-Algorithmus führt keinen einfachen Binärvergleich durch. Zum Beispiel:
einige Codepoints, z.B. "U+0000" werden während des Vergleichsvorgangs ignoriert,
zusammengesetzte Zeichen werden als gleich dem äquivalenten einzelnen Codepunkt angesehen (zum Beispiel der deutsche Buchstabe "ä", der durch "U+00E4" dargestellt wird, und die Kombination der Codepoints "U+0061" und "U+0308" werden von ICU als gleich betrachtet).
Anmerkung
Der Vergleich eines alphanumerischen und einen Unicode-Operanden kann, abhängig von
der Reihenfolge der Felder, unterschiedliche Ergebnisse liefern.
Siehe auch Logische Bedingungen im Leitfaden zur Programmierung.
Die Systemvariable *CODEPAGE gibt den IANA-Namen der
Standard-Codepage zurück, die intern von Natural für Konvertierungen zwischen Unicode-
und Codepage-Formaten benutzt wird.
Die Systemvariable *LOCALE enthält die Sprache und das Land
der aktuellen Locale.
Das Format kann bei großen und dynamischen Variablen benutzt werden. Bei dynamischen
Variablen gibt die Systemvariable *LENGTH die Anzahl der UTF-16-Codeeinheiten
zurück.
Siehe auch Dynamische Variablen im Leitfaden zur Programmierung.
Folgende Session-Parameter stehen zur Verfügung:
| Parameter | Beschreibung |
|---|---|
DL |
Bestimmt die Ausgabelänge eines Felds im Format A oder U. Siehe auch Ausgabelänge — der DL Parameter im Leitfaden zur Programmierung. |
EMU
|
Unicode-Editiermaske. |
ICU
|
Unicode-Einfügungszeichen. |
LCU
|
Vorangestellte Unicode-Zeichen. |
TCU
|
Nachgezogene Zeichen in Unicode. |
Solange wie Natural noch nicht Unicode-fähig war, war die Länge von alphanumerischen Feldern immer identisch mit der Anzahl der Spalten, die zum Anzeigen des Felds benötigt wurden (Anzahl der Anzeigespalten genannt). Das traf auch bei den ostasiatischen Sprachen zu, die DBCS-Codepages benutzen: Ein Feld im Format A kann nur die Hälfte der Zeichen aufnehmen (A10 zum Beispiel resultiert in A5).
Beispiel:
DEFINE DATA LOCAL 1 #A8 (A8) END-DEFINE #A8 := 'computer' WRITE #A8 #A8 := '' WRITE #A8 END
Der oben gezeigte Code ergibt folgende Ausgabe:
Page 1 ... computer
Bei Feldern im Format U ist die Länge eines Felds nicht mehr identisch mit der Anzahl
der Spalten. Zeichen im Format U können eine schmale Länge (z.B. lateinische Zeichen),
eine breite Länge (z.B. chinesische Zeichen) oder keine Länge (z.B. zusammengesetzte
Zeichen) haben. Deshalb ist völlig unbekannt, wie viele Anzeigespalten ein Feld im
Format U benötigt, denn es ist abhängig vom Inhalt des Feldes. Natural kann nicht
automatisch entscheiden, wie viele Spalten im Bildschirm reserviert werden müssen: Wird
die maximale Länge angenommen, dann werden in der lateinischen Zeichenausgabe große
Lücken auftreten. Wird die minimale Länge angenommen, können chinesische Zeichenausgaben
nicht vollständig angezeigt werden. Deshalb muss der Natural-Programmierer die
Anzeigebreite eines Feldes definieren. Dazu dient der DL-Parameter. Der AL-Parameter kann für
diesen Zweck nicht benutzt werden, weil er bewirkt, dass der Teil des Feldes, der die
definierte Feldlänge übersteigt, abgeschnitten wird. Es sollen aber keine Zeichen von
dem U-Format-Feld abgeschnitten werden. Es geht vielmehr darum, die Anfangsposition des
nachfolgenden Feldes zu definieren.
Beispiel:
DEFINE DATA LOCAL 1 #U8 (U8) 1 #U4 (U4) END-DEFINE #U8 := 'computer' WRITE #U8 #U4 := U'' WRITE #U4 (DL=8) END
Der oben gezeigte Code ergibt die gleiche Ausgabe wie oben:
Page 1 ... computer
Auf Windows ist es in einer Remote Development-Umgebung mit dem Natural Web I/O
Interface Client möglich in einem Feld zu blättern, wenn der für den
DL-Parameter angegebene Wert kleiner als die reale
Anzeigebreite des Feldes ist.
Die Parameter EMU, ICU, LCU und TCU ermöglichen es, Zeichen zu verwenden, die
nicht in der Standard-Codepage enthalten sind. Sie werden innerhalb des Programms in
Unicode-Format gespeichert. Diese Parameter können bei allen Feldformaten benutzt
werden.
Die Parameter EM,
IC, LC und TC können ebenfalls bei
U-Format-Feldern benutzt werden. Diese Parameter können außerdem von Nutzen sein, wenn
in der Standard-Codepage enthaltene Zeichen in anderen Codepages abweichende
Zeichencodierungen haben. Das Euro-Zeichen (€) zum Beispiel hat den Codepoint
"0x80" in der Codepage
"windows-1252" (Latin 1), jedoch in der Codepage
"windows-1251" (Cyrillic) den Codepoint
"0x88".
Somit stellt die Benutzung eines Unicode-Parameters (EMU,
ICU, LCU oder
TCU) sicher, dass das Euro-Zeichen immer korrekt angezeigt wird,
egal welche Codepage auf dem PC installiert ist.
Beispiel für EMU:
DEFINE DATA
LOCAL
01 EMPLOYEES-VIEW VIEW OF EMPLOYEES
02 FIRST-NAME
02 NAME
02 SALARY (1)
END-DEFINE
*
READ (6) EMPLOYEES-VIEW
DISPLAY NAME FIRST-NAME SALARY(1) (EMU=999,999
)
END-READ
*
END
Der oben gezeigte Code ergibt folgende Ausgabe:
Page 1 05-12-15 11:45:36
NAME FIRST-NAME ANNUAL
SALARY
-------------------- -------------------- --------
ADAM SIMONE 159,980
MORENO HUMBERTO 165,810
BLOND ALEXANDRE 172,000
MAIZIERE ELISABETH 166,900
CAOUDAL ALBERT 167,350
VERDIE BERNARD 170,100
Die Library SYSEXPG enthält Beispiel-Programme für die Unicode- und
Codepage-Unterstützung in Natural:
| Programm | Beschreibung |
|---|---|
UNICOX01 |
Listet alle Unicode-Zeichen auf. |
UNICOX02 |
Konvertiert Unicode-Zeichen in Codepoints und umgekehrt. |
CODEPX01 |
Listet alle Codepages auf und gibt an, ob die Codepage in Natural unterstützt wird und welche Zeichenkodierung sie verwendet. Bei allen unterstützen Codepages werden Services angeboten, die die Zeichen der Codepage auflisten und mit denen eine Zeichenkette von der Codepage in ihre hexadezimale Darstellung und umgekehrt konvertiert werden kann. |
CODEPXL1 |
Listet alle Zeichen einer beliebigen Ein-Byte-Codepage auf. |
CODEPXL2 |
Listet alle Zeichen einer beliebigen Zwei-Byte-Codepage auf. |
CODEPXC1 |
Konvertiert eine Zeichenkette von einer beliebigen Codepage in ihre hexadezimale Darstellung und umgekehrt. |