} else if((0x3C==aBytes[2]) && (0x3F==aBytes[3])) {
} else if((0x00==aBytes[2]) && (0x3F==aBytes[3])) {
static PRBool DetectByteOrderMark(const unsigned char* aBytes, PRInt32 aLen, nsString& oCharset, PRInt32& oCharsetSource) { oCharsetSource= kCharsetFromAutoDetection; oCharset.Truncate(); // See http://www.w3.org/TR/2000/REC-xml-20001006#sec-guessing // for details // Also, MS Win2K notepad now generate 3 bytes BOM in UTF8 as UTF8 signature // We need to check that // UCS2 BOM FEFF = UTF8 EF BB BF switch(aBytes[0])	 {   case 0x00:     if(0x00==aBytes[1]) {        // 00 00        if((0x00==aBytes[2]) && (0x3C==aBytes[3])) {           // 00 00 00 3C UCS-4, big-endian machine (1234 order)           oCharset.AssignWithConversion(UCS4_BE);        } else if((0x3C==aBytes[2]) && (0x00==aBytes[3])) {           // 00 00 3C 00 UCS-4, unusual octet order (2143)           oCharset.AssignWithConversion(UCS4_2143);        }      } else if(0x3C==aBytes[1]) {        // 00 3C        if((0x00==aBytes[2]) && (0x00==aBytes[3])) {           // 00 3C 00 00 UCS-4, unusual octet order (3412)           oCharset.AssignWithConversion(UCS4_3412);        } else if((0x3C==aBytes[2]) && (0x3F==aBytes[3])) {           // 00 3C 00 3F UTF-16, big-endian, no Byte Order Mark           oCharset.AssignWithConversion(UCS2_BE); // should change to UTF-16BE        }      }   break;   case 0x3C:     if(0x00==aBytes[1]) {        // 3C 00        if((0x00==aBytes[2]) && (0x00==aBytes[3])) {           // 3C 00 00 00 UCS-4, little-endian machine (4321 order)           oCharset.AssignWithConversion(UCS4_LE);        } else if((0x3F==aBytes[2]) && (0x00==aBytes[3])) {           // 3C 00 3F 00 UTF-16, little-endian, no Byte Order Mark           oCharset.AssignWithConversion(UCS2_LE); // should change to UTF-16LE        }      } else if(                     (0x3F==aBytes[1]) &&               (0x78==aBytes[2]) && (0x6D==aBytes[3]) &&               (0 == PL_strncmp("<?xml", (char*)aBytes, 5 ))) {       // 3C 3F 78 6D       // ASCII characters are in their normal positions, so we can safely       // deal with the XML declaration in the old C way       // XXX This part could be made simpler by using CWordTokenizer<char>,       //     but bug 104479 must be fixed first.       // The shortest string so far (strlen==5):       // <?xml       PRInt32 i;       PRBool versionFound = PR_FALSE, encodingFound = PR_FALSE;       for (i=6; i < aLen && !encodingFound; ++i) {         // end of XML declaration?         if ((((char*)aBytes)[i] == '?') &&            ((i+1) < aLen) &&           (((char*)aBytes)[i+1] == '>')) {           break;         }         // Version is required.         if (!versionFound) {           // Want to avoid string comparisons, hence looking for 'n'           // and only if found check the string leading to it. Not           // foolproof, but fast.           // The shortest string allowed before this is  (strlen==13):           // <?xml version           if ((((char*)aBytes)[i] == 'n') &&             (i >= 12) &&              (0 == PL_strncmp("versio", (char*)(aBytes+i-6), 6 ))) {             // Fast forward through version             char q = 0;             for (++i; i < aLen; ++i) {               char qi = ((char*)aBytes)[i];               if (qi == '\'' || qi == '"') {                 if (q && q == qi) {                   //  ending quote                   versionFound = PR_TRUE;                   break;                 } else {                   // Starting quote                   q = qi;                 }               }             }           }         } else {           // encoding must follow version           // Want to avoid string comparisons, hence looking for 'g'           // and only if found check the string leading to it. Not           // foolproof, but fast.           // The shortest allowed string before this (strlen==26):           // <?xml version="1" encoding           if ((((char*)aBytes)[i] == 'g') &&             (i >= 25) &&              (0 == PL_strncmp("encodin", (char*)(aBytes+i-7), 7 ))) {             PRInt32 encStart = 0;             char q = 0;             for (++i; i < aLen; ++i) {               char qi = ((char*)aBytes)[i];               if (qi == '\'' || qi == '"') {                 if (q && q == qi) {                   PRInt32 count = i - encStart;                   // encoding value is invalid if it is UTF-16                   if (count > 0 &&                      (0 != PL_strcmp("UTF-16", (char*)(aBytes+encStart)))) {                     oCharset.AssignWithConversion((char*)(aBytes+encStart),count);                     oCharsetSource = kCharsetFromMetaTag;                   }                   encodingFound = PR_TRUE;                   break;                 } else {                   encStart = i+1;                   q = qi;                 }               }             }           }         } // if (!versionFound)       } // for     }   break;   case 0xEF:       if((0xBB==aBytes[1]) && (0xBF==aBytes[2])) {        // EF BB BF        // Win2K UTF-8 BOM        oCharset.AssignWithConversion(UTF8);         oCharsetSource= kCharsetFromByteOrderMark;     }   break;   case 0xFE:     if(0xFF==aBytes[1]) {        // FE FF        // UTF-16, big-endian         oCharset.AssignWithConversion(UCS2_BE); // should change to UTF-16BE        oCharsetSource= kCharsetFromByteOrderMark;     }   break;   case 0xFF:     if(0xFE==aBytes[1]) {        // FF FE        // UTF-16, little-endian         oCharset.AssignWithConversion(UCS2_LE); // should change to UTF-16LE        oCharsetSource= kCharsetFromByteOrderMark;     }   break;   // case 0x4C: if((0x6F==aBytes[1]) && ((0xA7==aBytes[2] && (0x94==aBytes[3])) {   //   We do not care EBCIDIC here....   // }   // break; }  // switch return oCharset.Length() > 0;}