summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author罗泽轩 <spacewanderlzx@gmail.com>2021-05-08 13:57:13 +0800
committerGitHub <noreply@github.com>2021-05-07 22:57:13 -0700
commit4525cd9c5609f41e6f82f219a8dfef89d73e207e (patch)
tree2e77e09b0bd544796cb72c3107ea9c47a5924239
parent47361baf61d635e65346d796c609d534e65d20d7 (diff)
downloadflatbuffers-4525cd9c5609f41e6f82f219a8dfef89d73e207e.tar.gz
flatbuffers-4525cd9c5609f41e6f82f219a8dfef89d73e207e.tar.bz2
flatbuffers-4525cd9c5609f41e6f82f219a8dfef89d73e207e.zip
[Lua] manipulate byte array as string (#6624)
* [Lua] manipulate byte array as string Sometimes it would be more effective than reading byte by byte * change according to the review * update
-rw-r--r--lua/flatbuffers/view.lua11
-rw-r--r--src/idl_gen_lua.cpp16
-rw-r--r--tests/MyGame/Example/Monster.lua15
-rw-r--r--tests/MyGame/Example/TypeAliases.lua3
-rw-r--r--tests/luatest.lua39
5 files changed, 84 insertions, 0 deletions
diff --git a/lua/flatbuffers/view.lua b/lua/flatbuffers/view.lua
index 105e967d..433f25c8 100644
--- a/lua/flatbuffers/view.lua
+++ b/lua/flatbuffers/view.lua
@@ -76,6 +76,17 @@ function mt:Vector(off)
return off + self:Get(N.UOffsetT, off) + 4
end
+function mt:VectorAsString(off, start, stop)
+ local o = self:Offset(off)
+ if o ~= 0 then
+ start = start or 1
+ stop = stop or self:VectorLen(o)
+ local a = self:Vector(o) + start - 1
+ return self.bytes:Slice(a, a + stop - start + 1)
+ end
+ return nil
+end
+
function mt:Union(t2, off)
assert(getmetatable(t2) == mt_name)
enforceOffset(off)
diff --git a/src/idl_gen_lua.cpp b/src/idl_gen_lua.cpp
index e7e78343..9efc435e 100644
--- a/src/idl_gen_lua.cpp
+++ b/src/idl_gen_lua.cpp
@@ -339,6 +339,18 @@ class LuaGenerator : public BaseGenerator {
code += EndFunc;
}
+ // Access a byte/ubyte vector as a string
+ void AccessByteVectorAsString(const StructDef &struct_def,
+ const FieldDef &field, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "AsString(start, stop)\n";
+ code += std::string(Indent) + "return " + SelfData + ":VectorAsString(" +
+ NumToString(field.value.offset) + ", start, stop)\n";
+ code += EndFunc;
+ }
+
// Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
@@ -499,6 +511,10 @@ class LuaGenerator : public BaseGenerator {
GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
} else {
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
+ if (vectortype.base_type == BASE_TYPE_CHAR ||
+ vectortype.base_type == BASE_TYPE_UCHAR) {
+ AccessByteVectorAsString(struct_def, field, code_ptr);
+ }
}
break;
}
diff --git a/tests/MyGame/Example/Monster.lua b/tests/MyGame/Example/Monster.lua
index fbd2c74e..26b59d3b 100644
--- a/tests/MyGame/Example/Monster.lua
+++ b/tests/MyGame/Example/Monster.lua
@@ -62,6 +62,9 @@ function Monster_mt:Inventory(j)
end
return 0
end
+function Monster_mt:InventoryAsString(start, stop)
+ return self.view:VectorAsString(14, start, stop)
+end
function Monster_mt:InventoryLength()
local o = self.view:Offset(14)
if o ~= 0 then
@@ -160,6 +163,9 @@ function Monster_mt:Testnestedflatbuffer(j)
end
return 0
end
+function Monster_mt:TestnestedflatbufferAsString(start, stop)
+ return self.view:VectorAsString(30, start, stop)
+end
function Monster_mt:TestnestedflatbufferLength()
local o = self.view:Offset(30)
if o ~= 0 then
@@ -315,6 +321,9 @@ function Monster_mt:Flex(j)
end
return 0
end
+function Monster_mt:FlexAsString(start, stop)
+ return self.view:VectorAsString(64, start, stop)
+end
function Monster_mt:FlexLength()
local o = self.view:Offset(64)
if o ~= 0 then
@@ -518,6 +527,9 @@ function Monster_mt:VectorOfEnums(j)
end
return 0
end
+function Monster_mt:VectorOfEnumsAsString(start, stop)
+ return self.view:VectorAsString(98, start, stop)
+end
function Monster_mt:VectorOfEnumsLength()
local o = self.view:Offset(98)
if o ~= 0 then
@@ -540,6 +552,9 @@ function Monster_mt:Testrequirednestedflatbuffer(j)
end
return 0
end
+function Monster_mt:TestrequirednestedflatbufferAsString(start, stop)
+ return self.view:VectorAsString(102, start, stop)
+end
function Monster_mt:TestrequirednestedflatbufferLength()
local o = self.view:Offset(102)
if o ~= 0 then
diff --git a/tests/MyGame/Example/TypeAliases.lua b/tests/MyGame/Example/TypeAliases.lua
index 91c62c44..e9c680b1 100644
--- a/tests/MyGame/Example/TypeAliases.lua
+++ b/tests/MyGame/Example/TypeAliases.lua
@@ -102,6 +102,9 @@ function TypeAliases_mt:V8(j)
end
return 0
end
+function TypeAliases_mt:V8AsString(start, stop)
+ return self.view:VectorAsString(24, start, stop)
+end
function TypeAliases_mt:V8Length()
local o = self.view:Offset(24)
if o ~= 0 then
diff --git a/tests/luatest.lua b/tests/luatest.lua
index 26b0a98d..1a70f5ff 100644
--- a/tests/luatest.lua
+++ b/tests/luatest.lua
@@ -282,6 +282,41 @@ local function getRootAs_canAcceptString()
assert(mon:Hp() == 80, "Monster Hp is not 80")
end
+local function testAccessByteVectorAsString()
+ local f = assert(io.open('monsterdata_test.mon', 'rb'))
+ local wireData = f:read("*a")
+ f:close()
+ local mon = monster.GetRootAsMonster(wireData, 0)
+ -- the data of byte array Inventory is [0, 1, 2, 3, 4]
+ local s = mon:InventoryAsString(1, 3)
+ assert(#s == 3)
+ for i = 1, #s do
+ assert(string.byte(s, i) == i - 1)
+ end
+
+ local s = mon:InventoryAsString(2, 5)
+ assert(#s == 4)
+ for i = 1, #s do
+ assert(string.byte(s, i) == i)
+ end
+
+ local s = mon:InventoryAsString(5, 5)
+ assert(#s == 1)
+ assert(string.byte(s, 1) == 4)
+
+ local s = mon:InventoryAsString(2)
+ assert(#s == 4)
+ for i = 1, #s do
+ assert(string.byte(s, i) == i)
+ end
+
+ local s = mon:InventoryAsString()
+ assert(#s == 5)
+ for i = 1, #s do
+ assert(string.byte(s, i) == i - 1)
+ end
+end
+
local tests =
{
{
@@ -305,6 +340,10 @@ local tests =
f = getRootAs_canAcceptString,
d = "Tests that GetRootAs<type>() generated methods accept strings"
},
+ {
+ f = testAccessByteVectorAsString,
+ d = "Access byte vector as string"
+ },
}
local benchmarks =