Как вы получаете доступ к имени ProtoField после объявления?
Как я могу получить доступ к свойству name ProtoField после того, как я его объявил?
Например, что-то вроде:
myproto = Proto ("myproto", "My Proto")
myproto.fields.foo = ProtoField.int8 ("myproto.foo", "Foo", base.DEC)
печать (myproto.fields.foo.name)
Где я получаю вывод:
Foo
2 ответа
Альтернативный метод, который немного более лаконичен:
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* myproto")
print(string.sub(fieldString, i + 2, j - (1 + string.len("myproto")))
РЕДАКТИРОВАТЬ: Или еще более простое решение, которое работает для любого протокола:
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* ")
print(string.sub(fieldString, i + 2, j - 1))
Конечно, 2-й метод работает только до тех пор, пока в имени поля нет пробелов. Так как это не всегда так, первый метод более надежен. Вот 1-й метод, заключенный в функцию, которую должен использовать любой диссектор:
-- The field is the field whose name you want to print.
-- The proto is the name of the relevant protocol
function printFieldName(field, protoStr)
local fieldString = tostring(field)
local i, j = string.find(fieldString, ": .* " .. protoStr)
print(string.sub(fieldString, i + 2, j - (1 + string.len(protoStr)))
end
... и вот оно используется:
printFieldName(myproto.fields.foo, "myproto")
printFieldName(someproto.fields.bar, "someproto")
Ладно, это дрянной, и, конечно, не "правильный" способ сделать это, но, похоже, это работает.
Я обнаружил это, посмотрев на вывод
печать (ToString(myproto.fields.foo))
Кажется, это показывает ценность каждого из членов ProtoField, но я не мог найти правильный способ доступа к ним. Поэтому вместо этого я решил разобрать строку. Эта функция будет возвращать 'Foo', но может быть адаптирована и для других полей.
function getname(field)
--First, convert the field into a string
--this is going to result in a long string with
--a bunch of info we dont need
local fieldString= tostring(field)
-- fieldString looks like:
-- ProtoField(188403): Foo myproto.foo base.DEC 0000000000000000 00000000 (null)
--Split the string on '.' characters
a,b=fieldString:match"([^.]*).(.*)"
--Split the first half of the previous result (a) on ':' characters
a,b=a:match"([^.]*):(.*)"
--At this point, b will equal " Foo myproto"
--and we want to strip out that abreviation "abvr" part
--Count the number of times spaces occur in the string
local spaceCount = select(2, string.gsub(b, " ", ""))
--Declare a counter
local counter = 0
--Declare the name we are going to return
local constructedName = ''
--Step though each word in (b) separated by spaces
for word in b:gmatch("%w+") do
--If we hav reached the last space, go ahead and return
if counter == spaceCount-1 then
return constructedName
end
--Add the current word to our name
constructedName = constructedName .. word .. " "
--Increment counter
counter = counter+1
end
end