Back to Basics: Two-Dimensional Arrays

I had planned to write an article on ECMAScript Harmony and my ideas for corresponding XPIDL changes… but four months after its announcement, I find I still don’t know what’s in the Harmony spec! (We know a few things that are out… but since the initial blog surge, it’s been quiet.)

So I’ve decided to put my ideas for XPIDL on the side, and move on to the last part in this series: my attempt at creating a XPCOM component for two-dimensional arrays. Read on for further details.

Continue reading Back to Basics: Two-Dimensional Arrays

Back to Basics: Why write components in C++?

A year or so ago, I introduced the ArrayConverter
module
to Verbosio, and tried to get it into mozilla.org code. The idea
was simple: a JavaScript library for converting between native JavaScript
arrays, XPCOM arrays, nsIArray objects and nsISimpleEnumerator
objects. Although it did not get in, I’ve been rethinking half of the
ArrayConverter module’s functionality, and I believe now that I
overlooked something.

I planned on writing two different articles – one talking about
reinventing the wheel unnecessarily, and another talking about why I, a
JavaScript expert, would choose to write XPCOM components in C++. It turns
out, though, that each of these has roughly the same answer: the penalties of
XPConnect. Read on for
further details.

Continue reading Back to Basics: Why write components in C++?

Back to Basics: Read-only Data

(I’m posting two articles today – and for those of you who correctly pointed out my XPCOM Services article had bugs in the sample code, I’ve updated it to point to live code with a couple adjustments. I continue to welcome your insight.)

XPCOM provides a lot of basic data types – nsIVariant
is one of the more complex ones from a C++ standpoint. In particular, they
provide arrays through the nsIArray
interface, object containers through nsIPropertyBag
and nsIPropertyBag2,
and a bunch of primitive values such as strings and floating-point numbers
through nsISupportsPrimitives.
XPCOM also provides components
and contracts
for these data types in C++, so you don’t have to
reimplement them. (You can if you want to, but it’s usually not necessary, as
I’ll explain in another article.)

There’s only one downside to these basic components: they’re eternally
changeable. What that means is I can pass a
nsISupportsString to your component, and it can change that
value before sending it onto another component. From my perspective, I don’t
have any way of “sealing” the data, of making it read-only. Even if I pass
you one of these components in an interface that has no change methods
(nsIArray), you could easily QueryInterface it for
an interface that has change methods (nsIMutableArray).
You’ll find an exception to the rule in nsIWritableVariant, but
that’s about it.

In this article, I’ll talk about two approaches to this problem – and the
choice I made.

Continue reading Back to Basics: Read-only Data

Finding files missing a tri-license?

Dear Lazyweb,

I realized that for Verbosio, I have forgotten to explicitly add the MPL/GPL/LGPL tri-license boilerplate to a number of my files. Although the project is open-source and under these licenses, I still see the missing boilerplates as an oversight.

I did a quick Google search for Perl scripts to find these files, and found only this: an Add_License script. It does support MPL, but not the tri-license.

Does anyone out there have a script for identifying these files? I’d prefer to add the boilerplates myself, but I still need to search for where they are not.

Back to Basics: Defining XPCOM Services

Once upon a time, I asked a question in the #developers channel
on irc.mozilla.org:

How do I define that a XPCOM component is
actually a service?

The answer I received:

See if the caller uses do_GetService(), or
Components.classes[…].getService().

This is less than satisfactory. I should be able to say “There can be only
one” and not “Oh, please, don’t create more than one of me.” Over the years,
I came up with different solutions for JavaScript – and I recently discovered
the standard way to do it for C++-based XPCOM components. Read on in the
extended entry for details.

Continue reading Back to Basics: Defining XPCOM Services

Back to Basics: Judo with nsIVariant

With XPIDL, XPCOM components can be very strict about what they allow.
Simply put, if you try to pass in an argument to a XPCOM component, and the
component requires a type that your argument doesn’t support, it won’t work.
In C++, your program won’t compile; in JavaScript, XPConnect throws
exceptions. This is a good thing.

Many of the basic data structures – nsIArray, nsIPropertyBag, etc. – take
a nsISupports argument. This covers most objects you construct
and work with. This is all well and good… unless you want to pass in a raw
type such as a number, a true or false value, a
string, etc. Then you’re stuck.

