in packetbeat/protos/amqp/amqp_fields.go [77:201]
func fieldUnmarshal(table mapstr.M, data []byte, offset uint32, length uint32, index int) (err bool) {
var name string
if offset >= length {
return false
}
// get name of the field. If it's an array, it will be the index parameter as a
// string. If it's a table, it will be the name of the field.
if index < 0 {
fieldName, offsetTemp, err := getShortString(data, offset+1, uint32(data[offset]))
if err {
logp.Warn("Failed to get short string in table")
return true
}
name = fieldName
offset = offsetTemp
} else {
name = strconv.Itoa(index)
index++
}
switch data[offset] {
case boolean:
if data[offset+1] == 1 {
table[name] = true
} else {
table[name] = false
}
offset += 2
case shortShortInt:
table[name] = int8(data[offset+1])
offset += 2
case shortShortUint:
table[name] = uint8(data[offset+1])
offset += 2
case shortInt:
table[name] = int16(binary.BigEndian.Uint16(data[offset+1 : offset+3]))
offset += 3
case shortUint:
table[name] = binary.BigEndian.Uint16(data[offset+1 : offset+3])
offset += 3
case longInt:
table[name] = int(binary.BigEndian.Uint32(data[offset+1 : offset+5]))
offset += 5
case longUint:
table[name] = binary.BigEndian.Uint32(data[offset+1 : offset+5])
offset += 5
case longLongInt:
table[name] = int64(binary.BigEndian.Uint64(data[offset+1 : offset+9]))
offset += 9
case longLongUint:
table[name] = binary.BigEndian.Uint64(data[offset+1 : offset+9])
offset += 9
case float:
bits := binary.BigEndian.Uint32(data[offset+1 : offset+5])
table[name] = math.Float32frombits(bits)
offset += 5
case double:
bits := binary.BigEndian.Uint64(data[offset+1 : offset+9])
table[name] = math.Float64frombits(bits)
offset += 9
case decimal:
scale := data[offset+1]
val := strings.Split(strconv.Itoa(int(binary.BigEndian.Uint32(data[offset+2:offset+6]))), "")
ret := make([]string, len(val)+1)
for i, j := 0, 0; i < len(val); i++ {
if i == len(val)-int(scale) {
ret[j] = "."
j++
}
ret[j] = val[i]
j++
}
table[name] = strings.Join(ret, "")
offset += 6
case shortString:
s, next, err := getShortString(data, offset+2, uint32(data[offset+1]))
if err {
logp.Warn("Failed to get short string in table")
return true
}
table[name] = s
offset = next
case longString:
s, next, err := getShortString(data, offset+5, binary.BigEndian.Uint32(data[offset+1:offset+5]))
if err {
logp.Warn("Failed to get long string in table")
return true
}
table[name] = s
offset = next
case fieldArray:
newMap := mapstr.M{}
next, err, _ := getArray(newMap, data, offset+1)
if err {
return true
}
table[name] = newMap
offset = next
case timestamp:
t := time.Unix(int64(binary.BigEndian.Uint64(data[offset+1:offset+9])), 0)
table[name] = t.Format(amqpTimeLayout)
offset += 9
case fieldTable:
newMap := mapstr.M{}
next, err, _ := getTable(newMap, data, offset+1)
if err {
return true
}
table[name] = newMap
offset = next
case noField:
table[name] = nil
offset++
case byteArray:
size := binary.BigEndian.Uint32(data[offset+1 : offset+5])
table[name] = bodyToByteArray(data[offset+1+size : offset+5+size])
offset += 5 + size
default:
// unknown field
return true
}
// advance to next field recursively
return fieldUnmarshal(table, data, offset, length, index)
}