decode msgpack in redis lua - lua

public class MsgPackInRedis {
private String ip;
private int port;
private String session;
private String protocol;
}
MsgPackInRedis msgPackStringInRedis = new MsgPackInRedis();
I encode a java object msgPackStringInRedis of class MsgPackInRedis with msgpack, then store in redis.
And I want to decode that in lua, which runs in redis, how can I get "session" ?
Can I do like this below, get session by index 3?
local msgPackObject = cmsgpack.unpack(msgPackStringInRedis)
local session = msgPackObject[3]

MessagePack is an encoding - think non-easily-readable JSON. In fact, this website does a back and forth translation between the two: http://kawanet.github.io/msgpack-lite/
Feeding your (0x94 0xc0 0x00 0xa4 0x41 0x42 0x43 0x44 0xc0) to the above website, you can see the JSON representation which looks like:
[
null,
0,
"ABCD",
null
]
You can test that in Redis' Lua as well, e.g. (note that Lua 5.1 accepts decimal byte representation, hence the different representation of the same payload in the example):
$ redis-cli EVAL "return(cmsgpack.unpack('\148\192\00\164\65\66\67\68\192')[3])" 0
"ABCD"
So frankly, I see no issue with your code. What is the problem that you are experiencing exactly?

Assuming that your MessagePack-ed data is stored in the String key called foo, this would do your bidding:
EVAL "return cmsgpack.unpack(redis.call('GET', KEYS[1]))" 1 foo
Note : the above assumes that the data is serialized as arrays. Returning an object will not work as Redis' protocol doesn't support that.

Related

Why jsonDecode in Dart has no type and no documentation?

As you can see in https://api.dart.dev/stable/2.7.1/dart-convert/jsonDecode.html, it has no type and no documentation. I don't know which methods I can invoke on the result neither I don't know which type to but on a parameter that should be a json object.
Why is Dart like this? And what are the advantages?
It does have documentation, and you are linking to it.
If you want it to have more documentation, then that is reasonable. The returned value is admittedly not documented very well.
The function jsonDecode is a shorthand for json.decode, which again forwards to JsonDecoder.convert.
It returns a "JSON value" object which depends on the JSON source that it decodes.
A "JSON value" can be any of:
* null
* an int
* a double
* a String
* a bool (true or false)
* a List<dynamic> containing zero or more JSON values.
* a Map<String, dynamic> mapping keys to JSON values.
Those are also the same values that are accepted by the JsonEncoder which converts object structures to JSON strings.
Since these types have no common superclass other than Object, the function cannot have a return type which is more specific than dynamic or Object.
The chosen return type is dynamic because the dynamic type allows the receiver to optimistically call any member on the value. They might know that the value will always be a map, so they can just do jsonParse(jsonSource)["key"] to look up a value. Obviously, if the source was not a JSON object, that call will fail.
If you don't know which type the result is, you have to check:
var data = jsonDecode(jsonSource);
if (data is Map<String, dynamic>) {
something something data["key"] something
} else if (data is List<dynamic>) {
something something list[2] something
} else ... etc ...
A valid JSON file is actually a valid Dart expression too. The value returned by jsonDecode is similar to the value you would get if you wrote the JSON code directly as Dart code (in Dart 1 it was exactly the same, in Dart 2, the Dart code might infer a more precise type for maps and lists).

Flutter - Remove escape sequence in dart

