Closed Bug 280591 Opened 20 years ago Closed 7 years ago

SetComplexPref/GetComplexPref should support any object that implements nsISerializable

Categories

(Core :: Preferences: Backend, enhancement)

x86
Windows XP
enhancement
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: timeless, Unassigned)

Details

(Keywords: helpwanted)

Attachments

(1 file)

currently each time someone wants to be able to setComplexPref (someobjecttype)
they have to hack nsIPref* to understand their object. Since we already have a
nice interface nsISerializable, we should let nsIPrefBranch understand that and
protect it from having to learn about internals of other objects.
I've got some code that creates a stream of bytes containing the contract ID or
class ID followed by the object's serialisation, which is all well and good, but
I can't just plonk it into SetCharPref since there's rather a lot of nulls
floating about, and what-not. Ideas?

Also, what /should/ I use to re-create a serialised object? Just class ID?
I am already using that interface - that is pretty much the *problem*. The
stream generated is binary. Prefs are char*. I am also using nsIBinary*Stream
for the prolog, which could be changed, but that doesn't help what the objects
themselves serialise to...
you could always use PL_Base64Encode. and nsIObjectInputStream answers:
> Also, what /should/ I use to re-create a serialised object? Just class ID?
(In reply to comment #4)
> you could always use PL_Base64Encode.

Ok.

> and nsIObjectInputStream answers:
> > Also, what /should/ I use to re-create a serialised object? Just class ID?

Cryptic answers are no use to me.
sorry. I did not mean to be cryptic. nsIObjectInputStream offers a readObject
method, which does all the work of reading an object for you (provided it was
serialized with nsIObjectOutputStream).


...hm, or so I would have thought. nsBinaryInputStream does not seem to
implement it, only fastload does... I wonder why the binary stream does not
implement this method and fastload just uses that one?
Yeah, the object streams don't make much sense to me... I've got objects to
serialise already, though, so I'm not too worried about that - I just need to
know what to re-create on reading.

Let me tidy the code up a little, and make it use class IDs only (for now), and
see if I can get base64 output working, then I'll attach it.
Fudge sticks.

PL_Base64Encode works great. I now have a url pref encoded in base64 and taking
up about 4 times the space it would as ASCII. ;)

*However*, I can't decode it! PL_Base64Decode completely fails to realise its
output may be binary, and thus only gives me a char* to it... :(

I guess I need an alternative base64 decoder, or some other encoding system.
As far as I know, the only big issue is this decoding one... but since I can't
get past that I have no idea if the rest of the reading code will actually
work. :)  (there are a few FIXMEs scattered about where I'm not sure of things,
but the save bit definately works. :D )

And don't ask about those contract IDs...
See http://lxr.mozilla.org/mozilla/source/xpcom/io/nsFastLoadFile.h#251,
http://lxr.mozilla.org/mozilla/source/xpcom/io/nsBinaryStream.h#59, etc.

The reason for nsBinaryInputStream inherits from nsIObjectInputStream (likewise
for Output) is to share code.  If only nsFastLoadFile* inherited from
nsIObject*Stream we would have to use delegation (wrapping) to share
nsBinaryStream.cpp code.  But by making the concrete (nsBinary*Stream)
superclass inherit from the wider iface, we avoid an extra layer of call forwarding.

/be
brendan: ah, so nsBinaryInputStream/OutputStream is not meant to read/write
arbitrary objects, unlike their java equivalent?

silver: ah, hm...
http://lxr.mozilla.org/seamonkey/source/nsprpub/lib/libc/include/plbase64.h#78
does mention a formula that sounds like it may give you a correct answer, maybe
biesi: yes, the Binary*Stream code predates FastLoad and nsIObject*Stream.idl,
and I didn't want to change existing interfaces, just impls.  This is a
code-sharing deal private to xpcom/ds.

/be
(In reply to comment #11)
> http://lxr.mozilla.org/seamonkey/source/nsprpub/lib/libc/include/plbase64.h#78
> does mention a formula that sounds like it may give you a correct answer, maybe

Ah, yes. I forgot base64 was a regular encoding (i.e. has a simple ratio between
encoded and decoded length). Let me try this... (though I'll need to account for
the '='s... oh joy, string-fu time)
The code I actually wrote for it was this:

    // First, calculate the maximum length of the output...
    PRUint32 count = ((3 * utf8String.Length()) / 4);
    PRUint32 pos = utf8String.Length() - 1;
    // ...then knock of a character for each "=" found at the end of the input.
    while (*(decodeString + pos) == '=') {
      count--;
      pos--;
    }

...but I do prefer the if/else version. However, the code linked to relies on
truncation of / with ints, which I don't like when you can do it exactly every
time, so I'm going to keep the code my way around (*3/4 first, then adjust).
Oops, decodeString should be the un-decoded string. Still, my point stands.
(Filter "spam" on 'prefs-nobody-20080612'.)
Assignee: prefs → nobody
QA Contact: prefs
QA Contact: preferences → preferences-backend
We are now heading in the direction of fewer complex values, not more. See bug 1408580. WONTFIX.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: