/// <summary> /// Reads a char string value from the buffer. /// </summary> private int ReadField( TsCCpxContext context, CharString field, int fieldIndex, ArrayList fieldValues, out object fieldValue ) { fieldValue = null; byte[] buffer = context.Buffer; // initialize serialization parameters. int charWidth = (field.CharWidthSpecified) ? (int)field.CharWidth : (int)context.CharWidth; int charCount = (field.LengthSpecified) ? (int)field.Length : -1; // apply defaults for built in types. if (field.GetType() == typeof(Ascii)) { charWidth = 1; } else if (field.GetType() == typeof(Unicode)) { charWidth = 2; } if (field.CharCountRef != null) { charCount = ReadReference(context, field, fieldIndex, fieldValues, field.CharCountRef); } // find null terminator if (charCount == -1) { charCount = 0; for (int ii = context.Index; ii < context.Buffer.Length - charWidth + 1; ii += charWidth) { charCount++; bool isNull = true; for (int jj = 0; jj < charWidth; jj++) { if (context.Buffer[ii + jj] != 0) { isNull = false; break; } } if (isNull) { break; } } } // check if there is enough data left. if (buffer.Length - context.Index < charWidth * charCount) { throw new TsCCpxInvalidDataInBufferException("Unexpected end of buffer."); } if (charWidth > 2) { // copy bytes. byte[] bytes = new byte[charCount * charWidth]; for (int ii = 0; ii < charCount * charWidth; ii++) { bytes[ii] = buffer[context.Index + ii]; } // swap bytes. if (context.BigEndian) { for (int ii = 0; ii < bytes.Length; ii += charWidth) { SwapBytes(bytes, 0, charWidth); } } fieldValue = bytes; } else { // copy characters. char[] chars = new char[charCount]; for (int ii = 0; ii < charCount; ii++) { if (charWidth == 1) { chars[ii] = System.Convert.ToChar(buffer[context.Index + ii]); } else { byte[] charBytes = new byte[] { buffer[context.Index + 2 * ii], buffer[context.Index + 2 * ii + 1] }; if (context.BigEndian) { SwapBytes(charBytes, 0, 2); } chars[ii] = BitConverter.ToChar(charBytes, 0); } } fieldValue = new string(chars).TrimEnd(new char[] { '\0' }); } return(charCount * charWidth); }
/// <summary> /// Writes a char string value to the buffer. /// </summary> private int WriteField( TsCCpxContext context, CharString field, int fieldIndex, TsCCpxComplexValue[] fieldValues, object fieldValue ) { byte[] buffer = context.Buffer; // initialize serialization parameters. int charWidth = (field.CharWidthSpecified) ? (int)field.CharWidth : (int)context.CharWidth; int charCount = (field.LengthSpecified) ? (int)field.Length : -1; // apply defaults for built in types. if (field.GetType() == typeof(Ascii)) { charWidth = 1; } else if (field.GetType() == typeof(Unicode)) { charWidth = 2; } byte[] bytes = null; if (charCount == -1) { // extra wide characters stored as byte arrays if (charWidth > 2) { if (fieldValue.GetType() != typeof(byte[])) { throw new TsCCpxInvalidDataToWriteException("Field value is not a byte array."); } bytes = (byte[])fieldValue; charCount = bytes.Length / charWidth; } // convert string to byte array. else { if (fieldValue.GetType() != typeof(string)) { throw new TsCCpxInvalidDataToWriteException("Field value is not a string."); } string stringValue = (string)fieldValue; charCount = stringValue.Length + 1; // calculate length of ascii string by forcing pure unicode characters to two ascii chars. if (charWidth == 1) { charCount = 1; foreach (char unicodeChar in stringValue) { charCount++; byte[] charBytes = BitConverter.GetBytes(unicodeChar); if (charBytes[1] != 0) { charCount++; } } } } } // update the char count reference. if (field.CharCountRef != null) { WriteReference(context, field, fieldIndex, fieldValues, field.CharCountRef, charCount); } if (buffer != null) { // copy string to buffer. if (bytes == null) { string stringValue = (string)fieldValue; bytes = new byte[charWidth * charCount]; int index = 0; for (int ii = 0; ii < stringValue.Length; ii++) { if (index >= bytes.Length) { break; } byte[] charBytes = BitConverter.GetBytes(stringValue[ii]); bytes[index++] = charBytes[0]; if (charWidth == 2 || charBytes[1] != 0) { bytes[index++] = charBytes[1]; } } } // check if there is enough data left. if (buffer.Length - context.Index < bytes.Length) { throw new TsCCpxInvalidDataToWriteException("Unexpected end of buffer."); } // write bytes to buffer. for (int ii = 0; ii < bytes.Length; ii++) { buffer[context.Index + ii] = bytes[ii]; } // swap bytes. if (context.BigEndian && charWidth > 1) { for (int ii = 0; ii < bytes.Length; ii += charWidth) { SwapBytes(buffer, context.Index + ii, charWidth); } } } return(charCount * charWidth); }