Re: [concordance-devel] libconcord new full patch (Re: Next try for the big IR learning patch..)

2008-06-24 Thread Andreas Schulz
On Tuesday 24 June 2008, Phil Dibowitz wrote:
 Andreas Schulz wrote:
  As I just recognized, better make that delete_*, to be consistent
  with delete_blob..

 Delete blob always deletes the same thing - in your case you have lots
 of different things..

Sure, by 'delete_*' I meant of course to rename each of them, 
not all to one, giving:
 ...
 void delete_key_names(char **garbage);
 void delete_ir_signal(uint32_t *garbage);
 void delete_post_string(char *garbage);

-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
___
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel


Re: [concordance-devel] libconcord new full patch (Re: Next try for the big IR learning patch..)

2008-06-24 Thread Stephen Warren
On Tue, June 24, 2008 1:04 am, Andreas Schulz wrote:
 So, maybe we can agree on the following interface:

That should work. Just a few mostly small comments:

In the delete_* functions, I'd use a more descriptive name for the
parameter than garbage, e.g.:

void delete_key_names(char **key_names);

In the description for get_key_names:

  * Memory allocated for the strings must be freed by the caller
  * via destroy_key_names() when not needed any longer, i.e.
  * after all codes have been posted via post_new_code.

I would avoid specifically mentioning deleting the memory after
post_new_code, because some clients will probably do this:

char ** key_names = get_key_names(...);
duplicate key_names into some internal structure (e.g. Python strings in a
list)
delete_key_names(key_names);
process the internal structure

The internal structure could be created by duplicating all the strings and
indexing them in some different way. Note: The key names are obviously
required to call post_new_code later, but there's no requirement it be the
same actual string (memory location holding it, that is), but simply that
the content of the string must be the same.

So, perhaps simply say this instead:

  * Memory allocated for the strings must be freed by the caller
  * via destroy_key_names() when no longer needed.

Same for other allocating functions.

In get_key_names, rather than returning an array with a NULL entry to
indicate the end, how about this:

int get_key_names(uint8_t *data, uint32_t size,
char *** key_names, uint32_t *key_names_length);

and called/used like this:

char **key_names;
uint32_t key_names_length;
int err = get_key_names(d, s, key_names, key_names_length);
if (err != SUCCESS) {
// handle error here
return;
}
for (int i = 0; i  key_names_length; ++i) {
printf(Key name %d is '%s'\n, i, key_names[i]);
}

This:
a) Can allow more meaningful error status
b) Is explicit about the array length up front

One could make a similar change to encode_for_posting, but since that's
always returning just one string, I'm not worried about that so much; your
call.

I would rename post_new_code's code parameter to encoded, to hint that
it comes from encode_for_posting.

Thanks for implementing this guys, and being open to API changes.


-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
___
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel


Re: [concordance-devel] libconcord new full patch ( Re: Next try for the big IR learning patch ..)

2008-06-23 Thread Andreas Schulz
(I re-added some cuts by Phil to answer both posts in one)

 On Sunday 22 June 2008, Phil Dibowitz wrote:
  On Sunday 22 June 2008, Stephen Warren wrote:
   A pulse is usually a low-high-low transition, whereas these docs
   talk about pulses and spaces. There should be differentiation between
   pulses (mark followed by space), marks (high time), and spaces (low
   time)

I actually wasn't really happy about the naming either initially, but 
missed to change it to something more appropriate, and then got used
to it... I have changed it now in libIRremotes to ir_signal and
ir_signal_length and will adapt libconcord accordingly, also making the
documentation clearer, as you suggested below.

   In the documentation for get_key_name, it may be worth mentioning that
   valid index values start at 1

anything wrong with index starting at 1 for '1'st entry?

   and increment by 1 until NULL is returned.

