package parser import ( "reflect" "strconv" ) // getDynamicLength gets length from another field with stack support func (p *Parser) getDynamicLength(fieldName string) int { if cachedValue, exists := p.fieldCache[fieldName]; exists { return p.valueToInt(cachedValue) } if p.currentStruct.IsValid() { if field := p.currentStruct.FieldByName(fieldName); field.IsValid() { return p.valueToInt(field.Interface()) } } for i := len(p.structStack) - 1; i >= 0; i-- { if field := p.structStack[i].FieldByName(fieldName); field.IsValid() { return p.valueToInt(field.Interface()) } } return 0 } // convertValue converts string to appropriate type for comparison func (p *Parser) convertValue(valueStr string, reference any) (any, error) { switch reference.(type) { case uint8, int8: if val, err := strconv.ParseInt(valueStr, 0, 8); err == nil { return uint8(val), nil } case uint16, int16: if val, err := strconv.ParseInt(valueStr, 0, 16); err == nil { return uint16(val), nil } case uint32, int32: if val, err := strconv.ParseInt(valueStr, 0, 32); err == nil { return uint32(val), nil } case uint64, int64: if val, err := strconv.ParseInt(valueStr, 0, 64); err == nil { return uint64(val), nil } case float32: if val, err := strconv.ParseFloat(valueStr, 32); err == nil { return float32(val), nil } case float64: if val, err := strconv.ParseFloat(valueStr, 64); err == nil { return val, nil } case string: return valueStr, nil } if val, err := strconv.ParseInt(valueStr, 0, 32); err == nil { return int(val), nil } return valueStr, nil } // compareValues performs comparison between two values func (p *Parser) compareValues(a, b any, op string) bool { aVal := p.valueToInt64(a) bVal := p.valueToInt64(b) switch op { case "==": return aVal == bVal case "!=": return aVal != bVal case ">": return aVal > bVal case ">=": return aVal >= bVal case "<": return aVal < bVal case "<=": return aVal <= bVal case "&": return (aVal & bVal) != 0 case "|": return (aVal | bVal) != 0 } return false } // valueToInt converts various types to int func (p *Parser) valueToInt(v any) int { switch val := v.(type) { case uint8: return int(val) case int8: return int(val) case uint16: return int(val) case int16: return int(val) case uint32: return int(val) case int32: return int(val) case uint64: return int(val) case int64: return int(val) case int: return val } return 0 } // valueToInt64 converts various types to int64 for comparison func (p *Parser) valueToInt64(v any) int64 { switch val := v.(type) { case uint8: return int64(val) case int8: return int64(val) case uint16: return int64(val) case int16: return int64(val) case uint32: return int64(val) case int32: return int64(val) case uint64: return int64(val) case int64: return val case int: return int64(val) case float32: return int64(val) case float64: return int64(val) } return 0 } // isTruthy checks if a value is truthy func (p *Parser) isTruthy(v any) bool { switch val := v.(type) { case bool: return val case uint8, int8, uint16, int16, uint32, int32, uint64, int64, int: return p.valueToInt64(val) != 0 case string: return val != "" } return false } // handleOversizedField handles fields that exceed their oversized value func (p *Parser) handleOversizedField(field reflect.Value, oversizedByte byte, length int) error { if field.Kind() == reflect.Slice { slice := reflect.MakeSlice(field.Type(), 1, 1) if slice.Len() > 0 { elem := slice.Index(0) if elem.CanSet() { switch elem.Kind() { case reflect.Uint8: elem.SetUint(uint64(oversizedByte)) case reflect.Int8: elem.SetInt(int64(int8(oversizedByte))) default: elem.SetUint(uint64(oversizedByte)) } } } field.Set(slice) } else { switch field.Kind() { case reflect.Uint8: field.SetUint(uint64(oversizedByte)) case reflect.Int8: field.SetInt(int64(int8(oversizedByte))) default: field.SetUint(uint64(oversizedByte)) } } return nil }