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

namespace Unplugged.Segy
{
    public class SegyReader
    {
        public int InlineNumberLocation { get; set; }
        public int CrosslineNumberLocation { get; set; }

        public SegyReader()
        {
            InlineNumberLocation = 189;
            CrosslineNumberLocation = 193;
        }

        #region From the Top: Methods that start reading from the beginning of the file

        public virtual ISegyFile Read(string path)
        {
            using (var stream = File.OpenRead(path))
                return Read(stream);
        }

        public virtual ISegyFile Read(Stream stream)
        {
            return Read(stream, int.MaxValue);
        }

        public virtual ISegyFile Read(Stream stream, int traceCount)
        {
            using (var reader = new BinaryReader(stream))
            {
                var fileHeader = ReadFileHeader(reader);
                var traces = new List<ITrace>();
                for (int i = 0; i < traceCount; i++)
                {
                    var trace = ReadTrace(reader, fileHeader.SampleFormat);
                    if (trace == null)
                        break;
                    traces.Add(trace);
                }
                return new SegyFile { Header = fileHeader, Traces = traces };
            }
        }

        public virtual IFileHeader ReadFileHeader(BinaryReader reader)
        {
            var text = ReadTextHeader(reader);
            FileHeader header = ReadBinaryHeader(reader) as FileHeader;
            header.Text = text;
            return header;
        }

        public virtual string ReadTextHeader(string path)
        {
            using (var stream = File.OpenRead(path))
                return ReadTextHeader(stream);
        }

        public virtual string ReadTextHeader(Stream stream)
        {
            using (var reader = new BinaryReader(stream))
                return ReadTextHeader(reader);
        }

        public virtual string ReadTextHeader(BinaryReader reader)
        {
            var bytes = reader.ReadBytes(_textHeaderSize);
            string text = (bytes[0] == 'C') ?
                ASCIIEncoding.Default.GetString(bytes) :
                IbmConverter.ToString(bytes);
            return InsertNewLines(text);
        }

        #endregion

        #region Already in progress: Methods that start reading from the current location in the stream

        public virtual IFileHeader ReadBinaryHeader(BinaryReader reader)
        {
            var binaryHeader = reader.ReadBytes(_binaryHeaderSize);
            var byte0 = binaryHeader[_sampleFormatIndex];
            var byte1 = binaryHeader[_sampleFormatIndex + 1];
            bool isLittleEndian = (byte1 == 0);
            var sampleFormat = isLittleEndian ?
                    (FormatCode)byte0 :
                    (FormatCode)byte1;
            return new FileHeader { SampleFormat = sampleFormat, IsLittleEndian = isLittleEndian };
        }

        public virtual ITraceHeader ReadTraceHeader(BinaryReader reader)
        {<commit_msg>Documented the main read functions<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Unplugged.IbmBits;

namespace Unplugged.Segy
{
    public class SegyReader
    {
        public int InlineNumberLocation { get; set; }
        public int CrosslineNumberLocation { get; set; }

        public SegyReader()
        {
            InlineNumberLocation = 189;
            CrosslineNumberLocation = 193;
        }

        #region From the Top: Methods that start reading from the beginning of the file

        /// <summary>
        /// Given a file path, reads entire SEGY file into memory
        /// </summary>
        public virtual ISegyFile Read(string path)
        {
            using (var stream = File.OpenRead(path))
                return Read(stream);
        }

        /// <summary>
        /// Given stream, reads entire SEGY file into memory.
        /// Assumes the stream is at the start of the file.
        /// </summary>
        public virtual ISegyFile Read(Stream stream)
        {
            return Read(stream, int.MaxValue);
        }

        /// <summary>
        /// Given stream and traceCount, reads the requested number
        /// of traces into memory. The given traceCount may exceed
        /// the number of traces in the file; 
        /// in that case all the traces in the file are read.
        /// Assumes the stream is at the start of the file.
        /// </summary>
        public virtual ISegyFile Read(Stream stream, int traceCount)
        {
            using (var reader = new BinaryReader(stream))
            {
                var fileHeader = ReadFileHeader(reader);
                var traces = new List<ITrace>();
                for (int i = 0; i < traceCount; i++)
                {
                    var trace = ReadTrace(reader, fileHeader.SampleFormat);
                    if (trace == null)
                        break;
                    traces.Add(trace);
                }
                return new SegyFile { Header = fileHeader, Traces = traces };
            }
        }

        /// <summary>
        /// Given a BinaryReader, reads the SEGY File Header into memory.
        /// Asummes the BinaryReader is at the start of the file.
        /// </summary>
        public virtual IFileHeader ReadFileHeader(BinaryReader reader)
        {
            var text = ReadTextHeader(reader);
            FileHeader header = ReadBinaryHeader(reader) as FileHeader;
            header.Text = text;
            return header;
        }

        /// <summary>
        /// Given a file path reads the text header from the beginning
        /// of the SEGY file.
        /// </summary>
        public virtual string ReadTextHeader(string path)
        {
            using (var stream = File.OpenRead(path))
                return ReadTextHeader(stream);
        }

        /// <summary>
        /// Given a stream reads the text header.
        /// Assumes the stream is at the start of the file.
        /// </summary>
        public virtual string ReadTextHeader(Stream stream)
        {
            using (var reader = new BinaryReader(stream))
                return ReadTextHeader(reader);
        }

        /// <summary>
        /// Given a BinaryReader reads the text header.
        /// Assumes the BinaryReader is at the start of the file.
        /// </summary>
        public virtual string ReadTextHeader(BinaryReader reader)
        {
            var bytes = reader.ReadBytes(_textHeaderSize);
            string text = (bytes[0] == 'C') ?
                ASCIIEncoding.Default.GetString(bytes) :
                IbmConverter.ToString(bytes);
            return InsertNewLines(text);
        }

        #endregion

        #region Already in progress: Methods that start reading from the current location in the stream

        public virtual IFileHeader ReadBinaryHeader(BinaryReader reader)
        {
            var binaryHeader = reader.ReadBytes(_binaryHeaderSize);
            var byte0 = binaryHeader[_sampleFormatIndex];
            var byte1 = binaryHeader[_sampleFormatIndex + 1];
            bool isLittleEndian = (byte1 == 0);
            var sampleFormat = isLittleEndian ?
                    (FormatCode)byte0 :
                    (FormatCode)byte1;
            return new FileHeader { SampleFormat = sampleFormat, IsLittleEndian = isLittleEndian };
        }

        public virtual ITraceHeader ReadTraceHeader(BinaryReader reader)
        {
{'fraction_non_alphanumeric': 0.07759179966264435, 'fraction_numerical': 0.003892565200467108, 'mean_word_length': 1.6998248686514885, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, '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': '4376308', 'n_tokens_mistral': 1918, 'n_tokens_neox': 1822, 'n_words': 592}