declare -g __versions_total=0
declare __packet_offset=0
+declare -g __cur_level=0
if [ $debug == "0" ]; then
echo_verbose() { true; }
fi
parse_version() {
+ local level="${1:- 1}"
declare -g __packet_version=$((2#${__packets:$__packet_offset:3}))
((__packet_offset+=3))
echo_verbose "Packet version: $__packet_version"
}
parse_type() {
+ local level="${1:- 1}"
declare -g __packet_type=$((2#${__packets:$__packet_offset:3}))
((__packet_offset+=3))
echo_verbose "Packet type: $__packet_type"
}
parse_literal() {
+ local level="${1:- 1}"
local keep_going=${__packets:$__packet_offset:1}
local binary_value=""
((__packet_offset+=1))
# if we're here, we're on to the last group
binary_value+=${__packets:$__packet_offset:4}
((__packet_offset+=4))
- declare -g __packet_literal=$((2#$binary_value))
- echo_verbose "Packet literal: $__packet_literal"
+ declare -g __packet_value=$((2#$binary_value))
+ echo_verbose "Packet literal: $__packet_value"
}
parse_operator() {
+ local level="${1:- 1}"
+ local ptype="${2:-}"
local len_type=$((2#${__packets:$__packet_offset:1}))
+ local number=0
((__packet_offset+=1))
case $len_type in
0)
- __packets_length=$((2#${__packets:$__packet_offset:15}))
+ number=$((2#${__packets:$__packet_offset:15}))
((__packet_offset+=15))
;;
1)
- __packets_count=$((2#${__packets:$__packet_offset:11}))
+ number=$((2#${__packets:$__packet_offset:11}))
((__packet_offset+=11))
;;
esac
+
+ case $ptype in
+ 0)
+ parse_sum $len_type $number
+ ;;
+ 1)
+ parse_product $len_type $number
+ ;;
+ 2)
+ parse_minimum $len_type $number
+ ;;
+ 3)
+ parse_maximum $len_type $number
+ ;;
+ 5)
+ parse_greaterthan $len_type $number
+ ;;
+ 6)
+ parse_lessthan $len_type $number
+ ;;
+ 7)
+ parse_equal $len_type $number
+ ;;
+ esac
+}
+
+parse_sum() {
+ local len_type=$1
+ local count=$2
+ local total=0
+ local id=$__packet_offset
+ local a=0
+
+ echo_verbose "[$id]: Doing a sum ($len_type - $count)"
+
+ case $len_type in
+ 0)
+ local end_offset=$((__packet_offset+$count))
+ while [ $__packet_offset -lt $end_offset ]; do
+ echo_verbose "[$id]: Getting sum sub packet"
+ parse_packet
+ ((total+=$__packet_value))
+ done
+ ;;
+ 1)
+ for (( a=0; a<$count; a++ )); do
+ echo_verbose "[$id]: Getting sum sub packet"
+ parse_packet
+ ((total+=$__packet_value))
+ done
+ ;;
+ esac
+
+ echo_verbose "[$id]: Sum total: $total (offset: $__packet_offset)"
+
+ declare -g __packet_value=$total
+}
+
+parse_product() {
+ local len_type=$1
+ local count=$2
+ local total=1
+ local id=$__packet_offset
+ local a=0
+
+ echo_verbose "[$id]: Doing a product ($len_type - $count)"
+
+ case $len_type in
+ 0)
+ local end_offset=$((__packet_offset+$count))
+ while [ $__packet_offset -lt $end_offset ]; do
+ echo_verbose "[$id]: Getting product sub packet"
+ parse_packet
+ ((total*=$__packet_value))
+ done
+ ;;
+ 1)
+ for (( a=0; a<$count; a++ )); do
+ echo_verbose "[$id]: Getting product sub packet"
+ parse_packet
+ ((total*=$__packet_value))
+ done
+ ;;
+ esac
+
+ echo_verbose "[$id]: Product total: $total (offset: $__packet_offset)"
+
+ declare -g __packet_value=$total
+}
+
+parse_minimum() {
+ local len_type=$1
+ local count=$2
+ local minimum=
+ local id=$__packet_offset
+ local a=0
+
+ echo_verbose "[$id]: Doing mimimum"
+
+ case $len_type in
+ 0)
+ local end_offset=$((__packet_offset+$count))
+ while [ $__packet_offset -lt $end_offset ]; do
+ echo_verbose "[$id]: Getting minimum sub packet"
+ parse_packet
+ if [ -z $minimum ] || [ $__packet_value -lt $minimum ]; then
+ minimum=$__packet_value
+ fi
+ done
+ ;;
+ 1)
+ for (( a=0; a<$count; a++ )); do
+ echo_verbose "[$id]: Getting minimum sub packet"
+ parse_packet
+ if [ -z $minimum ] || [ $__packet_value -lt $minimum ]; then
+ minimum=$__packet_value
+ fi
+ done
+ ;;
+ esac
+
+ echo_verbose "[$id]: Minimum value: $minimum (offset: $__packet_offset)"
+
+ declare -g __packet_value=$minimum
+}
+
+parse_maximum() {
+ local len_type=$1
+ local count=$2
+ local maximum=
+ local id=$__packet_offset
+ local a
+
+ echo_verbose "[$id]: Doing maximum ($len_type - $count)"
+
+ case $len_type in
+ 0)
+ local end_offset=$((__packet_offset+$count))
+ while [ $__packet_offset -lt $end_offset ]; do
+ echo_verbose "[$id]: Getting maximum sub packet"
+ parse_packet
+ if [ -z $maximum ] || [ $__packet_value -gt $maximum ]; then
+ maximum=$__packet_value
+ fi
+ done
+ ;;
+ 1)
+ for (( a=0; a<$count; a++ )); do
+ echo_verbose "[$id]: Getting maximum sub packet"
+ parse_packet
+ if [ -z $maximum ] || [ $__packet_value -gt $maximum ]; then
+ maximum=$__packet_value
+ fi
+ done
+ ;;
+ esac
+
+ echo_verbose "[$id]: Maximum value: $maximum (offset: $__packet_offset)"
+
+ declare -g __packet_value=$maximum
+}
+
+parse_greaterthan() {
+ local len_type=$1
+ local count=$2
+ local id=$__packet_offset
+
+ echo_verbose "[$id]: Doing >"
+
+ # we don't actually care, we know that it's exactly 2 sub packets that we want... so
+ parse_packet
+ local val1=$__packet_value
+ parse_packet
+ local val2=$__packet_value
+
+ if [ $val1 -gt $val2 ]; then
+ declare -g __packet_value=1
+ else
+ declare -g __packet_value=0
+ fi
+
+ echo_verbose "[$id]: Got $__packet_value (offset: $__packet_offset)"
+}
+
+parse_lessthan() {
+ local len_type=$1
+ local count=$2
+ local id=$__packet_offset
+
+ echo_verbose "[$id]: Doing <"
+
+ # we don't actually care, we know that it's exactly 2 sub packets that we want... so
+ parse_packet
+ local val1=$__packet_value
+ parse_packet
+ local val2=$__packet_value
+
+ if [ $val1 -lt $val2 ]; then
+ declare -g __packet_value=1
+ else
+ declare -g __packet_value=0
+ fi
+
+ echo_verbose "[$id]: Got $__packet_valuei (offset: $__packet_offset)"
+}
+
+parse_equal() {
+ local len_type=$1
+ local count=$2
+ local id=$__packet_offset
+
+ echo_verbose "[$id]: Doing ="
+
+ # we don't actually care, we know that it's exactly 2 sub packets that we want... so
+ parse_packet
+ local val1=$__packet_value
+ parse_packet
+ local val2=$__packet_value
+
+ if [ $val1 -eq $val2 ]; then
+ declare -g __packet_value=1
+ else
+ declare -g __packet_value=0
+ fi
+
+ echo_verbose "[$id]: Got $__packet_value (offset: $__packet_offset)"
+}
+
+parse_packet() {
+ parse_version && local pversion=$__packet_version
+ parse_type && local ptype=$__packet_type
+
+ ((__versions_total+=$pversion))
+
+ case $ptype in
+ 4)
+ parse_literal
+ ;;
+ *)
+ parse_operator $__cur_level $ptype
+ ;;
+ esac
}
parse_packets() {
+ local level="${1:- 1}"
# we'll first need the version and the type, so grab those
- local pversion
- local ptype
while [ $__packet_offset -lt ${#__packets} ]; do
- parse_version
- parse_type
- version=$__packet_version
- ptype=$__packet_type
-
- ((__versions_total+=$version))
-
- echo_verbose "Remaining: ${__packets:$__packet_offset}"
- case $ptype in
- 4)
- parse_literal
- ;;
- *)
- parse_operator
- ;;
- esac
+ parse_packet
if [ $(($__packet_offset+7)) -ge ${#__packets} ]; then
break
parse_packets
echo "Total: $__versions_total"
+echo "End value: $__packet_value"