<commit_before>﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using PeNet.Header.Pe;

namespace PeNet
{
    /// <summary>
    /// Extensions method to work make the work with buffers 
    /// and addresses easier.
    /// </summary>
    public static class ExtensionMethods
    {
        /// <summary>
        ///     Map an virtual address to the raw file address.
        /// </summary>
        /// <param name="va">Virtual Address</param>
        /// <param name="sectionHeaders">Section Headers</param>
        /// <returns>Raw file address.</returns>
        public static ulong VaToOffset(this ulong va, ICollection<ImageSectionHeader> sectionHeaders)
        {
            var rva= va - sectionHeaders.First().ImageBaseAddress;
            return RvaToOffset(rva, sectionHeaders);
        }

        /// <summary>
        ///     Map an relative virtual address to the raw file address.
        /// </summary>
        /// <param name="rva">Relative Virtual Address</param>
        /// <param name="sectionHeaders">Section Headers</param>
        /// <returns>Raw file address.</returns>
        public static ulong RvaToOffset(this ulong rva, ICollection<ImageSectionHeader> sectionHeaders)
        {
            ImageSectionHeader GetSectionForRva(ulong relVirAdr)
            {
                var notLastSection = sectionHeaders.FirstOrDefault(s =>
                    relVirAdr >= s.VirtualAddress && relVirAdr < s.VirtualAddress + s.VirtualSize);

                if (notLastSection != null)
                    return notLastSection;

                var lastSection = sectionHeaders.LastOrDefault(s => 
                        relVirAdr >= s.VirtualAddress && relVirAdr <= s.VirtualAddress + s.VirtualSize);

                return lastSection;
            }

            var section = GetSectionForRva(rva);

            if (section is null)
            {
                throw new Exception("Cannot find corresponding section.");
            }

            return rva - section.VirtualAddress + section.PointerToRawData;
        }

        /// <summary>
        ///     Map an relative virtual address to the raw file address.
        /// </summary>
        /// <param name="rva">Relative Virtual Address</param>
        /// <param name="sectionHeaders">Section Headers</param>
        /// <returns>Raw file address.</returns>
        public static uint RvaToOffset(this uint rva, ICollection<ImageSectionHeader> sectionHeaders)
        {
            return (uint) RvaToOffset((ulong) rva, sectionHeaders);
        }

        /// <summary><commit_msg>Fewer allocations in RvaToOffset<commit_after>﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using PeNet.Header.Pe;

namespace PeNet
{
    /// <summary>
    /// Extensions method to work make the work with buffers 
    /// and addresses easier.
    /// </summary>
    public static class ExtensionMethods
    {
        /// <summary>
        ///     Map an virtual address to the raw file address.
        /// </summary>
        /// <param name="va">Virtual Address</param>
        /// <param name="sectionHeaders">Section Headers</param>
        /// <returns>Raw file address.</returns>
        public static ulong VaToOffset(this ulong va, ICollection<ImageSectionHeader> sectionHeaders)
        {
            var rva= va - sectionHeaders.First().ImageBaseAddress;
            return RvaToOffset(rva, sectionHeaders);
        }

        /// <summary>
        ///     Map an relative virtual address to the raw file address.
        /// </summary>
        /// <param name="rva">Relative Virtual Address</param>
        /// <param name="sectionHeaders">Section Headers</param>
        /// <returns>Raw file address.</returns>
        public static ulong RvaToOffset(this ulong rva, ICollection<ImageSectionHeader> sectionHeaders)
        {
            static ImageSectionHeader? GetSectionForRva(ICollection<ImageSectionHeader> sh, ulong relVirAdr)
            {
                ImageSectionHeader? sec = null;
                for (var i = 0; i < sh.Count; i++)
                {
                    if (relVirAdr >= sh.ElementAt(i).VirtualAddress
                        && relVirAdr < sh.ElementAt(i).VirtualAddress + sh.ElementAt(i).VirtualSize)
                    {
                        sec = sh.ElementAt(i);
                    }
                }

                if (sec != null)
                    return sec;

                for (var i = sh.Count - 1; i >= 0; i--)
                {
                    if (relVirAdr >= sh.ElementAt(i).VirtualAddress &&
                        relVirAdr <= sh.ElementAt(i).VirtualAddress + sh.ElementAt(i).VirtualSize)
                    {
                        sec = sh.ElementAt(i);
                    }
                }

                return sec;
            }

            var section = GetSectionForRva(sectionHeaders, rva);

            if (section is null)
            {
                throw new Exception("Cannot find corresponding section.");
            }

            return rva - section.VirtualAddress + section.PointerToRawData;
        }

        /// <summary>
        ///     Map an relative virtual address to the raw file address.
        /// </summary>
        /// <param name="rva">Relative Virtual Address</param>
        /// <param name="sectionHeaders">Section Headers</param>
        /// <returns>Raw file address.</returns>
        public static uint RvaToOffset(this uint rva, ICollection<ImageSectionHeader> sectionHeaders)
        {
            return (uint) RvaToOffset((ulong) rva, sectionHeaders);
        }

        /// <summary>
{'fraction_non_alphanumeric': 0.10798532238336536, 'fraction_numerical': 0.0005242005940940067, 'mean_word_length': 1.7625482625482625, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 71, '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': '6248928', 'n_tokens_mistral': 1474, 'n_tokens_neox': 1415, 'n_words': 376}