Jump to content
  • Advertisement
Sign in to follow this  

[.net] C#: Reading non-terminated strings?

This topic is 4076 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How on earth would I go about reading a string from a binarystream that, according to this resource looks like this; 'The IFF header is 64 bytes long. The first 60 bytes are the signature, which consists of two strings: "IFF FILE 2.5:TYPE FOLLOWED BY SIZE" " JAMIE DOORNBOS & MAXIS 1" (without the quote marks). The first string is terminated by a null byte; the second string is not. The game checks all sixty bytes to determine if it's a valid IFF file.' This seems to be nearly impossible to do in C#! 0_o Here's my current code:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace DBPF.Iff
    public class IffLoader
        private string m_Header;
        private long m_RSMPOffset;
        private IffFile[] m_Files;
        private string m_ArchivePath;
        private RSMPResource m_RSMPResource;
        private TypeList[] m_TypeLists;

        public bool LoadIffFile(string FilePath)
            FileStream Stream = File.OpenRead(FilePath);
            BinaryReader Reader = new BinaryReader(Stream);
            ASCIIEncoding ASCIIEncoding = new ASCIIEncoding();
            m_ArchivePath = FilePath;

            m_Header = Encoding.Default.GetString(Reader.ReadBytes(60));

            if (!m_Header.Equals("IFF FILE 2.5:TYPE FOLLOWED BY SIZE  "))
                MessageBox.Show("Archive was not an *.iff archive!");
                return false;

            m_RSMPOffset = (long)Reader.ReadUInt32();

            Stream.Seek(m_RSMPOffset, SeekOrigin.Begin);

            m_RSMPResource = new RSMPResource();
            m_RSMPResource.Unknown = Reader.ReadUInt32();
            m_RSMPResource.Version = Reader.ReadUInt32();
            m_RSMPResource.ID = ASCIIEncoding.GetString(Reader.ReadBytes(4));
            m_RSMPResource.Size = Reader.ReadUInt32();
            m_RSMPResource.NumTypeLists = Reader.ReadUInt32();

            m_TypeLists = new TypeList[m_RSMPResource.NumTypeLists];

            int NumFiles = 0;

            //Read the information pertaining to all the typelists in the RSMP resource,
            //and then read the information pertaining to all entries in each of the
            for (int x = 0; x < m_TypeLists.Length; x++)
                m_TypeLists[x] = new TypeList();
                m_TypeLists[x].TypeCode = ASCIIEncoding.GetString(Reader.ReadBytes(4));
                m_TypeLists[x].NumEntries = Reader.ReadUInt32();
                m_TypeLists[x].Entries = new ListEntry[m_TypeLists[x].NumEntries];

                for (int y = 0; y < m_TypeLists[x].NumEntries; y++)
                    m_TypeLists[x].Entries[y] = new ListEntry();
                    m_TypeLists[x].Entries[y].Offset = BitConverter.ToInt32(Reader.ReadBytes(4), 0);
                    m_TypeLists[x].Entries[y].ID = Reader.ReadUInt16();
                    m_TypeLists[x].Entries[y].Unknown = Reader.ReadUInt16();
                    m_TypeLists[x].Entries[y].Flags = Reader.ReadUInt16();
                    m_TypeLists[x].Entries[y].NameString = Reader.ReadString();

                    //Increase the number of files for each entry, so that
                    //m_Files can be initialized to a proper length.

            m_Files = new IffFile[NumFiles];
            int NumTotalEntries = 0;

            foreach (TypeList TmpList in m_TypeLists)
                foreach (ListEntry TmpEntry in TmpList.Entries)

                    Stream.Seek(TmpEntry.Offset, SeekOrigin.Begin);

                    m_Files[NumTotalEntries] = new IffFile();
                    m_Files[NumTotalEntries].TypeCode = ASCIIEncoding.GetString(Reader.ReadBytes(4));
                    m_Files[NumTotalEntries].Size = Reader.ReadUInt32();
                    m_Files[NumTotalEntries].ID = Reader.ReadUInt16();
                    m_Files[NumTotalEntries].Flags = Reader.ReadUInt16();
                    m_Files[NumTotalEntries].Name = ASCIIEncoding.GetString(Reader.ReadBytes(64));
                    m_Files[NumTotalEntries].Offset = Stream.Position;


            return true;

        /// <summary>
        /// Extracts all the files in the currently opened archive.
        /// </summary>
        /// <param name="Filename">The name of the directory to extract to.
        ///                        Will be created if it doesn't exist.</param>
        public void UnpackArchive(string Filename)
            #region Assignments
            //Filetype extension for the current file.
            string CurrentExtension = "";

            //Filestream and reader for the archive file.
            FileStream ArchiveStream = File.OpenRead(m_ArchivePath);
            BinaryReader Reader = new BinaryReader(ArchiveStream);


            foreach (IffFile TmpFile in m_Files)
                FileStream Stream = File.Create(Filename + "\\" + TmpFile.Name + CurrentExtension);
                BinaryWriter Writer = new BinaryWriter(Stream);

                //Seek to the offset in the archive for the current file.
                ArchiveStream.Seek(TmpFile.Offset, SeekOrigin.Begin);
                //Initialize the databuffer to the size of the current file,
                //minus the size of the resourceheader.
                TmpFile.Data = new byte[TmpFile.Size - 76];
                //Read the file into the databuffer.
                TmpFile.Data = Reader.ReadBytes((int)TmpFile.Size - 76);

                //And, finally, write the databuffer into the new file. :)
                //Lastly, nullify the databuffer to save memory.
                TmpFile.Data = null;


        /// <summary>
        /// Returns all the *.iff files loaded by this loader in an array.
        /// </summary>
        public IffFile[] FileList
            get { return m_Files; }

Here's some of the things I have tried, in vain: m_Header = ASCIIEncoding.GetString(Reader.ReadBytes(60)); m_Header = Reader.ReadString() + Reader.ReadString(); m_Header = Reader.ReadString() + ASCIIEncoding.GetString(Reader.ReadBytes(24)); No matter what I do, and despite endless googling, I always seem to end up with this string (not exactly this one, but something close to it (I.E I cannot get the line termination down right or something, which makes it impossible to do an if() check on it)): "IFF FILE 2.5:TYPE FOLLOWED BY SIZE " Thanks in advance!

Share this post

Link to post
Share on other sites
            FileStream Stream = File.OpenRead("Sprites.iff");
BinaryReader reader = new BinaryReader(Stream);

byte[] header = reader.ReadBytes(60);
string header_line_1 = String.Empty, header_line_2 = String.Empty;

for (int i = 0; i < 60; i++)
if (header == 0x00)
header_line_1 = Encoding.ASCII.GetString(header, 0, i);
header_line_2 = Encoding.ASCII.GetString(header, i + 1, 59 - i);

if (!header_line_1.Equals("IFF FILE 2.5:TYPE FOLLOWED BY SIZE") || !header_line_2.Equals(" JAMIE DOORNBOS & MAXIS 1"))
throw new Exception("Not a valid IFF file!");

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!