Explorar el Código

Use char literals in IDNA mapping.

Simon Sapin hace 10 años
padre
commit
ed30dca0d6
Se han modificado 3 ficheros con 20 adiciones y 20 borrados
  1. 13 8
      make_idna_table.py
  2. 7 12
      src/idna.rs
  3. BIN
      src/idna_mapping.rs

+ 13 - 8
make_idna_table.py

@@ -36,15 +36,15 @@ pub enum MappingStatus {
 }
 
 pub struct Mapping {
-    pub from: u32,
-    pub to: u32,
+    pub from: char,
+    pub to: char,
     pub status: MappingStatus,
-    pub mapping: &'static [u32],
+    pub mapping: &'static [char],
 }
 
 ''')
 
-print("static NONE: [u32;0] = [];")
+print("static NONE: [char;0] = [];")
 
 txt = open("IdnaMappingTable.txt")
 line_no = 0
@@ -58,7 +58,10 @@ for line in txt:
     line_no = line_no + 1
 
 txt = open("IdnaMappingTable.txt")
-print("pub static TABLE: [Mapping; "+str(line_no)+"] = [")
+print("pub static TABLE: &'static [Mapping] = &[")
+
+def char(s):
+    return "'%s'" % unichr(int(s, 16)).replace('\\', '\\\\').replace('\'', '\\\'').encode('utf8')
 
 mappings = []
 
@@ -69,6 +72,8 @@ for line in txt:
     if len(head.strip()) == 0:
         continue
     table_line = head.split(';')
+    if table_line[0].strip() == 'D800..DFFF':
+        continue  # Surrogates don't occur in Rust strings.
     first, sep, last = table_line[0].strip().partition('..')
     if len(last)==0:
         last = first
@@ -78,12 +83,12 @@ for line in txt:
             codes = table_line[2].strip().split(' ')
             newmap = ""
             for code in codes:
-                newmap = newmap + "0x" + code + ", "
+                newmap = newmap + char(code) + ", "
             newmap = "[" + newmap + "]"
             mapping = "MAPPING_%s_%s" % (first, last)
-            static_array = "static %s : [u32; %d] = %s;" % (mapping, len(codes), newmap)
+            static_array = "static %s : [char; %d] = %s;" % (mapping, len(codes), newmap)
             mappings.append(static_array)
-    print "    Mapping{ from: 0x%s, to: 0x%s, status: MappingStatus::%s, mapping: &%s }," % (first, last, table_line[1].strip(), mapping)
+    print "    Mapping{ from: %s, to: %s, status: MappingStatus::%s, mapping: &%s }," % (char(first), char(last), table_line[1].strip(), mapping)
 
 print("];")
 

+ 7 - 12
src/idna.rs

@@ -5,21 +5,17 @@
 use idna_mapping::*;
 use punycode;
 use std::ascii::AsciiExt;
-use std::char;
 use unicode_normalization::UnicodeNormalization;
 
-fn idna_mapped(mapping: &'static [u32]) -> Result<String, Error> {
+fn idna_mapped(mapping: &'static [char]) -> Result<String, Error> {
     let mut ret = "".to_string();
-    for c in mapping {
-        match char::from_u32(*c) {
-            Some(c) => ret.push(c),
-            None => return Err(Error::InvalidCharacterInMapping)
-        }
+    for &c in mapping {
+        ret.push(c)
     }
     return Ok(ret);
 }
 
-fn idna_deviation(codepoint: char, mapping: &'static [u32], transitional: bool) -> Result<String, Error> {
+fn idna_deviation(codepoint: char, mapping: &'static [char], transitional: bool) -> Result<String, Error> {
     if transitional {
        return idna_mapped(mapping);
     }
@@ -33,7 +29,7 @@ fn idna_disallowed_std3_valid(codepoint: char, use_std3_asciirules: bool) -> Res
     return Ok(codepoint.to_string());
 }
 
-fn idna_disallowed_std3_mapped(mapping: &'static [u32], use_std3_asciirules: bool) -> Result<String, Error> {
+fn idna_disallowed_std3_mapped(mapping: &'static [char], use_std3_asciirules: bool) -> Result<String, Error> {
     if use_std3_asciirules {
         return Err(Error::DissallowedMappedInStd3);
     }
@@ -45,9 +41,9 @@ fn map_char(codepoint: char, flags: Uts46Flags) -> Result<String, Error> {
     let mut max = TABLE.len() - 1;
     while max > min {
         let mid = (min + max) >> 1;
-        if (codepoint as u32) > TABLE[mid].to {
+        if codepoint > TABLE[mid].to {
            min = mid;
-        } else if (codepoint as u32) < TABLE[mid].from {
+        } else if codepoint < TABLE[mid].from {
             max = mid;
         } else {
             min = mid;
@@ -82,7 +78,6 @@ pub struct Uts46Flags {
 
 pub enum Error {
     PunycodeEncodingError,
-    InvalidCharacterInMapping,
     DissallowedByStd3AsciiRules,
     DissallowedMappedInStd3,
     DissallowedCharacter,

BIN
src/idna_mapping.rs