views:

93

answers:

2

alert(line) alerts 'ac' typeof(line) is 'string'

When I run line.charAt(0), charAt is not a function.
When line is 'http://www.google.com/', it works,

I think it's the UTF-8 encoding of the file that I opened...

How to make charAt work with UTF-8?

UPDATED:

http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/src/effective_tld_names.dat?raw=1 is in my extension's chrome folder as effective_tld_names.dat

To run the code:

authority = 'orkut.com.br';
lines = sc_geteffectivetldnames();  
lines = sc_preparetouse(lines);
domainname = sc_extractdomainname(authority, lines);

The code:

function sc_geteffectivetldnames () {
    var MY_ID = "[email protected]";
    var em = Components.classes["@mozilla.org/extensions/manager;1"].
             getService(Components.interfaces.nsIExtensionManager);
    var file = em.getInstallLocation(MY_ID).getItemFile(MY_ID, "chrome/effective_tld_names.dat");
    var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].
                            createInstance(Components.interfaces.nsIFileInputStream);
    istream.init(file, 0x01, 0444, 0);
    istream.QueryInterface(Components.interfaces.nsILineInputStream);
    var line = {}, lines = [], hasmore;
    do {
      hasmore = istream.readLine(line);
      lines.push(line.value); 
    } while(hasmore);
    istream.close();
    return lines;
}

function sc_preparetouse(lines) {
    lines = sc_notcomment(lines);
    lines = sc_notempty(lines);
    return lines;
}
function sc_notcomment(lines) {
    var line;
    var commentre;
    var matchedcomment;
    var replacedlines;
    replacedlines = new Array();
    var i = 0;
    while (i < lines.length) {
        line = lines[i];
        commentre = new RegExp("^//", 'i');
        matchedcomment = line.match(commentre);
        if(matchedcomment) {
            lines.splice(i, 1);
        } else {
            i++;
        }
    }
    return lines;
}
function sc_notempty(lines) {
    var line;
    var emptyre;
    var matchedempty;
    var replacedlines;
    replacedlines = new Array();
    var i = 0;
    while (i < lines.length) {
        line = lines[i];
        emptyre = new RegExp("^$", 'i');
        matchedempty = line.match(emptyre);
        if(matchedempty) {
            lines.splice(i, 1);
        } else {
            i++;
        }
    }
    return lines;
}
function sc_extractdomainname(authority, lines) {
    for (var i = 0; i < lines.length; i++) {
        line = lines[i];
        alert(line);
        alert(typeof(line));
        if (line.chatAt(0) == '*') {
            alert('test1');
            continue;
        }
        if (line.chatAt(0) == '!') {
            alert('test2');
            line.chatAt(0) = '';
        }
        alert('test3');
        checkline = sc_checknotasteriskline(authority, line);
        if (checkline) {
            domainname = checkline;
        }
    }
    if (!domainname) {
        for (var i = 0; i < lines.length; i++) {
            line = lines[i];
            alert(line);
            if (line.chatAt(0) != '*') {
                alert('test4');
                continue;
            }
            if (line.chatAt(0) == '!') {
                alert('test5');
                line.chatAt(0) = '';
            }
            alert('test6');
            checkline = sc_checkasteriskline(authority, line);
            if (checkline) {
                domainname = checkline;
            }
        }
    }
    return domainname;
}

It alerts 'ac', then 'string', then nothing.

UPDATED:

I'm thinking there is a difference between files opened with nsIExtensionManager and NSIIOService, because that real code doesn't work, but this test code works:

function makeURI(aURL, aOriginCharset, aBaseURI) {
  var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                            .getService(Components.interfaces.nsIIOService);
  return ioService.newURI(aURL, aOriginCharset, aBaseURI);
}

URL = makeURI('file://C:/test/TLDs.dat');

// URL is a nsIURI; see nsIIOService::newURI for getting a string into a nsIURI.
var file = URL.QueryInterface(Components.interfaces.nsIFileURL).file;
// file is now a nsIFile

// open an input stream from file
var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].
                        createInstance(Components.interfaces.nsIFileInputStream);
istream.init(file, 0x01, 0444, 0);
istream.QueryInterface(Components.interfaces.nsILineInputStream);

// read lines into array
var line = {}, lines = [], hasmore;
do {
  hasmore = istream.readLine(line);
  lines.push(line.value); 
} while(hasmore);

istream.close();

// do something with read data

lines[0].charAt(0);
+1  A: 

It's hard to tell what's going on without seeing any code, but remember that not all properties that evaluate as strings are really strings. A good example of this is the location object. Use of the object on its own will give you a string value, but you can't use any methods that are available to native strings on that string value.

// Although `window.location` returns a string, you cannot use String methods on it
alert(window.location.charAt(0));       // error
alert(window.location.href.charAt(0));  // no error

The same could be true of strings provided by external interfaces, such as plugins or ActiveX controls. The solution to this problem is to cast to a native string:

alert((""+window.location).charAt(0));        // auto casting with concatenation
alert(String(window.location).charAt(0));     // with the String() constructor
alert(window.location.toString().charAt(0));  // with toString()

At least the first two of those methods should solve your problem (replace window.location with your var). If not, try posting some code so we can get a better idea of what's happening.


Looking at your code, I can only assume that what I said above is correct. The readLine method returns a line object that contains the non-native string property value (which is rather odd, considering). I would suggest editing your code to look like this:

function sc_geteffectivetldnames () {
    var MY_ID = "[email protected]";
    var em = Components.classes["@mozilla.org/extensions/manager;1"].
             getService(Components.interfaces.nsIExtensionManager);
    var file = em.getInstallLocation(MY_ID).getItemFile(MY_ID, "chrome/effective_tld_names.dat");
    var istream = Components.classes["@mozilla.org/network/file-input-stream;1"].
                            createInstance(Components.interfaces.nsIFileInputStream);
    istream.init(file, 0x01, 0444, 0);
    istream.QueryInterface(Components.interfaces.nsILineInputStream);
    var line = {}, lines = [], hasmore;
    do {
      hasmore = istream.readLine(line);
      lines.push(String(line.value));     // <--- or ""+line.value
    } while(hasmore);
    istream.close();
    return lines;
}
Andy E
Andy E, come back!
Delirium tremens
@Delirium: I have returned!
Andy E
A: 

I found URI Parsing for Firefox in MDC.

https://developer.mozilla.org/en/Code_snippets/URI_parsing

Somehow, it's not appearing on Google.

Delirium tremens