Changeset 12919


Ignore:
Timestamp:
03/01/09 13:53:55 (3 years ago)
Author:
sys
Message:

Optimisations algo encode Url

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Jav_FW/com/scenari/s/fw/utils/HUrl.java

    r11069 r12919  
    3939package com.scenari.s.fw.utils; 
    4040 
    41 import java.io.ByteArrayOutputStream; 
    42 import java.io.IOException; 
    43 import java.io.OutputStreamWriter; 
     41import java.io.CharArrayWriter; 
    4442import java.io.UnsupportedEncodingException; 
    4543import java.net.URLDecoder; 
     44import java.net.URLEncoder; 
     45import java.nio.charset.Charset; 
     46import java.nio.charset.IllegalCharsetNameException; 
     47import java.nio.charset.UnsupportedCharsetException; 
    4648import java.util.BitSet; 
    4749 
     
    7577         * Instancie une URL avec ses paramètres "aa/bb/cc?p=v1&pp=v2". 
    7678         */ 
    77         public HUrl(String pUrlAvecParams) throws Exception{ 
     79        public HUrl(String pUrlAvecParams) throws Exception { 
    7880                super(); 
    7981                hInit(pUrlAvecParams); 
     
    162164         *  
    163165         */ 
    164         public void hInit(String pUrlAvecParams) throws Exception{ 
     166        public void hInit(String pUrlAvecParams) throws Exception { 
    165167                if (pUrlAvecParams != null) { 
    166168                        int vOffs = pUrlAvecParams.indexOf('?'); 
     
    185187         * @param pParams java.lang.String 
    186188         */ 
    187         public void hInit(String pUrlSansParams, String pParams) throws Exception{ 
     189        public void hInit(String pUrlSansParams, String pParams) throws Exception { 
    188190                if (pUrlSansParams == null) { 
    189191                        fUrl = ""; 
     
    373375        /** 
    374376         *  
    375          * Encode tous les caractères sauf les "/" et ":". Les espaces sont transformés 
     377         * Encode tous les caractères sauf les "/" et ":".  
     378         * Correposnd à encodeURI() en JS. 
     379         * Les espaces sont transformés 
    376380         * en "%20" et non en "+". (le client webdav Windows ne gère pas le +). 
    377381         */ 
    378         public static String hEncode(String s, String enc) throws UnsupportedEncodingException { 
     382        public static String hEncode(CharSequence s, String enc) throws UnsupportedEncodingException { 
    379383                return xEncode(s, enc, sDontNeedEncodingUrl); 
    380384        } 
     
    382386        /** 
    383387         *  
    384          * Encode tous les caractères sauf les "/" et ":". Les espaces sont transformés 
     388         * Encode tous les caractères.  
     389         * Correposnd à encodeURIComponent() en JS. 
     390         * Les espaces sont transformés 
    385391         * en "%20" et non en "+". (le client webdav Windows ne gère pas le +). 
    386392         */ 
    387         public static String hEncodeParam(String s, String enc) throws UnsupportedEncodingException { 
     393        public static String hEncodeParam(CharSequence s, String enc) throws UnsupportedEncodingException { 
    388394                return xEncode(s, enc, sDontNeedEncodingParam); 
    389395        } 
    390396 
    391397        /** 
    392          *  
    393          * Encode tous les caractères qui ne sont pas dans le tableau pDontNeedToEncode.  
    394          * Les espaces sont transformés en "%20" et non en "+". (le client webdav Windows ne gère pas le +). 
    395          */ 
    396         public static String xEncode(String s, String enc, BitSet pDontNeedToEncode) throws UnsupportedEncodingException { 
    397  
    398                 boolean needToChange = false; 
    399                 boolean wroteUnencodedChar = false; 
    400                 int maxBytesPerChar = 10; // rather arbitrary limit, but safe for now 
    401                 StringBuilder out = new StringBuilder(s.length()); 
    402                 ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar); 
    403  
    404                 OutputStreamWriter writer = new OutputStreamWriter(buf, enc); 
    405  
    406                 for (int i = 0; i < s.length(); i++) { 
    407                         int c = s.charAt(i); 
     398         * <p>Encode tous les caractères qui ne sont pas dans le tableau pDontNeedToEncode.  
     399         * Les espaces sont transformés en "%20" et non en "+". (le client webdav Windows ne gère pas le +).</p> 
     400         *  
     401         * <p>Par rapport à l'implémentation java {@link URLEncoder}, cette version est plus otptimisée si 
     402         * statistiquement les cas de présence de caractères à encoder (en %XX) sont faibles  
     403         * (instanciation juste à temps des buffers et objets d'encodings).</p> 
     404         */ 
     405        public static String xEncode(CharSequence s, String enc, BitSet pDontNeedToEncode) throws UnsupportedEncodingException { 
     406                if (enc == null) throw new NullPointerException("charsetName"); 
     407 
     408                StringBuffer out = null; 
     409                CharArrayWriter charArrayWriter = null; 
     410                Charset charset = null; 
     411 
     412                for (int i = 0; i < s.length();) { 
     413                        int c = (int) s.charAt(i); 
    408414                        //System.out.println("Examining character: " + c); 
    409415                        if (pDontNeedToEncode.get(c)) { 
    410416                                // SYS 2003-03-09. Mise en commentaire pour transformer l'espace en %20 
    411                                 //if (c == ' ') { 
    412                                 //      c = '+'; 
    413                                 //      needToChange = true; 
    414                                 //} 
     417                                //                if (c == ' ') { 
     418                                //                    c = '+'; 
     419                                //                    needToChange = true; 
     420                                //                } 
    415421                                //System.out.println("Storing: " + c); 
    416                                 out.append((char) c); 
    417                                 wroteUnencodedChar = true; 
     422                                if (out != null) out.append((char) c); 
     423                                i++; 
    418424                        } else { 
     425                                if (out == null) { 
     426                                        //1er car à encoder détecté 
     427                                        try { 
     428                                                charset = Charset.forName(enc); 
     429                                        } catch (IllegalCharsetNameException e) { 
     430                                                throw new UnsupportedEncodingException(enc); 
     431                                        } catch (UnsupportedCharsetException e) { 
     432                                                throw new UnsupportedEncodingException(enc); 
     433                                        } 
     434                                        out = new StringBuffer(s.length() + 32); 
     435                                        if (i > 0) out.append(s, 0, i); 
     436                                        charArrayWriter = new CharArrayWriter(); 
     437                                } 
    419438                                // convert to external encoding before hex conversion 
    420                                 try { 
    421                                         if (wroteUnencodedChar) { // Fix for 4407610 
    422                                                 writer = new OutputStreamWriter(buf, enc); 
    423                                                 wroteUnencodedChar = false; 
    424                                         } 
    425                                         writer.write(c); 
     439                                do { 
     440                                        charArrayWriter.write(c); 
    426441                                        /* 
    427442                                         * If this character represents the start of a Unicode 
    428443                                         * surrogate pair, then pass in two characters. It's not 
    429                                          * clear what should be done if a bytes reserved in the  
     444                                         * clear what should be done if a bytes reserved in the 
    430445                                         * surrogate pairs range occurs outside of a legal 
    431                                          * surrogate pair. For now, just treat it as if it were  
     446                                         * surrogate pair. For now, just treat it as if it were 
    432447                                         * any other character. 
    433448                                         */ 
    434449                                        if (c >= 0xD800 && c <= 0xDBFF) { 
    435450                                                /* 
    436                                                  System.out.println(Integer.toHexString(c)  
    437                                                  + " is high surrogate"); 
    438                                                  */ 
     451                                                  System.out.println(Integer.toHexString(c) 
     452                                                  + " is high surrogate"); 
     453                                                */ 
    439454                                                if ((i + 1) < s.length()) { 
    440                                                         int d = s.charAt(i + 1); 
     455                                                        int d = (int) s.charAt(i + 1); 
    441456                                                        /* 
    442                                                          System.out.println("\tExamining "  
    443                                                          + Integer.toHexString(d)); 
    444                                                          */ 
     457                                                          System.out.println("\tExamining " 
     458                                                          + Integer.toHexString(d)); 
     459                                                        */ 
    445460                                                        if (d >= 0xDC00 && d <= 0xDFFF) { 
    446461                                                                /* 
    447                                                                  System.out.println("\t"  
    448                                                                  + Integer.toHexString(d)  
    449                                                                  + " is low surrogate"); 
    450                                                                  */ 
    451                                                                 writer.write(d); 
     462                                                                  System.out.println("\t" 
     463                                                                  + Integer.toHexString(d) 
     464                                                                  + " is low surrogate"); 
     465                                                                */ 
     466                                                                charArrayWriter.write(d); 
    452467                                                                i++; 
    453468                                                        } 
    454469                                                } 
    455470                                        } 
    456                                         writer.flush(); 
    457                                 } catch (IOException e) { 
    458                                         buf.reset(); 
    459                                         continue; 
    460                                 } 
    461                                 byte[] ba = buf.toByteArray(); 
     471                                        i++; 
     472                                } while (i < s.length() && !pDontNeedToEncode.get((c = (int) s.charAt(i)))); 
     473 
     474                                charArrayWriter.flush(); 
     475                                String str = new String(charArrayWriter.toCharArray()); 
     476                                byte[] ba = str.getBytes(charset.name()); 
    462477                                for (int j = 0; j < ba.length; j++) { 
    463478                                        out.append('%'); 
     
    475490                                        out.append(ch); 
    476491                                } 
    477                                 buf.reset(); 
    478                                 needToChange = true; 
    479                         } 
    480                 } 
    481  
    482                 return (needToChange ? out.toString() : s); 
     492                                charArrayWriter.reset(); 
     493                        } 
     494                } 
     495 
     496                return (out != null ? out.toString() : s.toString()); 
    483497        } 
    484498 
     
    525539                return decodeURI(pUri, pOffset, pOffsetEnd, pEncoding, new StringBuilder(pOffsetEnd - pOffset)); 
    526540        } 
    527          
     541 
    528542        /** 
    529543         * Decode une URL. 
Note: See TracChangeset for help on using the changeset viewer.