<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace DarkMultiPlayer
{
    class ConfigNodeSerializer
    {
        private delegate void WriteNodeDelegate(ConfigNode configNode, StreamWriter writer);
        private delegate List<string[]> PreFormatConfigDelegate(string[] cfgData);
        private delegate ConfigNode RecurseFormatDelegate(List<string[]> cfg);

        private WriteNodeDelegate WriteNodeThunk;
        private PreFormatConfigDelegate PreFormatConfigThunk;
        private RecurseFormatDelegate RecurseFormatThunk;

        public ConfigNodeSerializer()
        {
            CreateDelegates();
        }

        private void CreateDelegates()
        {
            try
            {
                Type configNodeType = typeof(ConfigNode);
                var writeNodeMethodInfo = configNodeType.GetMethod("WriteNode", BindingFlags.NonPublic | BindingFlags.Instance);
                
                //pass null for instance so we only do the slower reflection part once ever, then provide the instance at runtime
                WriteNodeThunk = (WriteNodeDelegate)Delegate.CreateDelegate(configNodeType, null, writeNodeMethodInfo);

                //these ones really are static and won't have a instance first parameter 
                var preFormatConfigMethodInfo = configNodeType.GetMethod("PreFormatConfig", BindingFlags.NonPublic | BindingFlags.Static);
                PreFormatConfigThunk = (PreFormatConfigDelegate)Delegate.CreateDelegate(configNodeType, null, preFormatConfigMethodInfo);

                var recurseFormatMethodInfo = configNodeType.GetMethod("RecurseFormat", BindingFlags.NonPublic | BindingFlags.Static);
                RecurseFormatThunk = (RecurseFormatDelegate)Delegate.CreateDelegate(configNodeType, null, recurseFormatMethodInfo);
            }
            catch (Exception ex)
            {
                //maybe older or newer KSP version with different data?
                DarkLog.Debug("Can't create delegates for ConfigNode serialization. Falling back to temp file. Exception: " + ex.ToString());
            }
        }

        public byte[] Serialize(ConfigNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (WriteNodeThunk == null)
            {
                //if WriteNodeThunk wasn't set in the constructor, can't reflect into it
                //Use dogey hack fallback
                return ConvertConfigNodeToByteArray(node);
            }

            //otherwise, call the insides of what ConfigNode would have called if we said Save(filename)
            using (var stream = new MemoryStream())
            {
                using (var writer = new StreamWriter(stream))<commit_msg>Fixed issue with ambiguous reflection error.<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace DarkMultiPlayer
{
    class ConfigNodeSerializer
    {
        private delegate void WriteNodeDelegate(ConfigNode configNode, StreamWriter writer);
        private delegate List<string[]> PreFormatConfigDelegate(string[] cfgData);
        private delegate ConfigNode RecurseFormatDelegate(List<string[]> cfg);

        private WriteNodeDelegate WriteNodeThunk;
        private PreFormatConfigDelegate PreFormatConfigThunk;
        private RecurseFormatDelegate RecurseFormatThunk;

        public ConfigNodeSerializer()
        {
            CreateDelegates();
        }

        private void CreateDelegates()
        {
            try
            {
                DarkLog.Debug("ConfigNodeSerializer creating delegates...WriteNode...");
                Type configNodeType = typeof(ConfigNode);
                var writeNodeMethodInfo = configNodeType.GetMethod("WriteNode", BindingFlags.NonPublic | BindingFlags.Instance);
                
                //pass null for instance so we only do the slower reflection part once ever, then provide the instance at runtime
                WriteNodeThunk = (WriteNodeDelegate)Delegate.CreateDelegate(typeof(WriteNodeDelegate), null, writeNodeMethodInfo);

                DarkLog.Debug("ConfigNodeSerializer creating delegates...PreFormatConfig...");
                //these ones really are static and won't have a instance first parameter 
                var preFormatConfigMethodInfo = configNodeType.GetMethod("PreFormatConfig", BindingFlags.NonPublic | BindingFlags.Static);
                PreFormatConfigThunk = (PreFormatConfigDelegate)Delegate.CreateDelegate(typeof(PreFormatConfigDelegate), null, preFormatConfigMethodInfo);

                DarkLog.Debug("ConfigNodeSerializer creating delegates...RecurseFormat...");
                var recurseFormatMethodInfo = configNodeType.GetMethod("RecurseFormat", BindingFlags.NonPublic | BindingFlags.Static, null, new[] { typeof(List<string[]>) }, null);
                RecurseFormatThunk = (RecurseFormatDelegate)Delegate.CreateDelegate(typeof(RecurseFormatDelegate), null, recurseFormatMethodInfo);

                DarkLog.Debug("ConfigNodeSerializer delegates ready!");
            }
            catch (Exception ex)
            {
                //maybe older or newer KSP version with different data?
                DarkLog.Debug("Can't create delegates for ConfigNode serialization. Falling back to temp file. Exception: " + ex.ToString());
            }
        }

        public byte[] Serialize(ConfigNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (WriteNodeThunk == null)
            {
                //if WriteNodeThunk wasn't set in the constructor, can't reflect into it
                //Use dogey hack fallback
                return ConvertConfigNodeToByteArray(node);
            }

            //otherwise, call the insides of what ConfigNode would have called if we said Save(filename)
            using (var stream = new MemoryStream())
            {
                using (var writer = new StreamWriter(stream))
{'fraction_non_alphanumeric': 0.07220971373431971, 'fraction_numerical': 0.0, 'mean_word_length': 2.4321192052980134, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3491795', 'n_tokens_mistral': 1471, 'n_tokens_neox': 1372, 'n_words': 400}