<commit_before>﻿using System;
using System.Text;
using System.Collections.Generic;
using static Secs4Net.Item;
using System.Runtime.CompilerServices;

namespace Secs4Net
{
    public static class SecsExtension
    {
        public static string ToHexString(this byte[] value)
        {
            if (value.Length == 0) return string.Empty;
            int length = value.Length * 3;
            char[] chs = new char[length];
            for (int ci = 0, i = 0; ci < length; ci += 3)
            {
                byte num = value[i++];
                chs[ci] = GetHexValue(num / 0x10);
                chs[ci + 1] = GetHexValue(num % 0x10);
                chs[ci + 2] = ' ';
            }
            return new string(chs, 0, length - 1);
        }

        static char GetHexValue(int i) => (i < 10) ? (char)(i + 0x30) : (char)((i - 10) + 0x41);

        #region Bytes To Item Value
        internal static Item BytesDecode(this SecsFormat format)
        {
            switch (format)
            {
                case SecsFormat.ASCII: return A();
                case SecsFormat.JIS8: return J();
                case SecsFormat.Boolean: return Boolean();
                case SecsFormat.Binary: return B();
                case SecsFormat.U1: return U1();
                case SecsFormat.U2: return U2();
                case SecsFormat.U4: return U4();
                case SecsFormat.U8: return U8();
                case SecsFormat.I1: return I1();
                case SecsFormat.I2: return I2();
                case SecsFormat.I4: return I4();
                case SecsFormat.I8: return I8();
                case SecsFormat.F4: return F4();
                case SecsFormat.F8: return F8();
            }
            throw new ArgumentException(@"Invalid format:" + format, nameof(format));
        }
<commit_msg>add pattern match extension method for tests the message is compatible with another one.<commit_after>﻿using System;
using System.Text;
using System.Collections.Generic;
using static Secs4Net.Item;
using System.Runtime.CompilerServices;
using System.Linq;

namespace Secs4Net
{
    public static class SecsExtension
    {
        public static string ToHexString(this byte[] value)
        {
            if (value.Length == 0) return string.Empty;
            int length = value.Length * 3;
            char[] chs = new char[length];
            for (int ci = 0, i = 0; ci < length; ci += 3)
            {
                byte num = value[i++];
                chs[ci] = GetHexValue(num / 0x10);
                chs[ci + 1] = GetHexValue(num % 0x10);
                chs[ci + 2] = ' ';
            }
            return new string(chs, 0, length - 1);
        }

        static char GetHexValue(int i) => (i < 10) ? (char)(i + 0x30) : (char)((i - 10) + 0x41);

        public static bool IsMatch(this SecsMessage src, SecsMessage target)
        {
            if (src.S != target.S) return false;
            if (src.F != target.F) return false;
            if (target.SecsItem == null) return true;
            return src.SecsItem.IsMatch(target.SecsItem);
        }

        public static bool IsMatch(this Item src, Item target)
        {
            if (src.Format != target.Format) return false;
            if (target.Count == 0) return true;
            if (src.Count != target.Count) return false;

            switch (target.Format)
            {
                case SecsFormat.List:
                    return src.Items.Zip(target.Items, (a, b) => a.IsMatch(b)).All(match => match);
                default:
                    return Unsafe.As<byte[]>(src.Values).SequenceEqual(Unsafe.As<byte[]>(target));
            }
        }

        #region Bytes To Item Value
        internal static Item BytesDecode(this SecsFormat format)
        {
            switch (format)
            {
                case SecsFormat.ASCII: return A();
                case SecsFormat.JIS8: return J();
                case SecsFormat.Boolean: return Boolean();
                case SecsFormat.Binary: return B();
                case SecsFormat.U1: return U1();
                case SecsFormat.U2: return U2();
                case SecsFormat.U4: return U4();
                case SecsFormat.U8: return U8();
                case SecsFormat.I1: return I1();
                case SecsFormat.I2: return I2();
                case SecsFormat.I4: return I4();
                case SecsFormat.I8: return I8();
                case SecsFormat.F4: return F4();
                case SecsFormat.F8: return F8();
            }
            throw new ArgumentException(@"Invalid format:" + format, nameof(format));
        }

{'fraction_non_alphanumeric': 0.10866752910737387, 'fraction_numerical': 0.020914187149633463, 'mean_word_length': 1.6120495495495495, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5888304', 'n_tokens_mistral': 1386, 'n_tokens_neox': 1289, 'n_words': 376}