Skip to content

Instantly share code, notes, and snippets.

@jclement
Last active October 11, 2015 20:28
Show Gist options
  • Select an option

  • Save jclement/3915529 to your computer and use it in GitHub Desktop.

Select an option

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
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