To decode API response string to JSON, json.decode() works fine.
This will parse a JSON string similar to
{ "Response" : {"Responsecode" : "1" , "Response" : "Success"}}
But in my case, the response comes in the serialized form like:
{\"Response\" : {\"Responsecode\" : \"0\" , \"Response\" : \"Success\"}}
json.decode() won’t work.
In Java, I used StringEscapeUtils.unescapeJson() for the same problem.
I searched for Dart but couldn’t find how to unescape characters in a string.
Edit:
Suppose, the value of key data is abc"de
So, its corresponding JSON would be {"data":"abc\"de"}
And hence during serialization, this json string is escaped to give {\"data\":\"abc\\\"de\"} as the response, which is sent by the API.
So, my intention is to remove the escape sequences, so that I can get the string {"data":"abc\"de"}, which would later be decoded using json.decode(). Removing the escape sequences was done using StringEscapeUtils.unescapeJson() in java.
json.decode can decode single strings too, so you should be able to just call it twice. The first time it'll return you a string (where the escape characters have been decoded) and the second time it'll decode that string into the map:
import 'dart:convert';
void main() {
var a = r'''"{\"Response\" : {\"Responsecode\" : \"0\" , \"Response\" : \"Success\"}}"''';
var b = json.decode(json.decode(a));
print(b['Response']['Responsecode']); // 0
print(b['Response']['Response']); // Success
}

How to load/save wxString from/to wxStream or wxMemoryBuffer?

I have my own class (nBuffer) like wxMemoryBuffer and I use it to load/save custom data, it's more convenient than using streams because I have a lot of overloaded methods for different data types based on these:
class nBuffer
{ // ...
bool wr(void* buf, long unsigned int length);// write
bool rd(void* buf, long unsigned int length);// read
}
I'm trying to implemets methods to load/save wxString from/to this buffer.
With wxWidgets 2.8 I've used the next code (simplified):
bool nBuffer::wrString(wxString s)
{ // save string:
int32 lng=s.Length()*4;
wr(&lng,4);// length
wr(s.GetData(),lng);// string itself
return true;
}
bool nBuffer::rdString(wxString &s)
{ // load string:
uint32 lng;
rd(&lng,4);// length
s.Alloc(lng);
rd(s.GetWriteBuf(lng),lng);// string itself
s.UngetWriteBuf();
s=s.Left(lng/4);
return true;
}
This code is not good because:
Is assumes there are 4 bytes of data for each string character (it might be less),
With wxWidgets 3.0, wxString.GetData() returns wxCStrData instead of *void, so the compiler fails on wr(s.GetData(),lng); and I have no idea of how to convert it to a simple byte buffer.
Strange, but I found nothing googling that for hours... Also I've found nothing useful in wxWidgets docs.
The questions are:
That is the preferred, correct and safe way to convert wxString to byte buffer,
The same about converting the byte buffer back to wxString.
For arbitrary wxStrings you need to serialize them in either UTF-8 or UTF-16 format. The former is a de facto standard for data exchange, so I advise to use it, but you could prefer UTF-16 if you know that your data is biased to the sort of characters that take less space in it than in UTF-8 and if space saving is important for you.
Assuming you use UTF-8, serializing is done using utf8_str() method:
wxScopedCharBuffer const utf8 = s.utf8_str();
wr(utf8.data(), utf8.length());
Deserializing is as simple as using wxString::FromUTF8(data, length).
For UTF-16 you would use general mb_str(wxMBConvUTF16) and wxString(data, wxMBConvUTF16, length) methods, which could also be used with wxMBConvUTF8, but the UTF-8-specific methods above are more convenient and, in some build configurations, more efficient.

.NET RSAKeyValue base64 private key to a single base64 private key

I am supplied the following RSA private key in the format
<RSAKeyValue>
<Modulus>XXXXXXXX</Modulus>
<Exponent>XXXXXXXX</Exponent>
<P>XXXXXXXX</P>
<Q>XXXXXXXX</Q>
<DP>XXXXXXXX</DP>
<DQ>XXXXXXXX</DQ>
<InverseQ>XXXXXXXXXX/InverseQ>
<D>XXXXXXXX</D>
</RSAKeyValue>
The XXXX are in Base64 format.
I want to know how to combine it all the XXXXXX bits to a single Base64 string.
With this single Base64 string i do the following:
1. Feed it to a TMemorStream
2. use Indy's TIdDecoderMIME class to decode Base64 from the MemoryStream
3. The decoded MemoryStream is then feed into CryptDecrypt function from wcrypt2.pas (a delphi wrapper of Microsoft's Cryptographic API) from Jedi
I know the solution for public key in the same format
<RSAKeyValue>
<Modulus>xqiYKv0umaLdmrKPyBfYmAfzZYVsvsOJyS4c1lBPjqpn7zh+XyxPXK7MxJkAlenQJM33M+ZYfmlPLya7JWXXTPviylEEtlmul9GshpX2caxWu2YO9vNIHRZYYau4ccbkm95iMyJi8KN2ANtqDwiJv55vcXZDqjPSDE4ap49xmog==</Modulus>
<Exponent>AAQC</Exponent>
</RSAKeyValue>
The solution is to add "BgIAAACkAABSU0ExAAQAAAE" + Exponent + Modulus
The result is:
BgIAAACkAABSU0ExAAQAAAEAAQCxqiYKv0umaLdmrKPyBfYmAfzZYVsvsOJyS4c1lBPjqpn7zh+XyxPXK7MxJkAlenQJM33M+ZYfmlPLya7JWXXTPviylEEtlmul9GshpX2caxWu2YO9vNIHRZYYau4ccbkm95iMyJi8KN2ANtqDwiJv55vcXZDqjPSDE4ap49xmog==
With the private key how do we combine it? I know it starts off like this:
"BwIAAACkAABSU0ExAAQAAAE" + Exponent + Modulus + ???????
The XXXX in the RSAKeyValue XML are in base64, just that i do not want to expose the details there. I want to know how do i combine all the XXXX base64 codes into a single base64 private key.
I suspect that this means that you are performing the base64 encoding line by line. It's much simpler to perform the encoding on the entire file.
For example you might do this as follows:
Load the file into a TStringList.
Extract a single string representing the file using the Text property of the string list.
Base64 encode that string.
Send it over the wire.
At the receiving end, decode the string.
Assign the string to the Text property of a string list.

Lua Error Attempt to perform arithmetic on local variable

Here is the function
calc.lua:
function foo(n)
return n*2
end
Here is my LuaJavaCall
L.getGlobal("foo");
L.pushJavaObject(8);
int retCode=L.pcall(1,1,0); // nResults)//L.pcall(1, 1,-2);
String errstr = L.toString(-1); // Attempt to perform arithmetic on local variable 'n'
Update: as indicated below I needed to use L.pushNumber(8.0) instead of L.pushJavaObject()
Try using L.pushNumber instead of L.pushJavaObject like this:
L.getGlobal("foo");
L.pushNumber(8.0);
int retCode = L.pcall(1,1,0);
String errstr = L.toString(-1);
Lua probably sees JavaObject as a type of 'userdata' in which case there are no predefined operations for it; Lua won't know what to do with a JavaObject * 2 since you didn't define how to handle it.
OTOH, Lua does know how to handle a number since that's a builtin primitive type. For the code snippet you presented, pushing a number would be the least painful way to get it working instead of writing extra code that tells Lua how to work with numbers wrapped inside a JavaObject.

Resources