darin wrote:
+mozSRoaming::mozSRoaming()
+ : mFiles(10)
+{
+ mIsRoaming = PR_FALSE;
+ mMethod = 0;
+ mRegistry = 0;
+}
nit: why not initialize all variables using the variable
initializer list?
mFiles is an array or so, thus the custom constructor call via init
list. I thought the general style was to use the ctor body, thus the
rest, but both is fine with me.
It's generally better to assign member variables in the constructor's
initializer list. By doing so, you enable the compiler to warn
you if the order of initialization does not match the order in which
the member variables are declared. Initializing them in order
helps with performance (I presume).
nit: do
you want to use NSPR logging instead? commenting out printf statements
is a messy way to manage debug logging.
True, but NSPR log is even more messy IMHO - set up env vars each
session, figure out the right module name and log level etc.. We can
remove the printfs entirely, if they are a concern.
$ export NSPR_LOG_MODULES=sroaming:5
$ export NSPR_LOG_FILE=/tmp/sroaming.log
how hard is that?
NSPR logging is nice precisely because it allows you to have logging
without editing and recompiling the source. Also, you can enable
NSPR logging in release builds. This is nice if you find people
reporting bugs in the field. Being able to ask people to send you
a NSPR log has proven invaluable to me while trying to figure out wierd
necko bugs. Still, it's your module... if you want printf-style
log statements scattered throughout, then so be it.
+
+ rv = ReadRoamingPrefs();
+ nsresult rv = NS_OK;
nit: no reason to initialize |rv| if you are going to assign a
value into it immediately.
There is: IIRC, I found myself moving around the definition and
adding/removing init all the time, IIRC even having it accidently
uninitalized at one point in this very module. Our code is not set in
stone, OTOH compilers may optimize this away anyways. For consistency
and safety, I always define and init nsresult at the very top.
Compilers usually warn you if you try to use an uninitialized
variable. I think it's bad form to rely on the compiler to clean
up things like this, but it's just a personal nit. I'm not going
to hold you to it.
passing
nsCOMPtr<nsIFile> by value has significant cost.
Huch? I assumes nsCOMPtr to be lightweight, only slightly more heavy
than a raw pointer and only increasing/decreasing a counter.
Oh, it's much more than increasing/decreasing a counter. AddRef
and Release are virtual function calls. The overhead associated
with the virtual function call far outweighs the cost of
incrementing/decrementing a counter. If you can avoid virtual
function calls, then you should. Passing a nsCOMPtr by value is
bad form.
are you
sure you want to do this? i would recommend using the standard XPCOM
getter
style, which would be much more efficient, e.g.:
The idea was to have the result be a return value, so that I can use
nested function calls. XPCOM style doesn't allow that, which I find
extremly inconvient. In this case, however, I see that I don't use the
function in a nested way anyways and always check the return value, so
the XPCOM way would be better, yes, we could then maybe also return an
error code.
returning an error code is good :-)
+ ioParamBlock->SetInt(0, download ? 1 :
2);
+ ioParamBlock->SetInt(1, files.Count());
should these indicies (0 and 1) correspond to some enum type?
magic
numbers are bad. it is not at all clear to me (the casual code reader)
what they are supposed to mean.
It's defined in the long comment right above it ;-).
This just passes information to/from the JS code. I agree that the
nsIDialogParamBlock used is a bad solution, but I didn't know any other
one which wouldn't require considerably more [complicated] code.
enums
give me some string to grep on to learn more about the identifier :-)
Yes, but these are also used in the JS code, so your grep would fail
=> misleading.
Your JS code could define constants by the same name. Associating
names to magic numbers (especially an enumeration) is almost always a
good thing.
OK. (I find the if-operator *much* easier to
decipher.)
Fine by me.
it
seems
kind of odd to fetch the nsIRegistry instance in this way given that
it happens to be a member variable (mRegistry).
Keep in mind that this code is run at most once at each of startup and
shutdown.
My point was that you already have the member variable so why not just
provide an inline accessor on the class.
nit:
GetRegistryTree might be a better name for this.
OK. But the same would need to apply for ProfileDir(), FilesToRoam(),
then.
Yeah, that sounds good.
nit:
"else" after a return statement is unnecessary.
Note that this (any many other comments) probably makes no difference
in the resulting exe.
Yes, I agree. However, it just helps unclutter code if you remove
unnecessary text. In some cases it can help reduce indenting,
which can improve readability. This is just a nit. Feel
free to ignore.
should
mMethod be an enumeration type? magic numbers (1 & 2)... what do
they
mean?
They are defined somewhere, they simply mean "use mozSRoamingStream"
and "use mozSRoamingCopy". I guess we could use an enum here, but the
values must stay, they are used in the user's registry, IIRC, even as
new values (= for new 'protocol handlers') are added.
It's just good form to give a descriptive name to these numbers.
+ So, I just power netlib up again and then
power it down again by sending
+ the corresponding profile change notification.
this will have effect on SSL.
IIRC, I tested the code with SSL and it works, but not sure.
for
example, if you are fetching the profile over an SSL connection and the
user had already agreed to accept the site's certificate for this
session, then you will end up requiring the user tore-accept the
certificate.
If you put your profile on an SSL-protected server and don't
permanently accept the server's certificate, you are insane. Any other
cases?
I don't know... lot's of stuff happens when you issue a profile change
notification. I worry that you could end up causing unexpected
side-effects. If not now, maybe later. It seems wrong to
co-opt these notifications like this.
of
course, i'm not sure how the UI for that would be handled anyways.
perhaps we need a better event. restarting necko like this seems like a
hack.
It is, as written. But adding a new event didn't (and doesn't) seem
very tempting.
Yeah, I agree that it would be painful. I think at the very least
it should be something to explore in the future.
nit:
comment style really varies in this file.
There is a system behind it, but OK to change it however the editor
pleases.
Well, it's your module. I'm just pointing out the inconsistencies
as I see them. If you have a system, then by all means ;-)
why are
you using wide strings for URLs? why not just use UTF-8?
Don't remember, anything is fine with me.
UTF-8 is generally better for URL strings in C++ Mozilla code.
+ Unfortunately, this doesn't work. I have
to
+ block this function until the transfer is done, but have the
transfer
+ itself and the progress UI working. darin says, I will get threading
+ issues then. He suggested to initiate the transfer from the dialog
I said this?
Yes, I can give you the IRC logs, if that helps.
I think there had to have been more to what I said then what you are
mentioning here. Maybe quote me exactly instead? ;-)
It's
not
clear from your comments here what threading
issues have to do with this... where are the threads? Maybe we spoke
about spinning up a new thread for the downloads? That would be a
problem
for sure since Necko is not threadsafe.
What I wanted to do was to put all the transfer logic into the C++
part, still have a dialog showing the progress and results to the user,
and not return |Download()| until all of that is finished (all
transfers done, dialog closed (automatically when successful, by user
when failure)).
As far I as I understood you, putting the transfer logic into JS was
the only way, because of said threading issues (which I didn't
understand, I have zero clue about Mozilla's threading).
It's too late now anyways, because all the code is written. I'm not
going to re-implement it in C++. But if I misunderstood you, we should
update the comment.
I'm thinking that the new synchronous I/O support that went into Necko
during the 1.6 dev cycle may greatly simply some of this. But, oh
well... you're right. It's all written now, and it presumably works
well, so there's not much point in rewriting it.
*phew*! done.
Yeah, no kidding! This was a really big patch!
I look forward to trying it out in 1.8 alpha :-)