Jump to content

"Format Into String" with collection of parameters


Recommended Posts

I want to decouple the producer of a set of data from the consumer which turns the data into a formatted string. The producer should run super fast, so I don't want it to spend effort formatting the data into a string; just throw the parameters (which the producer knows but the consumer doesn't) into a data structure and send that to the consumer. The consumer should be bindable to any shape of producer, so it doesn't want to know which parameters it'll get or how it should format them.

 

This should be straightforward. I can send a "format string" along with the parameters so the consumer does whatever it's told by each producer. But LV's Format Into String primitive requires a fixed number of parameters at compile time! I'm trying to roll my own using regex or the tokenizer, but I realize I'll have to implement the whole format specifier syntax if I want it to work generically.

 

Can anyone think of an easier solution? Preferably one that doesn't establish an external dependency on my code...I don't want to have to ship a VIPM with its own license terms or install a new .so/daemon on the cRIO.

Link to comment

Is some restriction of the format specifier syntax acceptable? Namely, do you need to support $ order? Do you need to output some argument multiple times? If the correspondence parameter -> formatted  form is 1:1, a loop on an array of variants containing arguments, plus one array of format strings could perhaps do? Or, one array of clusters (index of parameter, format string) to account for reshuffling and repetition, and then concatenate as suggested above?

Edited by ensegre
  • Like 1
Link to comment

You're both onto what I've been working on since I posted. It's not as bad as I feared. I'll have to enforce ordered parameters, at least in the first pass, to minimize string mangling. Let me hammer on it a little more, and I'll try to upload a version that uses an array of variants for your review.

Link to comment

OpenG has a similar function in its String library for formatting a Variant into a String, though not for splitting up a multi-variable format.  Like you, they've chosen to implement a subset of the possible formatting commands.

 

Alternatively, you might have success with an XNode which effectively scripts the wiring between Unbundle (assuming your data is in a cluster) and Format.

Link to comment

OK, so here's a very quick-and-dirty XNode to do what I think you're wanting.  Don't use in any code you care lots about, though it should be ok if you always wire it up properly - i.e. errors are ignored, not handled :)

FormatCluster.zip

FormatCluster.zip

 

Edited by GregSands
File no longer linked to with site upgrade
Link to comment

Fast producer, extremely flexible consumer?
 
Object queue (yeah LVOOP is a good choice here).
 
Allows fully flexible parsing with minimal overhead in the producer (deals with no DD VIs).  Receiver doesn't need to know ANYTHING about the formatting.

 

BTW if you're thinking you can't send objecty by RT-FIFO, just send a DVR of the object instead.

String formatter.zip

Edited by shoneill
  • Like 1
Link to comment

OpenG has a similar function in its String library for formatting a Variant into a String, though not for splitting up a multi-variable format.  Like you, they've chosen to implement a subset of the possible formatting commands.

 

...(assuming your data is in a cluster)...

Insofar as I'm using Format Into String to do the actual formatting, I don't have to implement any of the formatting commands. I just have to scrape the variable's data type so I can cast it from the Variant.

 

If my data were a cluster, the consumer would have to know its structure (data types, data names, shape of memory structure) at compile time. That would completely undo the objective of decoupling consumer from producer. ;)

 

OK, so here's a very quick-and-dirty XNode to do what I think you're wanting.  Don't use in any code you care lots about, though it should be ok if you always wire it up properly - i.e. errors are ignored, not handled :)

(Thanks, but if I can't use it in code I care about, what good is it? :lol:)  While this, when completely fleshed out, allows me to easily write a consumer that's correctly coupled to a particular producer at edit time, it still establishes coupling. My data producer won't always be a LV app, or even an app written by my team. I want to completely abstract the type and arrangement of the inbound data set from the consumer. It should just receive a "collection" and see that turned into a formatted string.

 

Fast producer, extremely flexible consumer?

 

Object queue (yeah LVOOP is a good choice here).

Good point: By embedding the "format this data" algorithm into the data itself (via a method on the abstract type and data in the concrete type), I can hand abstract data to the consumer and let the data format itself. In a high-level sense, that's what I've done with my Variant implementation: The abstract data set is an array of Variants (which itself could be structure as a Variant if I wanted to get even more abstract about the structure), and the formatting algorithm is abstracted into a string provided with the data and a function (Format Into String) that processes the data.

 

The queue is just a transport mechanism for getting the data and algorithm over to the consumer. Assuming the producer is always LV code, the queue is one of many good choices. On that note, since my producer isn't always LV code, a LV Object might limit my implementation, too. (I'd have to convert the data from another type into a LV Object, requiring knowledge of the concrete data type in the consumer.) But for LV-to-LV implementation, a queue of objects is a great way to go.

Edited by Stobber
Link to comment

OK, I think I'm not fully understanding what you're trying to do, or even what a "collection" is.  Your data is not in a Variant, not in a cluster, not in a class, perhaps not even in a LabVIEW type.  Is it just a sequence of bytes, and you're using the format string to tell your Formatter how to interpret those bytes?

In which case, going back to your first post, it seems to me that you do have to write your own implementation, though you can choose how general or specific you want to make it.  But there's no advantage necessarily in being tied to the LabVIEW format syntax - your requirements may be substantially less, or greater, than what it provides.  The code you originally provided seems entirely reasonable then, with the small adjustment of interpreting raw bytes rather than a variant.

I guess you may also want to consider the option of sending the formatting only once (essentially defining the String representation of your data "object"), and reusing it for all of the data, especially as it sounds as though your producer is providing a lot of data very quickly, too fast to do the formatting itself.  That sounds sortof like registering an object with your Formatter, and then just telling it the following data is of that type.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.