Well, probably some things just become too obvious when you have been working 
on them for several days...

   I really don't like the static buffer used by get_key_name. It's nasty
   that a client can only use this API on a single data blob at a time.
 
  So the question is - do we want to support more than one file AT THE
  SAME TIME? Given the current API you can in fact go through more than
  one file at a time. So being pragmatic, it's not so bad.
  Thus I've gone back and forth a few times, and can't quite decide.

I currently don't see any use for being able to handle multiple files in 
parallel - maybe sequential, in case someone comes up with a concordance 
daemon lurking 24/7 in the background - but parallel? Multiple parallel 
connections to Logitech, or collecting a bunch of downloaded files and
procesing them in parallel? It's all still driven by the software on the
Logitech servers, anyway...

   that the API internally maintains non-obvious implicit state. I'd
   prefer something more like the API below, where the XMLBuffer is
   dynamically allocated per iterator, but the type/content is still
   opaque to the client:
  
   void *keyiter_create(uint8_t *data, uint32_t size);
   char *keyiter_next(void* keyiter);
   void keyiter_destroy(void *keyiter);
   void keyiter_key_destroy(char *);
  
   No reversing or random access allowed either; should be much simpler.
 
  So I guess the idea with this feature is being able to go oh, damn, I
  hit the wrong button on the other remote and don't want to have to go
  back and redo the whole sequence. I like that.

To which Stephen replied:
 At least in congruity, I will make the client application use
 get_key_name to retrieve a list of all known key names into a Python
 list, and then iterate back/forth within that.

Well, concordance could do that as well, so what about:
  char **get_keynames(uint8_t *data, uint32_t size);
  void destroy_keynames(char **names);
and be done with the XML data in one call?

   Please document that the memory pointed at by get_key_name's return
   value needs to be free'd by the client. libconcord needs an API for the
   client to call to do this.
   encode_for_posting needs to define who owns the memory returned, and
   how to destroy it.

I started adding deallocators in libIRremotes, and will do so for libconcord. 
I'm not sure about the internals of python - will deallocators be of any use
there, and when should they be called?

   post_new_code and encode_for_posting check all the output/pointer
   parameters against being NULL, but learn_from_remote doesn't.

Guess I thought anybody so stupid to call learn_from_remote(NULL,NULL,NULL) 
should deserve a SIGSEGV... well, adding a check won't hurt, and may be
useful when interfacing to some other language..

   I'm not convinced that the Python bindings changes for verbose are
   the correct way to go; they don't handle exceptions very well.
 
  I didn't read through those changes, but I would say that seems
  reasonable to be able to enable debug in a production version so you can
  tell your users to do this when they report some problem you can't
  reproduce.

At least it was helpful to me in some stage of the develpment to see what
was going on and coming out - I also don't see any big difference in the 
exception handling - except maybe for the case that 'print' in the wrapper 
itself throws an exception (is that likely?).

   It'd be best if you removed the verbose part from the Python bindings

as you like it..There's probably also still to much 'verbose' stuff in my 
proposal for congruity (e.g. it prints geometry data when you zoom the
IR signal plot), and probably nobody is actually interested in the way the 
signal is encoded for posting to Logitech either...some information needed
while coding is surely useless once you've got the code right, so what should 
a verbose mode show? An enthusiast may enjoy to see the exact mark/space 
durations and even feed them into some other decoding tool, while a plain 
user will just think 'what the ?'

And-probably 

Re: [concordance-devel] libconcord new full patch (Re: Next try for the big IR learning patch..)

2008-06-23 Thread Phil Dibowitz
Andreas Schulz wrote:
 In the documentation for get_key_name, it may be worth mentioning that
 valid index values start at 1
 
 anything wrong with index starting at 1 for '1'st entry?

All arrays have their 1st entry at 0. That's how CS works. :)

I would say, start at 0.

 I currently don't see any use for being able to handle multiple files in 
 parallel - maybe sequential, in case someone comes up with a concordance 
 daemon lurking 24/7 in the background - but parallel? Multiple parallel 
 connections to Logitech, or collecting a bunch of downloaded files and
 procesing them in parallel? It's all still driven by the software on the
 Logitech servers, anyway...