Fortunately, all is not lost. There is an interface named
nsIWritableVariant, which XPCOM provides for wrapping native
types in an nsISupports object. (There are type-specific
interfaces like nsISupportsPRBool as well, but
nsIWritableVariant is an one-size-fits-all solution.) Even more
interesting, its read-only companion, nsIVariant, is “magical”
to XPConnect: JavaScript receives its values as native types, not as
nsIVariant objects.

Thus, nsIVariant turns the strengths of XPIDL barriers so
that they are no longer fighting you, but working with you. This is what I am
calling judo with nsIVariant. Read on in the extended entry for more details.

Continue reading Back to Basics: Judo with nsIVariant

Back to Basics: XPCOM Arrays and Memory

A couple weeks ago, I started reading “Learning Python”, by
Mark Lutz. It’s an interesting feeling, going back to the basics of
programming – numbers, strings, arrays, etc. In reading this book, I kept
thinking there were some things missing from the basic XPCOM tool set.
Therefore, I decided to attempt implementing these missing pieces.

Now, I could be totally wrong about any or all of these being missing…
but it’s also a good exercise for me to push my boundaries and strengthen my
C++ skill set. The result is not only code that I can use for
proof-of-concept, but code that may be useful elsewhere.

This is the first article in a multipart series titled “Back to Basics”,
exploring these concepts. This first article is about native C++ arrays
through XPCOM – and making sure I don’t leak memory. Read on in the extended
entry for details.

Continue reading Back to Basics: XPCOM Arrays and Memory

“Dancing Dude at Skyfire” – Hello World

Original video and YouTube

Yeah, that’s me. You’d think I’d burned through my fifteen minutes of fame already…

Yes, I wore the Mozilla shirt deliberately. My role at Skyfire is to basically customize Mozilla Firefox for our needs. So it seemed fitting to combine the shirt and the little Skyfire badge.

As for the dancing itself… I think I can hold my own. 🙂 I’ll say this much – at that level, it is a workout in addition to a whole lot of fun. I don’t care about being alone out there either. I basically make it up on the spot (or I used to, anyway…)

Replacing JSLib in Verbosio

I came to an unpleasant decision last week. While working on reorganizing Verbosio’s source code, I realized that JSLib should not survive the transition.

I didn’t really like this very much. JSLib has been useful to me in the past. But when I thought about it, the only thing I used JSLib for was its file I/O utilities. These utilities should be used from chrome (and I abused that in my file search components).

Plus, I’m a much more experienced developer than when I first started with Abacus over four years ago. The Mozilla code base has similarly improved, and I just felt I could do the same job I was asking JSLib to do, with less (and cleaner) code.

I’m not saying JSLib is a bad library or a bad idea – far from it. I’m saying what I needed from JSLib is too small to justify having it around. Libraries for Mozilla are a popular idea – FUEL, STEEL, and JavaScript modules (.jsm) come to mind.

Besides, if you’re going to replace a library with one of your own, you should add value (not just cut costs).

I decided to write a library that, in theory, would be able to read and write to flat files, zip archives… and zip archives within zip archives. Think JAR files inside a XPI. Then, to make sure that I did it right, I decided to write a xpcshell test case for the module. (Yes, you can do that. The test harness doesn’t care whether you’re testing components or a .jsm file.) After a couple of days, I came up with FileCommon.jsm and test_FileCommon.js.

(The key is in FileCommon.getFile(), near the end. It takes multiple arguments, beginning with the path to a zip archive in the operating system, then an entry inside the zip (which is also a zip), then an entry inside the second zip archive, and so on.)

I’m sure there are bugs in this implementation. Right now no code in Verbosio uses it yet, and as I work on replacing JSLib with FileCommon.jsm, I’ll continue to add to the module. Eventually, I may make it a standard components module with new interfaces. Like so much else in Verbosio, it’s right now a proof-of-concept.

With JSLib, the time has come to move on. XUL Widgets will also fade, as I absorb its efforts into the Verbosio project directly. XUL Widgets (and Verbosio) doesn’t have any other customers, anyway, so centralizing under one roof makes sense.

Thanks for getting me started, Pete.

Alex Vincent's ramblings about Mozilla technology, authoring, and whatever he feels like.