Log in

No account? Create an account
LiveJournal Client Discussions [entries|archive|friends|userinfo]
LiveJournal Client Discussions

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Yet another question about user pictures [Dec. 18th, 2001|10:45 pm]
LiveJournal Client Discussions


Can I reliably assume that pickw_count will come before the pick_n entries when I login to the server?

Similarly, can I reliably assume that nobody will ever have more than twice the maximum (so...20 at the moment) number of user pictures?

From: asciident
2001-12-18 09:47 pm (UTC)
Well, maximum is a little misleading... you're assuming that 10 userpics is the max, but perm. accounts can have up to 15... still not over 20 but ... *shrug*
(Reply) (Thread)
[User Picture]From: credendovides
2001-12-18 10:37 pm (UTC)
You could probably get away with it, as things run now.... But I could not in good conscience recommend it. I won't lecture about programming styles, but I think it would be a mistake to make any such assumptions, causing pain down the road.
(Reply) (Thread)
[User Picture]From: stesla
2001-12-18 11:37 pm (UTC)
There are certain assumptions that can be made. If the protocol says "pickw_count will come before pickw_n" and I'm writing for the protocol, then I can assume that I'll get a count before I get the things I'm counting.

Assuming a maximum is pretty silly, I'll admit. What I'll probably end up doing is pick some outrageous number, comment the hell out of it in the header and define it:

#define PICKW_MAX 1024

or some such nonsense which would never realistically be (since I'd later do a

char *userpics[PIKCW_MAX]

I just think it's silly to take the time to malloc when I have a set maximum anyway.
(Reply) (Parent) (Thread)
[User Picture]From: credendovides
2001-12-18 11:46 pm (UTC)
Before I say this, let me just preceed it by saying I don't mean to pick on you. But I come from a network security company in the past, and I've seen more security vulnerabilities from people saying just that "Oh, this is a reasonable number of X, it will be fine". Dealing with malloc is not that hard. Just malloc it when you start and free it when you clean up. It is also easier to track down if you have a bug, as there are a lot more malloc verifiers than there are stack verifiers. I hate seeing hard coded constants for dynamic data. Doubly so when it then allocates a fixed number of records based on that hard coded constant.

That aside, I haven't read the protocol spec recently. If it says that the count will always come first, then by all means, rely on it.

But if it doesn't, or as I seem to recall (Of course my memory is far from perfect) it says the opposite - that order of returned fields is not garunteed in any way shape or form. From a design perspective, it is cleaner to not assume any order. If you do that, you can simply load all the values into an array (Simple) or hash (Fast) and then look for the values you care about explicitly. Then you can create a clean seperation between the protocol layer and the communication layer.
(Reply) (Parent) (Thread)
[User Picture]From: stesla
2001-12-19 12:04 am (UTC)
Sure. That's why I was askin' :)

As far as hashes go...I would if I were using Perl. As it were I don't want to take the time to write a good hash, nor do I want the time to figure out why my wrapper around the Berkley DB libraries was always segfaulting :P

So I'm processing the stuff as I read it through.

My end solution will likely be to pick a reasonable Magic Number which I increment the array by whenever I malloc.
(Reply) (Parent) (Thread)
[User Picture]From: credendovides
2001-12-19 03:07 am (UTC)
Dynamically resizing the array as you get the contents is one way to do it, setting the size exactly if you happen to get the count. Generally, if you don't get the count, the way it's done is start with a reasonable number (Say, 8 in this case) and if it grows beyond that, keep doubling it. (IE if you get a 9, make it 16, if you then get a 17, make it 32... But be sure to do it in a loop, so if you get 33 first, it will see 8 is too small, double it to 16, see that is too small, double it to 32, see that is too small, then double it to 64)

For something like this, I'd personally just throw together a hash if I needed it and not worry about if it was perfect, or even a good hash, since any hash is better than straight strcmp. Though since I'm writing mine in C++, I'm just using the STL hash container to handle the return values from the server.
(Reply) (Parent) (Thread)
[User Picture]From: stesla
2001-12-19 01:07 pm (UTC)
Like I said in a response to xb95 down below...

I may end up writing a simple associative array anyway.
(Reply) (Parent) (Thread)
[User Picture]From: xb95
2001-12-19 07:45 am (UTC)
Uh, actually, pickw_count and all _count/_maxnum variables come back after the data. The specs (if they say that) are wrong and should be corrected. You can verify this by telnetting into the web server and pasting in a header and checking it out that way. I highly recommend you read in every variable, then iterate through all of them to find the one you want, and then find each individual one. If you rely on them to be in a certain order, you will only cause yourself more headaches.

Also, take it from another client author: fixed arrays for dynamic things sucks. Don't even bother. I've ended up using a linked list sort of thing to keep track of all the Friends and such. It makes it muuuuuuch easier. G'luck!
(Reply) (Thread)
[User Picture]From: stesla
2001-12-19 01:06 pm (UTC)
To save myself many headaches (and it's only really caused a couple, so I think it's still worth it...) I decided not to slurp it in, I decided to read it in and parse it as I was going. (The headaches being how to hash it in C).

I may end up setting a primitive associative array to slurp things into, since I know that all of the keys are unique...but for now I just cubbyhole the values as I get them. I try to avoid the fixed array thing as much as possible, but I always consider if it is a good way to do things. Then I usually don't do it that way anyway :P
(Reply) (Parent) (Thread)
From: evan
2001-12-19 04:14 pm (UTC)


There's no guarantee anything will be in any order-- I dunno what the docs, say, but I've read the LJ source.

If you're afraid of a hash (which is the Right Way to do this), you can always read in every key-value pair into a struct like:

typedef struct {
  char *key, *value;
} protocol_keyval;

Then you have:

char *lookup(protocol_keyval *keyvals, char *key) {
  for ( ; keyvals->key; keyvals++) {
    if (strcmp(key, keyvals->key) == 0)
      return keyvals->value;
  return NULL; /* key not found-- error. */
But that's ugly and just emulating a hash.
(Reply) (Thread)
[User Picture]From: stesla
2001-12-19 06:26 pm (UTC)

Re: hashes

I'll likely end up writing a real hash. Save me headaches later. Just didn't feel like writing the collision handling code back in June when I started this...so I tried doing it other ways. Now I'll go back and do The Right Thing.

I'll have to dig out that nice collision algorithm I saw a while back.
(Reply) (Parent) (Thread)