Encoding & Decoding
TinyCLR OS provides many internal fast methods to handle many encoding and decoding tasks.
Strings and Arrays
The Encoding class is used to convert between strings, character arrays, and byte arrays. For example, to convert from a byte array to a string:
var string = System.Text.Encoding.UTF8.GetString(new byte[] { 65, 66, 67, 68, 69 });
//string = "ABCDE"
Convert From String to Byte Array
System.Text.Encoding.UTF8.GetBytes(string s)
//The following method returns an integer for the number of bytes converted.
//The resulting bytes are returned within the byte[] array.
System.Text.Encoding.UTF8.GetBytes(string s, int charIndex, int charCount, byte[] bytes,
int byteIndex)
Convert From Byte Array to Character Array
System.Text.Encoding.UTF8.GetChars(byte[] bytes)
System.Text.Encoding.UTF8.GetChars(byte[] bytes, int byteIndex, int byteCount)
Convert From Byte Array to String
System.Text.Encoding.UTF8.GetString(byte[] bytes)
System.Text.Encoding.UTF8.GetString(byte[] bytes, int index, int count)
Base64
Base64 is a standard way to convert binary data into readable ASCII readable.
var base64EncodedString = System.Convert.FromBase64String(string);
var base64EncodedChar = System.Convert.FromBase64CharArray(char[]);
var convertedFromBase64 = System.Convert.ToBase64String(byte[]);
RFC4648 Base64 standard is supported by adding Convert.UseRFC4648Encoding = true;
.
BitConverter
The BitConverter class is used to convert from one data type to another. For example, to convert an integer into a byte array:
var byteArray = System.BitConverter.GetBytes(23);
//byteArray[0] = 23, byteArray[1] = 0, byteArray[2] = 0, byteArray[3] = 0
byteArray = System.BitConverter.GetBytes(65536);
//byteArray[0] = 0, byteArray[1] = 0, byteArray[2] = 1, byteArray[3] = 0
You can also convert from a byte array to a string, but the results are different than the results from the Encoding class:
var string = System.BitConverter.ToString(new byte[] { 65, 66, 67, 68, 69 });
//string = "41-42-43-44-45" (hexadecimal values delimited by hyphens).
var string = System.Text.Encoding.UTF8.GetString(new byte[] { 65, 66, 67, 68, 69 });
//string = "ABCDE"
BitConverter Overloads
Convert to a Byte Array
System.BitConverter.GetBytes(char value)
System.BitConverter.GetBytes(double value)
System.BitConverter.GetBytes(float value)
System.BitConverter.GetBytes(int value)
System.BitConverter.GetBytes(long value)
System.BitConverter.GetBytes(short value)
System.BitConverter.GetBytes(uint value)
System.BitConverter.GetBytes(ulong value)
System.BitConverter.GetBytes(ushort value)
System.BitConverter.GetBytes(bool value)
Convert from a Byte Array
System.BitConverter.ToBoolean(byte[] bytes, int startIndex)
System.BitConverter.ToChar(byte[] bytes, int startIndex)
System.BitConverter.ToDouble(byte[] bytes, int startIndex)
System.BitConverter.ToInt16(byte[] bytes, int startIndex)
System.BitConverter.ToInt32(byte[] bytes, int startIndex)
System.BitConverter.ToInt64(byte[] bytes, int startIndex)
System.BitConverter.ToSingle(byte[] bytes, int startIndex)
System.BitConverter.ToString(byte[] bytes)
System.BitConverter.ToString(byte[] bytes, int startIndex)
System.BitConverter.ToString(byte[] bytes, int startIndex, int length)
System.BitConverter.ToUInt16(byte[] bytes, int startIndex)
System.BitConverter.ToUInt32(byte[] bytes, int startIndex)
System.BitConverter.ToUInt64(byte[] bytes, int startIndex)
Convert Between Double and Long
System.BitConverter.DoubleToInt64Bits(double value)
System.BitConverter.Int64BitsToDouble(long value)
Swap Endianness
SwapEndianness(byte[] data, int groupSize, int index, int size);
String Handling
ToString() Supported Conversions
As TinyCLR OS is a subset of the full desktop .NET development system, not all desktop .NET features are supported. The following ToString()
arguments are supported:
Debug.WriteLine(123.ToString("N4")); //Outputs 123.0000
Debug.WriteLine(123.ToString("F4")); //Outputs 123.0000
Debug.WriteLine(123.ToString("D4")); //Outputs 0123
Debug.WriteLine(123.ToString("G4")); //Outputs 123
Debug.WriteLine(123.ToString("X4")); //Outputs 007B
The following ToString()
arguments are not supported and will raise an exception:
Debug.WriteLine(123.ToString("E4")); //'E' option not supported
Debug.WriteLine(123.ToString("R4")); //'R' option not supported
Debug.WriteLine(123.ToString("P4")); //'P' option not supported
Debug.WriteLine(123.ToString("C2")); //'C' option not supported
StringBuilder
As strings are immutable, manipulating strings, especially in a tight loop, can impact system performance and increase memory usage and fragmentation. Because strings cannot be changed, every time you manipulate a string a new string is created and the original string becomes garbage. The StringBuilder class uses a string buffer to improve the performance of string manipulation, allowing you to manipulate strings instead of creating new strings.
The following example changes the content of a string without creating a new string.
var sb = new System.Text.StringBuilder("PA0 is the pin to use.");
sb[1] = 'B';
System.Diagnostics.Debug.WriteLine(sb.ToString()); //Will output "PB0 is the pin to use."
StringBuilder is also great when you want to build strings by concatenating characters or other strings. Without StringBuilder, each time you add a character to a string, a new string is created and the old string becomes garbage. The following code creates a string one character at a time without creating all the garbage strings.
var sb = new System.Text.StringBuilder();
for (int i=48; i<58; i++) {
sb.Append((char)i);
}
Debug.WriteLine(sb.ToString()); //Will output "0123456789"
Color Space
Internally TinyCLR uses the 5:6:5 RGB 16BPP color space, requiring two bytes per pixel. Users may find the need to use a different color space.
Conversion
Convert(byte[] inArray, byte[] outArray, ColorFormat colorFormat, RgbFormat rgbFormat, byte alpha, byte[] colorTable)
Users must create outArray
of a length that is determined based on the ColorFormat
the user is converting to. The table below will help in determining outArray
buffer size.
Color Space Desired | size of outArray buffer |
---|---|
3:5:2 | inArray.Length x 0.5 |
4:4:4 | inArray.Length x 0.75 |
5:6:5 | inArray.Length x 1 |
8:8:8 | inArray.Length x 1.5 |
8:8:8:8 | inArray.Length x 2.0 |
RgbFormat
is used to swap colors is necessary.
Tip
Converting to from 5:6:5 to 5:6:5 doesn't convert the color space but it is useful to change the RgbFormat
or scale using colorTable
.
The 64 values in colorTable
maps each RGB original colors (6bit max from 5:6:5) to a new scaled color (up to 8bit in 8:8:8). This is optional as Convert
will be default simply shift 6 bit up into 8 bits. This is an example of colorTable
with more ideal results
var ColorTable565To888 = new byte[64]{ 0,2,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,170,174,178,182,186,190,194,198,202,206,210,214,218,222,226,230,234,238,242,246,250 };
Tip
The custom color table option is only available in 5:6:5, 8:8:8, and 8:8:8:8 color spaces.
The alpha
is only used with the 8:8:8:8 color space to set the alpha channel value, between 0(transparent) to 255(opaque).
1Bpp Conversion
The ConvertTo1Bpp
function converts the internal 5:6:5 color space to 1BPP. Any color will result in 1 and only black will result in 0.
ConvertTo1Bpp(byte[] inArray, byte[] outArray, uint width)
width
is the pixel-width of the image that was used to create inArray
. The outArray
buffer size is = inArray.Length
x 0.0625
By default, ConvertTo1Bpp
groups each 8 pixels vertically, which is what most 1BPP display use. There is an overload that include BitFormat
to change to horizontal if desired.
ConvertTo1Bpp(byte[] inArray, byte[] outArray, uint width, BitFormat bitFormat)