Как получить доступ к имени ProtoField после объявления? - PullRequest
0 голосов
/ 25 августа 2018

Как я могу получить доступ к свойству name ProtoField после того, как я объявил его?

Например, что-то вроде:

myproto = Proto ("myproto","My Proto")

myproto.fields.foo = ProtoField.int8 ("myproto.foo", "Foo", base.DEC)

print (myproto.fields.foo.name)

Где я получаю вывод:

Foo

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Альтернативный метод, который немного более краткий:

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")
0 голосов
/ 28 августа 2018

Хорошо, это дерзкий и, конечно, не «правильный» способ сделать это, но, похоже, это работает.

Я обнаружил это, посмотрев на вывод

печать (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 
...