Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are some more bugs in this code.</p> <p>Here is test for it:</p> <pre><code>program PunyCodeTest; uses Vcl.Dialogs, SysUtils, PunyCode in '..\SRC\PunyCode.pas'; type TCodecTestRec = record Decoded: AnsiString; Encoded: AnsiString; end; TDomainTestRec = record Decoded: WideString; Encoded: AnsiString; end; const CodecTestCases: array [0..19] of TCodecTestRec = ( // My samples // ---------- // 蒙古火锅-test (Decoded: 'u+8499 u+53E4 u+706B u+9505 u+002D u+0074 u+0065 u+0073 u+0074'; Encoded: '-test-xt8h571o0z7ad54a'), // RFC 3492 - 7.1 Sample strings // ----------------------------- // (A) Arabic (Egyptian): (Decoded: 'u+0644 u+064A u+0647 u+0645 u+0627 u+0628 u+062A u+0643 u+0644 '+ 'u+0645 u+0648 u+0634 u+0639 u+0631 u+0628 u+064A u+061F'; Encoded: 'egbpdaj6bu4bxfgehfvwxn'), //(B) Chinese (simplified): (Decoded: 'u+4ED6 u+4EEC u+4E3A u+4EC0 u+4E48 u+4E0D u+8BF4 u+4E2D u+6587'; Encoded: 'ihqwcrb4cv8a8dqg056pqjye'), // (C) Chinese (traditional): (Decoded: 'u+4ED6 u+5011 u+7232 u+4EC0 u+9EBD u+4E0D u+8AAA u+4E2D u+6587'; Encoded: 'ihqwctvzc91f659drss3x8bo0yb'), // (D) Czech: Pro&lt;ccaron&gt;prost&lt;ecaron&gt;nemluv&lt;iacute&gt;&lt;ccaron&gt;esky (Decoded: 'U+0050 u+0072 u+006F u+010D u+0070 u+0072 u+006F u+0073 u+0074 '+ 'u+011B u+006E u+0065 u+006D u+006C u+0075 u+0076 u+00ED u+010D u+0065 '+ 'u+0073 u+006B u+0079'; Encoded: 'Proprostnemluvesky-uyb24dma41a'), // (E) Hebrew: (Decoded: 'u+05DC u+05DE u+05D4 u+05D4 u+05DD u+05E4 u+05E9 u+05D5 u+05D8 '+ 'u+05DC u+05D0 u+05DE u+05D3 u+05D1 u+05E8 u+05D9 u+05DD u+05E2 u+05D1 '+ 'u+05E8 u+05D9 u+05EA'; Encoded: '4dbcagdahymbxekheh6e0a7fei0b'), // (F) Hindi (Devanagari): (Decoded: 'u+092F u+0939 u+0932 u+094B u+0917 u+0939 u+093F u+0928 u+094D '+ 'u+0926 u+0940 u+0915 u+094D u+092F u+094B u+0902 u+0928 u+0939 u+0940 '+ 'u+0902 u+092C u+094B u+0932 u+0938 u+0915 u+0924 u+0947 u+0939 u+0948 '+ 'u+0902'; Encoded: 'i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd'), // (G) Japanese (kanji and hiragana): (Decoded: 'u+306A u+305C u+307F u+3093 u+306A u+65E5 u+672C u+8A9E u+3092 '+ 'u+8A71 u+3057 u+3066 u+304F u+308C u+306A u+3044 u+306E u+304B'; Encoded: 'n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa'), // (H) Korean (Hangul syllables): (Decoded: 'u+C138 u+ACC4 u+C758 u+BAA8 u+B4E0 u+C0AC u+B78C u+B4E4 u+C774 '+ 'u+D55C u+AD6D u+C5B4 u+B97C u+C774 u+D574 u+D55C u+B2E4 u+BA74 u+C5BC '+ 'u+B9C8 u+B098 u+C88B u+C744 u+AE4C'; Encoded: '989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c'), // (I) Russian (Cyrillic): (Decoded: 'U+043F u+043E u+0447 u+0435 u+043C u+0443 u+0436 u+0435 u+043E '+ 'u+043D u+0438 u+043D u+0435 u+0433 u+043E u+0432 u+043E u+0440 u+044F '+ 'u+0442 u+043F u+043E u+0440 u+0443 u+0441 u+0441 u+043A u+0438'; Encoded: 'b1abfaaepdrnnbgefbaDotcwatmq2g4l'), // (J) Spanish: Porqu&lt;eacute&gt;nopuedensimplementehablarenEspa&lt;ntilde&gt;ol (Decoded: 'U+0050 u+006F u+0072 u+0071 u+0075 u+00E9 u+006E u+006F u+0070 '+ 'u+0075 u+0065 u+0064 u+0065 u+006E u+0073 u+0069 u+006D u+0070 u+006C '+ 'u+0065 u+006D u+0065 u+006E u+0074 u+0065 u+0068 u+0061 u+0062 u+006C '+ 'u+0061 u+0072 u+0065 u+006E U+0045 u+0073 u+0070 u+0061 u+00F1 u+006F '+ 'u+006C'; Encoded: 'PorqunopuedensimplementehablarenEspaol-fmd56a'), // (K) Vietnamese: // T&lt;adotbelow&gt;isaoh&lt;odotbelow&gt;kh&lt;ocirc&gt;ngth&lt;ecirchookabove&gt;ch\ // &lt;ihookabove&gt;n&lt;oacute&gt;iti&lt;ecircacute&gt;ngVi&lt;ecircdotbelow&gt;t (Decoded: 'U+0054 u+1EA1 u+0069 u+0073 u+0061 u+006F u+0068 u+1ECD u+006B '+ 'u+0068 u+00F4 u+006E u+0067 u+0074 u+0068 u+1EC3 u+0063 u+0068 u+1EC9 '+ 'u+006E u+00F3 u+0069 u+0074 u+0069 u+1EBF u+006E u+0067 U+0056 u+0069 '+ 'u+1EC7 u+0074'; Encoded: 'TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g'), // (L) 3&lt;nen&gt;B&lt;gumi&gt;&lt;kinpachi&gt;&lt;sensei&gt; (Decoded: 'u+0033 u+5E74 U+0042 u+7D44 u+91D1 u+516B u+5148 u+751F'; Encoded: '3B-ww4c5e180e575a65lsy2b'), // (M) &lt;amuro&gt;&lt;namie&gt;-with-SUPER-MONKEYS (Decoded: 'u+5B89 u+5BA4 u+5948 u+7F8E u+6075 u+002D u+0077 u+0069 u+0074 '+ 'u+0068 u+002D U+0053 U+0055 U+0050 U+0045 U+0052 u+002D U+004D U+004F '+ 'U+004E U+004B U+0045 U+0059 U+0053'; Encoded: '-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n'), // (N) Hello-Another-Way-&lt;sorezore&gt;&lt;no&gt;&lt;basho&gt; (Decoded: 'U+0048 u+0065 u+006C u+006C u+006F u+002D U+0041 u+006E u+006F '+ 'u+0074 u+0068 u+0065 u+0072 u+002D U+0057 u+0061 u+0079 u+002D u+305D '+ 'u+308C u+305E u+308C u+306E u+5834 u+6240'; Encoded: 'Hello-Another-Way--fc4qua05auwb3674vfr0b'), // (O) &lt;hitotsu&gt;&lt;yane&gt;&lt;no&gt;&lt;shita&gt;2 (Decoded: 'u+3072 u+3068 u+3064 u+5C4B u+6839 u+306E u+4E0B u+0032'; Encoded: '2-u9tlzr9756bt3uc0v'), // (P) Maji&lt;de&gt;Koi&lt;suru&gt;5&lt;byou&gt;&lt;mae&gt; (Decoded: 'U+004D u+0061 u+006A u+0069 u+3067 U+004B u+006F u+0069 u+3059 '+ 'u+308B u+0035 u+79D2 u+524D'; Encoded: 'MajiKoi5-783gue6qz075azm5e'), // (Q) &lt;pafii&gt;de&lt;runba&gt; (Decoded: 'u+30D1 u+30D5 u+30A3 u+30FC u+0064 u+0065 u+30EB u+30F3 u+30D0'; Encoded: 'de-jg4avhby1noc0d'), // (R) &lt;sono&gt;&lt;supiido&gt;&lt;de&gt; (Decoded: 'u+305D u+306E u+30B9 u+30D4 u+30FC u+30C9 u+3067'; Encoded: 'd9juau41awczczp'), // (S) -&gt; $1.00 &lt;- (Decoded: 'u+002D u+003E u+0020 u+0024 u+0031 u+002E u+0030 u+0030 u+0020 '+ 'u+003C u+002D'; Encoded: '-&gt; $1.00 &lt;--') ); DomainTestCases: array [0..2] of TDomainTestRec = ( (Decoded: '蒙古火锅-test.cn'; Encoded: 'xn---test-xt8h571o0z7ad54a.cn'), (Decoded: 'президент.рф'; Encoded: 'xn--d1abbgf6aiiy.xn--p1ai'), (Decoded: 'почта.мд'; Encoded: 'xn--80a1acny.xn--d1ap') ); const UnicodeMaxLength = 256; AceMaxLength = 256; function ExtractCodePoint(S: AnsiString; var Off: Integer; out caseflag: Byte; out codept: TPunyCode): Boolean; procedure InvalidInput; begin raise EAssertionFailed.Create('Invalid input'); end; begin Result := False; if Off &gt; Length(S) then Exit; if Off+5 &gt; Length(S) then InvalidInput; if S[Off] = 'u' then caseflag := 0 else if S[Off] = 'U' then caseflag := 1 else InvalidInput; Inc(Off); if S[Off] &lt;&gt; '+' then InvalidInput; Inc(Off); codept := StrToInt('$'+Copy(S, Off, 4)); Inc(Off, 4); if (Off &lt;= Length(S)) and (S[Off] &lt;&gt; ' ') then InvalidInput; Inc(Off); Result := True; end; procedure TestEncoder(Decoded, Encoded: AnsiString); var inlen, outlen: Cardinal; caseflags: array [0..UnicodeMaxLength-1] of Byte; input: array [0..UnicodeMaxLength-1] of TPunyCode; output: array [0..AceMaxLength-1] of Byte; Off: Integer; caseflag: Byte; codept: TPunyCode; begin inlen := 0; Off := 1; while ExtractCodePoint(Decoded, Off, caseflag, codept) do begin caseflags[inlen] := caseflag; input[inlen] := codept; Inc(inlen); end; outlen := AceMaxLength; if (PunycodeEncode(inlen, @input, outlen, @output, @caseflags) &lt;&gt; pcSuccess) or (outlen &lt;&gt; Cardinal(Length(Encoded))) or not CompareMem(@output, @Encoded[1], outlen) then raise EAssertionFailed.CreateFmt('Encoding failed: %s', [Decoded]); end; function MakeDecoded(outlen: Cardinal; output: PPunycode; caseflags: PByte): AnsiString; var _caseflags: PByteArray absolute caseflags; I: Integer; S: AnsiString; begin Result := ''; for I := 0 to outlen - 1 do begin if _caseflags[I] = 0 then S := 'u+' else S := 'U+'; S := S + IntToHex(output[I], 4); if Result = '' then Result := S else Result := Result + ' ' + S; end; end; procedure TestDecoder(Decoded, Encoded: AnsiString); var inlen, outlen: Cardinal; caseflags: array [0..UnicodeMaxLength-1] of Byte; output: array [0..UnicodeMaxLength-1] of TPunyCode; begin inlen := Length(Encoded); if inlen &gt; AceMaxLength then raise EAssertionFailed.CreateFmt('Input is too big: %s', [Encoded]); outlen := UnicodeMaxLength; if (PunycodeDecode(inlen, PByte(@Encoded[1]), outlen, @output, @caseflags) &lt;&gt; pcSuccess) or (MakeDecoded(outlen, @output, @caseflags) &lt;&gt; Decoded) then raise EAssertionFailed.CreateFmt('Decoding failed: %s', [Encoded]); end; procedure TestCodec(Decoded, Encoded: AnsiString); begin TestEncoder(Decoded, Encoded); TestDecoder(Decoded, Encoded); end; procedure TestCodecTestCases; var I: Integer; begin for I := 0 to High(CodecTestCases) do TestCodec(CodecTestCases[I].Decoded, CodecTestCases[I].Encoded); end; procedure TestDomain(Decoded: WideString; Encoded: AnsiString); begin if PunycodeEncodeDomain(Decoded) &lt;&gt; Encoded then raise EAssertionFailed.CreateFmt('Encoding failed: %s', [Decoded]); if PunycodeDecodeDomain(Encoded) &lt;&gt; Decoded then raise EAssertionFailed.CreateFmt('Decoding failed: %s', [Encoded]); end; procedure TestDomainTestCases; var I: Integer; begin for I := 0 to High(DomainTestCases) do TestDomain(DomainTestCases[I].Decoded, DomainTestCases[I].Encoded); end; begin TestCodecTestCases; TestDomainTestCases; MessageDlg('Punycode was successfully tested', mtInformation, [mbOK], 0); end. </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload