コード例 #1
0
        public static List <string> FormatEncodedData(string data)
        {
            List <string> lines = new List <string>();

            /* Tokenize the string into "blocks" */
            BlockStack       stack          = new BlockStack(data);
            List <DataBlock> BlocksForLine  = new List <DataBlock>();
            EncodeTags       lastTypeOnLine = EncodeTags.NONE;

            while (stack.Count > 0)
            {
                BlocksForLine.Clear();
                int       lineLength = 0;
                DataBlock currentBlock;

                if (lines.Count > 0)
                {
                    if (lastTypeOnLine != EncodeTags.COMMA && stack.Peek().Type != EncodeTags.COMMA && stack.Peek().Type != lastTypeOnLine)
                    {
                        /* different types, inject an empty of the previous type */
                        DataBlock dummy = new DataBlock()
                        {
                            Type = lastTypeOnLine, Contents = "()"
                        };
                        BlocksForLine.Add(dummy);
                        lineLength += dummy.Length;
                    }
                }

                while (stack.Count > 0)
                {
                    currentBlock = stack.Pop();
                    if (lineLength + currentBlock.Length <= 70)
                    {
                        BlocksForLine.Add(currentBlock);
                        lineLength += currentBlock.Length;
                    }
                    else
                    {
                        stack.Push(currentBlock);
                        break;
                    }
                }

                /* We've filled the line with as many full blocks as we can */

                /* If next block is a length of 4 for ASCII or 5 for BINARY, add it */
                if (lineLength < 70 && stack.Count > 0)
                {
                    var needsSplit = true;
                    switch (stack.Peek().Type)
                    {
                    case EncodeTags.ASCII:
                        if (stack.Peek().Length == 4)
                        {
                            BlocksForLine.Add(stack.Pop());
                            needsSplit = false;
                        }
                        break;

                    case EncodeTags.BINARY:
                        if (stack.Peek().Length == 5)
                        {
                            BlocksForLine.Add(stack.Pop());
                            needsSplit = false;
                        }
                        break;

                    case EncodeTags.COMMA:
                        BlocksForLine.Add(stack.Pop());
                        needsSplit = false;
                        break;
                    }


                    if (needsSplit)
                    {
                        /* determine if we can split it */

                        var blockToSplit = stack.Pop();
                        Tuple <DataBlock, DataBlock> splitParts = blockToSplit.Split(70 - lineLength);
                        if (splitParts.Item2 != null)
                        {
                            stack.Push(splitParts.Item2);
                        }
                        BlocksForLine.Add(splitParts.Item1);
                    }
                }
                else
                {
                    if (BlocksForLine.Sum(b => b.Length) == 70)
                    {
                        if (stack.Count > 0 && BlocksForLine.Last().Type == EncodeTags.COMMA)
                        {
                            var blockToSplit = stack.Pop();
                            Tuple <DataBlock, DataBlock> splitParts = blockToSplit.Split(70 - lineLength);
                            if (splitParts.Item2 != null)
                            {
                                stack.Push(splitParts.Item2);
                            }
                            BlocksForLine.Add(splitParts.Item1);
                        }
                    }
                }
                lastTypeOnLine = BlocksForLine.Last().Type;

                /* if the next token happens to be a comma, just add it?*/
                if (stack.Count > 0 && stack.Peek().Type == EncodeTags.COMMA)
                {
                    BlocksForLine.Add(stack.Pop());
                    lastTypeOnLine = EncodeTags.COMMA;
                }

                /* Process all blocks to string */
                StringBuilder line = new StringBuilder();
                foreach (DataBlock block in BlocksForLine)
                {
                    switch (block.Type)
                    {
                    case EncodeTags.ASCII:
                        line.Append("A");
                        break;

                    case EncodeTags.BINARY:
                        line.Append("B");
                        break;
                    }
                    line.Append(block.Contents);
                }
                var lineText = line.ToString();
                lines.Add(lineText);
                line.Clear();
                line = null;
            }



            return(lines);
        }
コード例 #2
0
        public static string EncodeData(byte[] data)
        {
            StringBuilder sb         = new StringBuilder();
            EncodeTags    currentTag = EncodeTags.NONE;

            foreach (byte b in data)
            {
                if (b >= 32 && b < 127 && (char)b != ']' && (char)b != '[')
                {
                    /* we'll treat this as an ascii character */
                    switch (currentTag)
                    {
                    case EncodeTags.NONE:
                        sb.Append("A(");
                        currentTag = EncodeTags.ASCII;
                        break;

                    case EncodeTags.BINARY:
                        sb.Append(")A(");
                        currentTag = EncodeTags.ASCII;
                        break;

                    case EncodeTags.ASCII:
                        break;
                    }
                    if ((char)b == ')' || (char)b == '(')
                    {
                        sb.Append($"\\{(char)b}");
                    }
                    else if ((char)b == '\\')
                    {
                        sb.Append("\\\\");
                    }
                    else
                    {
                        sb.Append((char)b);
                    }
                }
                else
                {
                    /* we'll treat this as a binary */
                    switch (currentTag)
                    {
                    case EncodeTags.NONE:
                        sb.Append("B(");
                        currentTag = EncodeTags.BINARY;
                        break;

                    case EncodeTags.ASCII:
                        sb.Append(")B(");
                        currentTag = EncodeTags.BINARY;
                        break;

                    case EncodeTags.BINARY:
                        break;
                    }
                    sb.Append(EncodeByte(b));
                }
            }

            if (currentTag != EncodeTags.NONE)
            {
                sb.Append(")");
            }

            return(sb.ToString());
        }