I'm inclined to agree...

 Well, concordance could do that as well, so what about:
   char **get_keynames(uint8_t *data, uint32_t size);
   void destroy_keynames(char **names);
 and be done with the XML data in one call?

I don't think we need the call to destory() in this case. In this case
you're handed back an array of strings, which C knows how to deal with,
and any C-to-high-level language should be able to handle as well. For
example, in SWIG-to-perl I'd just allocate a scalar array, copy the
data, and then nuke the char**. There are other alternatives that SWIG
provides as well.

IMO, we only need the destroy() if they're opaque or non-C data. In this
case it's not a token is data that the user is expected to do something
with - data the user actually requested.

-- 
Phil Dibowitz [EMAIL PROTECTED]
Open Source software and tech docsInsanity Palace of Metallica
http://www.phildev.net/   http://www.ipom.com/

Never write it in C if you can do it in 'awk';
 Never do it in 'awk' if 'sed' can handle it;
 Never use 'sed' when 'tr' can do the job;
 Never invoke 'tr' when 'cat' is sufficient;
 Avoid using 'cat' whenever possible -- Taylor's Laws of Programming




signature.asc
Description: OpenPGP digital signature
-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php___
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel


Re: [concordance-devel] libconcord new full patch (Re: Next try for the big IR learning patch..)

2008-06-23 Thread Stephen Warren
On Mon, June 23, 2008 3:11 pm, Andreas Schulz wrote:
 On Sunday 22 June 2008, Stephen Warren wrote:
 In the documentation for get_key_name, it may be worth mentioning
 that valid index values start at 1

 anything wrong with index starting at 1 for '1'st entry?

Probably not, but it's sufficiently unusual for C (and many other
languages) that it's just worth mentioning.

 Well, concordance could do that as well, so what about:
   char **get_keynames(uint8_t *data, uint32_t size);
   void destroy_keynames(char **names);
 and be done with the XML data in one call?

That'd work too. I'll have to check whether it's easy to deal with
char** in the Python bindings; it should be...

 I started adding deallocators in libIRremotes, and will do so for
 libconcord. I'm not sure about the internals of python - will
 deallocators be of any use there, and when should they be called?

Absolutely useful. libconcord.py should simply expose the function call
as-is; never automatically call them (except in a situation where the
bindings actually copy the returned data into a Python type, rather than
returning a ctypes type referencing the memory, but we don't ever do that,
currently at least). The client app (e.g. congruity) should call them at
the same time a C application would; whenever it's done using the returned
data.


-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
___
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel


Re: [concordance-devel] libconcord new full patch (Re: Next try for the big IR learning patch..)

2008-06-23 Thread Stephen Warren
On Mon, June 23, 2008 3:28 pm, Phil Dibowitz wrote:
 Andreas Schulz wrote:
 Well, concordance could do that as well, so what about:
   char **get_keynames(uint8_t *data, uint32_t size);
   void destroy_keynames(char **names);
 and be done with the XML data in one call?

 I don't think we need the call to destory() in this case.

I don't agree. Why should the client (or bindings) know how the memory was
allocated, and hence how to free it. malloc() is common, but if the
client/bindings simply assume this, and call free() on the data, things
will break very horribly if libconcord was built using a debug malloc
library that redefines malloc/free to be something else, and perhaps
actually allocates a different (larger) sized chunk of memory in order to
add debug information headers/trailers, meaning that the actual pointer
passed to real free should be, say, 8 bytes less than that returned by the
debug malloc.


-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
___
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel


Re: [concordance-devel] libconcord new full patch (Re: Next try for the big IR learning patch..)

2008-06-22 Thread Stephen Warren
Andreas Schulz wrote:
 Next, here comes the latest version of my IR learning patch for
 libconcord.

A few comments on the API:

+ * pulse_count : total number of pulse and space durations in pulses
+ *  pulses should start with a pulse and end with a space duration,
+ *  hence pulse_count will always be an even number.

A pulse is usually a low-high-low transition, whereas these docs
talk about pulses and spaces. There should be differentiation between
pulses (mark followed by space), marks (high time), and spaces (low time)

So, I'd rewrite the docs as:

+/*
+ * Data structure information:
+ *
+ * carrier_clock: In Hz, usually ~36000..4
+ * pulses: IR mark/space durations (alternating) in microseconds
+ * pulse_count: Total number of pulses, i.e. total number of marks plus
+ *  total number of spaces. Pulses consist of a mark plus a space,
+ *  hence pulse_count will always be an even number.

In the documentation for get_key_name, it may be worth mentioning that
valid index values start at 1 (rather than the typical 0) and increment
by 1 until NULL is returned. With the current docs, it could be legal
for index values 1, 2 to be defined, 3, 4 not, then 5, 6, 7 to be
defined. Actually, see below for further comments on the semantics of
this API.

Please document that the memory pointed at by get_key_name's return
value needs to be free'd by the client. libconcord needs an API for the
client to call to do this; not all clients are C, and hence they can't
all call C's free(), and delete_blob is only defined for file blobs
(which are free()d using delete[], which should only be used for new[]'d
pointers, and not for malloc/strdup/...-returned pointers).

I really don't like the static buffer used by get_key_name. It's nasty
that a client can only use this API on a single data blob at a time, and
that the API internally maintains non-obvious implicit state. I'd prefer
something more like the API below, where the XMLBuffer is dynamically
allocated per iterator, but the type/content is still opaque to the client:

void *keyiter_create(uint8_t *data, uint32_t size);
char *keyiter_next(void* keyiter);
void keyiter_destroy(void *keyiter);
void keyiter_key_destroy(char *);

where the client uses this like:

void *i = keyiter_create(d, s);
for (;;) {
char *s = keyiter_next(i);
if (!s) {
break;
printf(Key: '%s'\n, s);
keyiter_key_destroy(s);
}
keyiter_destroy(i);

No reversing or random access allowed either; should be much simpler.

One could combine keyiter_create/keyiter_next in a similar fashion to
how strtok detects first v.s. subsequent invocations, but I think the
above API is a little clearer.

encode_for_posting needs to define who owns the memory returned, and how
to destroy it.

post_new_code and encode_for_posting check all the output/pointer
parameters against being NULL, but learn_from_remote doesn't.

The version number of the DLL should be increased to indicate that the
API changed incompatibly.

I'm not convinced that the Python bindings changes for verbose are the
correct way to go; they don't handle exceptions very well. It'd be best
if you removed the verbose part from the Python bindings, and I'll
work on a more automated and robust solution, and one that doesn't
require the host application to configure it, since I don't really want
to include that kind of debug logic in the production version of congruity.

Thanks!

-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
___
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel


Re: [concordance-devel] libconcord new full patch (Re: Next try for the big IR learning patch..)

2008-06-22 Thread Phil Dibowitz
Stephen Warren wrote:
 The version number of the DLL should be increased to indicate that the
 API changed incompatibly.

Oh - just as a side note, please don't do this in patches. There's no
need to increase it everytime a CHECKIN causes a change. At _release_
time, I'll compare the APIs and ABIs and adjust the so-version numbers
as appropriate based on the GNU library numbering scheme.

-- 
Phil Dibowitz [EMAIL PROTECTED]
Open Source software and tech docsInsanity Palace of Metallica
http://www.phildev.net/   http://www.ipom.com/

Never write it in C if you can do it in 'awk';
 Never do it in 'awk' if 'sed' can handle it;
 Never use 'sed' when 'tr' can do the job;
 Never invoke 'tr' when 'cat' is sufficient;
 Avoid using 'cat' whenever possible -- Taylor's Laws of Programming




signature.asc
Description: OpenPGP digital signature
-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php___
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel