Example #1
0
 /// <summary>
 /// Writes a ShocoModel as a C# Class
 /// </summary>
 /// <param name="model">ShocoModel to generate the class from</param>
 /// <param name="Filename">Destination for the generated class</param>
 /// <param name="Name">Name of the C# Class</param>
 /// <param name="Namespace">Namespace for the C# Class</param>
 public static void WriteAsCSharpClass(this ShocoModel model, string Filename, string Name, string Namespace)
 {
     using (var streamWriter = File.CreateText(Filename))
     {
         WriteAsCSharpClass(model, streamWriter, Name, Namespace);
     }
 }
Example #2
0
 /// <summary>
 /// Writes a ShocoModel as a C Header
 /// </summary>
 /// <param name="model">ShocoModel to generate the header from</param>
 /// <param name="Filename">Destination for the generated header</param>
 public static void WriteAsCHeader(this ShocoModel model, string Filename)
 {
     using (var stream = new FileStream(Filename, FileMode.Create, FileAccess.Write))
     {
         using (var writer = new StreamWriter(stream, Encoding.ASCII))
         {
             WriteAsCHeader(model, writer);
         }
     }
 }
Example #3
0
        /// <summary>
        /// Writes a ShocoModel as a C# Class
        /// </summary>
        /// <param name="model">ShocoModel to generate the class from</param>
        /// <param name="Writer">Destination for the generated class</param>
        /// <param name="Name">Name of the C# Class</param>
        /// <param name="Namespace">Namespace for the C# Class</param>
        public static void WriteAsCSharpClass(this ShocoModel model, TextWriter Writer, string Name, string Namespace)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }
            if (Writer == null)
            {
                throw new ArgumentNullException(nameof(Writer));
            }
            if (string.IsNullOrWhiteSpace(Name))
            {
                throw new ArgumentNullException(nameof(Name));
            }
            if (string.IsNullOrWhiteSpace(Namespace))
            {
                Namespace = DefaultCSharpNamespace;
            }

            Writer.WriteLine($"namespace {Namespace}");
            Writer.WriteLine("{");
            if (Namespace != DefaultCSharpNamespace)
            {
                Writer.WriteLine($"    using {DefaultCSharpNamespace};");
                Writer.WriteLine();
            }
            Writer.WriteLine($"    public class {Name} : ShocoModel");
            Writer.WriteLine("    {");

            Writer.WriteLine($"        public static {Name} Instance {{ get; }} = new {Name}();");
            Writer.WriteLine();
            Writer.WriteLine($"        private {Name}()");
            Writer.WriteLine($"            : base(MinimumCharacter: {model.MinimumCharacter},");
            Writer.WriteLine($"                  MaximumCharacter: {model.MaximumCharacter},");
            Writer.WriteLine($"                  MaximumSuccessorLength: {model.MaximumSuccessorLength},");

            Writer.WriteLine($"                  CharactersById: new byte[{model.CharactersById.Length}] {{");
            for (int offset = 0; offset < model.CharactersById.Length; offset += 11)
            {
                if (offset != 0)
                {
                    Writer.WriteLine(",");
                }
                Writer.Write($"                      {string.Join(", ", model.CharactersById.Skip(offset).Take(11).Select(EscapeCSharp))}");
            }
            Writer.WriteLine(" },");
            var idsByCharacter = model.IdsByCharacter;

            Writer.Write($"                  IdsByCharacter: new byte[256] {{");
            for (int offset = 0; offset < idsByCharacter.Length; offset += 32)
            {
                if (offset != 0)
                {
                    Writer.Write(",");
                }
                Writer.WriteLine();
                Writer.Write($"                      {string.Join(", ", idsByCharacter.Skip(offset).Take(32).Select(FormatAsCSharpByte))}");
            }
            Writer.WriteLine(" },");

            var successorIdsByCharacterId = model.SuccessorIdsByCharacterId;

            Writer.Write($"                  SuccessorIdsByCharacterId: new byte[{successorIdsByCharacterId.GetLength(0)}, {successorIdsByCharacterId.GetLength(1)}] {{");
            for (int offset = 0; offset < successorIdsByCharacterId.GetLength(0); offset++)
            {
                if (offset != 0)
                {
                    Writer.Write(",");
                }
                Writer.WriteLine();
                Writer.Write($"                      {{{string.Join(", ", successorIdsByCharacterId.Cast<byte>().Skip(offset * successorIdsByCharacterId.GetLength(1)).Take(successorIdsByCharacterId.GetLength(1)).Select(FormatAsCSharpByte))}}}");
            }
            Writer.WriteLine(" },");

            var charactersBySuccessorId = model.CharactersBySuccessorId;

            Writer.Write($"                  CharactersBySuccessorId: new byte[{charactersBySuccessorId.GetLength(0)}, {charactersBySuccessorId.GetLength(1)}] {{");
            for (int offset = 0; offset < charactersBySuccessorId.GetLength(0); offset++)
            {
                if (offset != 0)
                {
                    Writer.Write(",");
                }
                Writer.WriteLine();
                Writer.Write($"                      {{{string.Join(", ", charactersBySuccessorId.Cast<byte>().Skip(offset * charactersBySuccessorId.GetLength(1)).Take(charactersBySuccessorId.GetLength(1)).Select(EscapeCSharp))}}}");
            }
            Writer.WriteLine(" },");

            var packs = model.Packs;

            Writer.Write($"                  Packs: new ShocoPack[] {{");
            for (int index = 0; index < packs.Length; index++)
            {
                var pack = packs[index];
                if (index != 0)
                {
                    Writer.Write(",");
                }
                Writer.WriteLine();
                Writer.Write($"                      new ShocoPack(0x{pack.Header:X2}, {pack.BytesPacked}, {pack.BytesUnpacked}, new int[] {{ {string.Join(", ", pack.offsets)} }}, new int[] {{ {string.Join(", ", pack.masks)} }})");
            }
            Writer.WriteLine(" })");
            Writer.WriteLine($"        {{ }}");
            Writer.WriteLine();
            Writer.WriteLine("    }");
            Writer.WriteLine("}");
        }
Example #4
0
        /// <summary>
        /// Writes a ShocoModel as a C Header
        /// </summary>
        /// <param name="model">ShocoModel to generate the header from</param>
        /// <param name="Writer">Destination for the generated header</param>
        public static void WriteAsCHeader(this ShocoModel model, TextWriter Writer)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }
            if (Writer == null)
            {
                throw new ArgumentNullException(nameof(Writer));
            }

            var chars_count = model.CharactersById.Length;

            Writer.WriteLine(@"#ifndef _SHOCO_INTERNAL
#error This header file is only to be included by 'shoco.c'.
#endif
#pragma once
/*
This file was generated by 'generate_compressor_model.py'
so don't edit this by hand. Also, do not include this file
anywhere. It is internal to 'shoco.c'. Include 'shoco.h'
if you want to use shoco in your project.
*/
");
            Writer.WriteLine($"#define MIN_CHR {model.MinimumCharacter}");
            Writer.WriteLine($"#define MAX_CHR {model.MaximumCharacter}");
            Writer.WriteLine();
            Writer.WriteLine($"static const char chrs_by_chr_id[{chars_count}] = {{");
            Writer.Write("  ");
            Writer.WriteLine(string.Join(", ", model.CharactersById.Select(EscapeC)));
            Writer.WriteLine("};");
            Writer.WriteLine();
            Writer.WriteLine($"static const int8_t chr_ids_by_chr[256] = {{");
            Writer.Write("  ");
            Writer.WriteLine(string.Join(", ", model.IdsByCharacter.Select(FormatAsCByte)));
            Writer.WriteLine("};");
            Writer.WriteLine();
            var successors = model.SuccessorIdsByCharacterId;

            Writer.WriteLine($"static const int8_t successor_ids_by_chr_id_and_chr_id[{chars_count}][{chars_count}] = {{");
            for (int x = 0; x < chars_count; x++)
            {
                if (x != 0)
                {
                    Writer.WriteLine(",");
                }
                Writer.Write("  {");
                for (int y = 0; y < chars_count; y++)
                {
                    if (y != 0)
                    {
                        Writer.Write(", ");
                    }
                    Writer.Write(FormatAsCByte(successors[x, y]));
                }
                Writer.Write("}");
            }
            Writer.WriteLine();
            Writer.WriteLine("};");
            Writer.WriteLine();
            var characters = model.CharactersBySuccessorId;

            Writer.WriteLine($"static const int8_t chrs_by_chr_and_successor_id[MAX_CHR - MIN_CHR][{characters.GetLength(1)}] = {{");
            for (int x = 0; x < characters.GetLength(0); x++)
            {
                if (x != 0)
                {
                    Writer.WriteLine(",");
                }
                Writer.Write("  {");
                for (int y = 0; y < characters.GetLength(1); y++)
                {
                    if (y != 0)
                    {
                        Writer.Write(", ");
                    }
                    Writer.Write(EscapeC(characters[x, y]));
                }
                Writer.Write("}");
            }
            Writer.WriteLine();
            Writer.WriteLine("};");
            Writer.WriteLine();
            Writer.WriteLine();
            Writer.WriteLine($@"#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4324)    // structure was padded due to __declspec(align())
#endif

typedef struct Pack {{
  const uint32_t word;
  const unsigned int bytes_packed;
  const unsigned int bytes_unpacked;
  const unsigned int offsets[{model.Packs[0].offsets.Length}];
  const int16_t _ALIGNED masks[{model.Packs[0].masks.Length}];
  const char header_mask;
  const char header;
}} Pack;

#ifdef _MSC_VER
#pragma warning(pop)
#endif");
            Writer.WriteLine();
            var packs = model.Packs;

            Writer.WriteLine($@"#define PACK_COUNT {packs.Length}
#define MAX_SUCCESSOR_N {8 - 1}");
            Writer.WriteLine();
            Writer.WriteLine("static const Pack packs[PACK_COUNT] = {");
            for (int i = 0; i < packs.Length; i++)
            {
                var pack = packs[i];
                if (i != 0)
                {
                    Writer.WriteLine(",");
                }
                Writer.Write($"  {{ 0x{pack.Header << 24:x8}, {pack.BytesPacked}, {pack.BytesUnpacked}, {{ {string.Join(", ", pack.offsets)} }}, {{ {string.Join(", ", pack.masks)} }}, 0x{(pack.Header >> 1) | pack.Header:x2}, 0x{pack.Header:x2} }}");
            }
            Writer.WriteLine();
            Writer.WriteLine("};");
        }
Example #5
0
 /// <summary>
 /// Writes a ShocoModel as a C# Class using the default namespace
 /// </summary>
 /// <param name="model">ShocoModel to generate the class from</param>
 /// <param name="Filename">Destination for the generated class</param>
 /// <param name="Name">Name of the C# Class</param>
 public static void WriteAsCSharpClass(this ShocoModel model, string Filename, string Name)
 {
     WriteAsCSharpClass(model, Filename, Name, Namespace: null);
 }
Example #6
0
 /// <summary>
 /// Writes a ShocoModel as a C# Class using the default namespace
 /// </summary>
 /// <param name="model">ShocoModel to generate the class from</param>
 /// <param name="Writer">Destination for the generated class</param>
 /// <param name="Name">Name of the C# Class</param>
 public static void WriteAsCSharpClass(this ShocoModel model, TextWriter Writer, string Name)
 {
     WriteAsCSharpClass(model, Writer, Name, Namespace: null);
 }