/ T0 / BlobWriter.cs
BlobWriter.cs
  1  /*
  2   * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
  3   *
  4   * Permission is hereby granted, free of charge, to any person obtaining 
  5   * a copy of this software and associated documentation files (the
  6   * "Software"), to deal in the Software without restriction, including
  7   * without limitation the rights to use, copy, modify, merge, publish,
  8   * distribute, sublicense, and/or sell copies of the Software, and to
  9   * permit persons to whom the Software is furnished to do so, subject to
 10   * the following conditions:
 11   *
 12   * The above copyright notice and this permission notice shall be 
 13   * included in all copies or substantial portions of the Software.
 14   *
 15   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 16   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 17   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 18   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 19   * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 20   * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 21   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22   * SOFTWARE.
 23   */
 24  
 25  using System;
 26  using System.IO;
 27  using System.Text;
 28  
 29  /*
 30   * A simple class for writing out bytes as hexadecimal constants or
 31   * explicit expressions for the initializer of a C array of 'unsigned
 32   * char'. It starts every line with a given number of tabs, and aims at
 33   * keeping lines below a given threshold (each indentation tab counts as
 34   * 8 characters). An explicit newline is inserted before the first
 35   * element, and commas are used as separators.
 36   */
 37  
 38  class BlobWriter {
 39  
 40  	TextWriter w;
 41  	int maxLineLen;
 42  	int indent;
 43  	int lineLen;
 44  
 45  	/*
 46  	 * Create a new instance. 'maxLineLen' is in characters, and
 47  	 * 'indent' is the number of tab characters at the start of
 48  	 * each line.
 49  	 */
 50  	internal BlobWriter(TextWriter w, int maxLineLen, int indent)
 51  	{
 52  		this.w = w;
 53  		this.maxLineLen = maxLineLen;
 54  		this.indent = indent;
 55  		lineLen = -1;
 56  	}
 57  
 58  	void DoNL()
 59  	{
 60  		w.WriteLine();
 61  		for (int i = 0; i < indent; i ++) {
 62  			w.Write('\t');
 63  		}
 64  		lineLen = (indent << 3);
 65  	}
 66  
 67  	/*
 68  	 * Append a new byte value; it will be converted to an hexadecimal
 69  	 * constant in the output.
 70  	 */
 71  	internal void Append(byte b)
 72  	{
 73  		if (lineLen < 0) {
 74  			DoNL();
 75  		} else {
 76  			w.Write(',');
 77  			lineLen ++;
 78  			if ((lineLen + 5) > maxLineLen) {
 79  				DoNL();
 80  			} else {
 81  				w.Write(' ');
 82  				lineLen ++;
 83  			}
 84  		}
 85  		w.Write("0x{0:X2}", b);
 86  		lineLen += 4;
 87  	}
 88  
 89  	/*
 90  	 * Append a C expression, which will be used as is. The expression
 91  	 * may resolve to several bytes if it uses internal commas. The
 92  	 * writer will try to honour the expected line length, but it
 93  	 * won't insert a newline character inside the expression.
 94  	 */
 95  	internal void Append(string expr)
 96  	{
 97  		if (lineLen < 0) {
 98  			DoNL();
 99  		} else {
100  			w.Write(',');
101  			lineLen ++;
102  			if ((lineLen + 1 + expr.Length) > maxLineLen) {
103  				DoNL();
104  			} else {
105  				w.Write(' ');
106  				lineLen ++;
107  			}
108  		}
109  		w.Write("{0}", expr);
110  		lineLen += expr.Length;
111  	}
112  }