1. Passing Map to Remote App

I want to pass a map from a server to a client. Anybody have any good ideas on how to best do that?

So far, I figure the best way is to pass a sprint(pairs(map)) and then use new_from_kv_pairs() at the other end.

Any other ideas?

new topic     » topic index » view message » categorize

2. Re: Passing Map to Remote App

You can probably use save_map() and load_map():

map a = map:new_from_kvpairs({ 
    {"name","Jerry Smith"}, 
    {"age",`16`}, -- note, numbers must be quoted somehow; 
    {"bal",`49.95`}, 
    {"city","Buffalo NY"}, 
    {"phone","000-555-1212"}, 
    {"pix","thumbnails/Jerry.jpg"}}) 
 
save_map(a,canonical_path("~/demos/resources/Jerry.map"),SM_RAW) 

If you use SM_RAW mode, the output will be like this:

þþ;9:B9<:;:B9B=Bþ:=7:79)mnnuxyvnw})1>A?:C>@:@B:@:mknm5);9:>69;69;):=C:AC><2þþwjvnþjpnþyrþkjuþyqxwnþlr}‚þþSn{{‚)\vr}qþ:?þ}q~vkwjru|8Sn{{‚7sypþ=B7B>þ9996>>>6:;:;þ 
K~oojux)Wb 
There are lots of non-readable characters in there: ETX,ACK,EOT,VT, etc.

If you use SM_TEXT, then the results are human-readable:

\#22name\#22 = \#22Jerry Smith\#22 
\#22age\#22 = \#2216\#22 
\#22pix\#22 = \#22thumbnails/Jerry.jpg\#22 
\#22bal\#22 = \#2249.95\#22 
\#22phone\#22 = \#22000\-555\-1212\#22 
\#22city\#22 = \#22Buffalo NY\#22 

Either way:

object x = load_map("resources/Jerry.map") 
display(map:get(x,"name")) -- displays Jerry Smith 

Which mode may be easier/safer to transfer is left up to your experimentation. The raw mode map may need to be encoded in order to transfer it. What transport protocol do you intend to use?

new topic     » goto parent     » topic index » view message » categorize

3. Re: Passing Map to Remote App

irv said...

You can probably use save_map() and load_map():

I had considered the save/load method before deciding to not go that way, but only because there are file reads and writes that can otherwise be eliminated.

  1. load saved map file as a raw file
  2. send it to the client
  3. client saves it as a file
  4. client uses load_map()


or I guess you could

  1. send url of saved map file to client
  2. client retrieves it (e.g., HttpGet(url_of_map_file)) and saves it as a file
  3. client uses load_map()


What I'm doing for now is:

  1. load_map()
  2. var = pairs( my_map )
  3. send it to client
  4. client uses map_from_kv_pairs()


That seems to be the quickest and easiest so far.

Best case scenario might be:

  1. var = save_map(my_map) -- just like sprint() but for maps
  2. send it to client
  3. var = load_map(data) -- just like value() but for maps
new topic     » goto parent     » topic index » view message » categorize

4. Re: Passing Map to Remote App

Probably the best way is something to do with sockets.

(That previous sentence is everything I know about sockets, unfortunately smile)

new topic     » goto parent     » topic index » view message » categorize

5. Re: Passing Map to Remote App

irv said...

Probably the best way is something to do with sockets.

(That previous sentence is everything I know about sockets, unfortunately smile)

lol!

You're probably right!

And same! grin

new topic     » goto parent     » topic index » view message » categorize

6. Re: Passing Map to Remote App

It looks like save_map() just uses the serialize() function.

https://github.com/OpenEuphoria/euphoria/blob/master/include/std/map.e#L1433

if type_ = SM_RAW then 
    puts(file_handle_, serialize:serialize({ 
        2, -- saved map version 
        datetime:format(now_gmt(), "%Y%m%d%H%M%S" ), -- date of this saved map 
        info:version_string()} -- Euphoria version 
        )) 
    puts(file_handle_, serialize:serialize(keys_)) 
    puts(file_handle_, serialize:serialize(values_)) 
else 

So here are the (untested and very basic) in-memory equivalents:

include std/map.e 
include std/datetime.e 
include std/serialize.e 
include euphoria/info.e 
 
function serialize_map( map m ) 
 
    sequence keys = map:keys( m ) 
    sequence values = map:values( m ) 
 
    sequence data = {} 
 
    data &= serialize:serialize({ 2, 
        datetime:format(now_gmt(), "%Y%m%d%H%M%S" ), 
        info:version_string() 
    }) 
 
    data &= serialize:serialize( keys ) 
    data &= serialize:serialize( values ) 
 
    return data 
end function 
 
function deserialize_map( sequence data ) 
 
    integer pos = 1 
    object info, keys, value 
 
    {info,pos} = deserialize( data, pos ) 
    {keys,pos} = deserialize( data, pos ) 
    {values,pos} = deserialize( data, pos ) 
 
    if atom( info ) or atom( keys ) or atom( values ) then 
        return 0 
    end if 
 
    map m = map:new() 
 
    for i = 1 to length( keys ) do 
        map:put( m, keys[i], value[i] ) 
    end for 
 
    return m 
end function 

-Greg

new topic     » goto parent     » topic index » view message » categorize

7. Re: Passing Map to Remote App

ghaberek said...

It looks like save_map() just uses the serialize() function.

Interesting. BENCHMARK TIME!

This would be on the client (not tested):

-- on client 
object data = HttpGet("mysite.com/api/map/my_map") 
data = decode(data) 
{res,data} = value(data) 
data = map_from_kv_pairs(data) 

I'm currently doing basically this on the server (and it's working fine):

-- on server 
object data = load_map( map:get(request_object,"map_id" ) ) -- "my_map" 
data = pairs(data) 
return encode(sprint(data)) -- encode can be base64() and/or encryption 

Does sprint() do a serialize too, I wonder?

new topic     » goto parent     » topic index » view message » categorize

8. Re: Passing Map to Remote App

euphoric said...

Does sprint() do a serialize too, I wonder?

Technically sprint() and value() are a form of (de)serialization, yes. The advantage to using serialize() over sprint() is that the binary output of serialize() will be much smaller.

-Greg

new topic     » goto parent     » topic index » view message » categorize

9. Re: Passing Map to Remote App

ghaberek said...
euphoric said...

Does sprint() do a serialize too, I wonder?

Technically sprint() and value() are a form of (de)serialization, yes. The advantage to using serialize() over sprint() is that the binary output of serialize() will be much smaller.

Sweet. I'm going to give this a try today.

new topic     » goto parent     » topic index » view message » categorize

10. Re: Passing Map to Remote App

euphoric said...
return encode(sprint(data)) -- encode can be base64() and/or encryption 

Does sprint() do a serialize too, I wonder?

If your keys are all strings, then it is probably worth considering json as well. You can try the phix json module at least at some point I wrote on that page that it works on OE.

new topic     » goto parent     » topic index » view message » categorize

11. Re: Passing Map to Remote App

petelomax said...
euphoric said...
return encode(sprint(data)) -- encode can be base64() and/or encryption 

Does sprint() do a serialize too, I wonder?

If your keys are all strings, then it is probably worth considering json as well. You can try the phix json module at least at some point I wrote on that page that it works on OE.

Thanks, pete!

Fortunately, all the apps being used here are OE-based, so I can just pass OE objects. I will have to go JSON at some point, I'm sure, so I'll keep that in mind.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu