1. Passing Map to Remote App
- Posted by euphoric (admin) Mar 12, 2019
- 1248 views
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?
2. Re: Passing Map to Remote App
- Posted by irv Mar 12, 2019
- 1227 views
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)WbThere 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?
3. Re: Passing Map to Remote App
- Posted by euphoric (admin) Mar 12, 2019
- 1246 views
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.
- load saved map file as a raw file
- send it to the client
- client saves it as a file
- client uses load_map()
or I guess you could
- send url of saved map file to client
- client retrieves it (e.g., HttpGet(url_of_map_file)) and saves it as a file
- client uses load_map()
What I'm doing for now is:
- load_map()
- var = pairs( my_map )
- send it to client
- client uses map_from_kv_pairs()
That seems to be the quickest and easiest so far.
Best case scenario might be:
- var = save_map(my_map) -- just like sprint() but for maps
- send it to client
- var = load_map(data) -- just like value() but for maps
4. Re: Passing Map to Remote App
- Posted by irv Mar 12, 2019
- 1212 views
Probably the best way is something to do with sockets.
(That previous sentence is everything I know about sockets, unfortunately )
5. Re: Passing Map to Remote App
- Posted by euphoric (admin) Mar 12, 2019
- 1226 views
Probably the best way is something to do with sockets.
(That previous sentence is everything I know about sockets, unfortunately )
lol!
You're probably right!
And same!
6. Re: Passing Map to Remote App
- Posted by ghaberek (admin) Mar 12, 2019
- 1272 views
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
7. Re: Passing Map to Remote App
- Posted by euphoric (admin) Mar 12, 2019
- 1207 views
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?
8. Re: Passing Map to Remote App
- Posted by ghaberek (admin) Mar 13, 2019
- 1180 views
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
9. Re: Passing Map to Remote App
- Posted by euphoric (admin) Mar 13, 2019
- 1164 views
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.
10. Re: Passing Map to Remote App
- Posted by petelomax Mar 14, 2019
- 1136 views
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.
11. Re: Passing Map to Remote App
- Posted by euphoric (admin) Mar 14, 2019
- 1150 views
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.