Last active
October 11, 2015 20:28
-
-
Save jclement/3915529 to your computer and use it in GitHub Desktop.
Code for splitting long messages into chunks giving preference for keeping lines together
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| namespace Chunkerizer | |
| { | |
| public delegate string ChunkHeaderGenerator(int chunkIndex); | |
| /// <summary> | |
| /// | |
| /// _________________.---.______ | |
| /// (_(______________(_o o_(____() CHUNKERIZER | |
| /// .___.'. .'.___. Chop a long string into shorter chunks giving preference to | |
| /// \ o Y o / keeping lines together if possible. | |
| /// \ \__ __/ / Supports pushing a prefix on the start of each CHUNK (i.e. | |
| /// '.__'-'__.' "Chunk #") | |
| /// ''' | |
| /// </summary> | |
| public static class Chunkerizer | |
| { | |
| public static List<string> Chunk(string message, int maxChunkLength, ChunkHeaderGenerator chunkHeaderGenerator) | |
| { | |
| List<string> chunks = new List<string>(); | |
| List<string> lines = new List<string>(message.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)); | |
| int chunkIndex = 1; | |
| string currentChunk = chunkHeaderGenerator(chunkIndex); | |
| foreach (string line in lines) | |
| { | |
| if ((2 + line.Length + chunkHeaderGenerator(chunkIndex + 1).Length) > maxChunkLength) | |
| { | |
| // This line will never fit. Do character split! | |
| string tempLine = line; | |
| while (!string.IsNullOrEmpty(tempLine)) | |
| { | |
| int availableRoom = Math.Max(0, maxChunkLength - currentChunk.Length - 2); | |
| string smallChunk = tempLine.Substring(0, Math.Min(tempLine.Length, availableRoom)); | |
| if (!string.IsNullOrEmpty(smallChunk)) currentChunk += smallChunk + "\r\n"; | |
| tempLine = tempLine.Substring(Math.Min(tempLine.Length, availableRoom)); | |
| chunks.Add(currentChunk); | |
| currentChunk = chunkHeaderGenerator(++chunkIndex); | |
| } | |
| } | |
| else if ((2 + (currentChunk + line).Length) > maxChunkLength) | |
| { | |
| // Line won't find in remainder of chunk. Skip to next chunk. | |
| chunks.Add(currentChunk); | |
| currentChunk = chunkHeaderGenerator(++chunkIndex); | |
| currentChunk += line + "\r\n"; | |
| } | |
| else | |
| { | |
| // Line will fit. Add it. | |
| currentChunk += line + "\r\n"; | |
| } | |
| } | |
| // Add the last chunk to the list | |
| if (!string.IsNullOrEmpty(currentChunk)) | |
| chunks.Add(currentChunk); | |
| return chunks; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment