Esempio n. 1
0
        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="sField">The field.</param>
        /// <param name="indexValue">The index value.</param>
        /// <param name="data">The data.</param>
        /// <param name="dataOffset">The data offset.</param>
        /// <param name="dataSize">The data size.</param>
        /// <param name="reqType">The req type.</param>
        /// <param name="value">The value.</param>
        /// <exception cref="HfaPointerInsertNotSupportedException">Attempting to insert a pointer is not supported.</exception>
        /// <exception cref="HfaEnumerationNotFoundException">Occurs if the specified value is not a valid member of the enumeration for this field.</exception>
        public void SetInstValue(string sField, int indexValue, byte[] data, long dataOffset, int dataSize, char reqType, object value)
        {
            // If this field contains a pointer, then we wil adjust the data offset relative to it.
            // This updates the offset info, but doesn't change the first four bytes.
            if (Pointer != '\0')
            {
                int nCount;
                if (NumBytes > -1)
                {
                    nCount = ItemCount;
                }
                else if (reqType == 's' && (ItemType == 'c' || ItemType == 'C'))
                {
                    // Either a string or a character array
                    nCount = 0;
                    IEnumerable <char> strVal = value as IEnumerable <char>;
                    if (strVal != null)
                    {
                        nCount = strVal.Count() + 1;
                    }
                }
                else
                {
                    nCount = indexValue + 1;
                }

                uint nOffset = (uint)nCount;
                Array.Copy(Hfa.LittleEndian(nOffset), 0, data, dataOffset + 4, 4);
                dataOffset += 8;
                dataSize   -= 8;
            }

            // Pointers to char or uchar arrays requested as strings are handled as a special case
            if ((ItemType == 'c' || ItemType == 'C') && reqType == 's')
            {
                int nBytesToCopy = NumBytes;
                var strVal       = (value as IEnumerable <char>)?.ToArray();
                if (strVal != null)
                {
                    nBytesToCopy = strVal.Length;
                }
                if (NumBytes == -1 && strVal != null)
                {
                    nBytesToCopy = strVal.Length;
                }

                // Force a blank erase to remove previous characters
                byte[] blank = new byte[nBytesToCopy];
                Array.Copy(blank, 0, data, dataOffset, nBytesToCopy);
                if (strVal != null)
                {
                    ASCIIEncoding ascii    = new ASCIIEncoding();
                    string        str      = new string(strVal);
                    byte[]        charData = ascii.GetBytes(str);
                    Array.Copy(charData, 0, data, dataOffset, charData.Length);
                }

                return;
            }

            // Translate the passed type into different representations
            int    nIntValue;
            double dfDoubleValue;

            if (reqType == 's')
            {
                nIntValue     = int.Parse((string)value);
                dfDoubleValue = double.Parse((string)value);
            }
            else if (reqType == 'd')
            {
                dfDoubleValue = (double)value;
                nIntValue     = Convert.ToInt32((double)value);
            }
            else if (reqType == 'i')
            {
                dfDoubleValue = Convert.ToDouble((int)value);
                nIntValue     = (int)value;
            }
            else if (reqType == 'p')
            {
                throw new HfaPointerInsertNotSupportedException();
            }
            else
            {
                return;
            }

            // Handle by type
            switch (ItemType)
            {
            case 'c':     // Char64
            case 'C':     // Char128
                if (reqType == 's')
                {
                    // handled earlier as special case,
                }
                else
                {
                    data[dataOffset + nIntValue] = (byte)nIntValue;
                }

                break;

            case 'e':     // enums are stored as ushort
            case 's':
                // little s  = ushort type
                if (ItemType == 'e' && reqType == 's')
                {
                    nIntValue = EnumNames.IndexOf((string)value);
                    if (nIntValue == -1)
                    {
                        throw new HfaEnumerationNotFoundException((string)value);
                    }
                }

                // Each enumeration is stored as a 2-bit unsigned short entry.
                ushort num = (ushort)nIntValue;
                Array.Copy(Hfa.LittleEndian(num), 0, data, dataOffset + (2 * indexValue), 2);
                break;

            case 'S':
                // signed short
                Array.Copy(Hfa.LittleEndian((short)nIntValue), 0, data, dataOffset + (indexValue * 2), 2);
                break;

            case 't':
            case 'l':
                Array.Copy(Hfa.LittleEndian((uint)nIntValue), 0, data, dataOffset + (indexValue * 4), 4);
                break;

            case 'L':
                // Int32
                Array.Copy(Hfa.LittleEndian(nIntValue), 0, data, dataOffset + (indexValue * 4), 4);
                break;

            case 'f':
                // Float (32 bit)
                float dfNumber = Convert.ToSingle(dfDoubleValue);
                Array.Copy(Hfa.LittleEndian(dfNumber), 0, data, dataOffset + (indexValue * 4), 4);
                break;

            case 'd':
                // Double (float 64)
                Array.Copy(Hfa.LittleEndian(dfDoubleValue), 0, data, dataOffset + (8 * indexValue), 8);
                break;

            case 'o':
                // object
                if (ItemObjectType == null)
                {
                    break;
                }

                int nExtraOffset = 0;

                if (ItemObjectType.NumBytes > 0)
                {
                    nExtraOffset = ItemObjectType.NumBytes * indexValue;
                }
                else
                {
                    for (int iIndexCounter = 0; iIndexCounter < indexValue; iIndexCounter++)
                    {
                        nExtraOffset += ItemObjectType.GetInstBytes(data, dataOffset + nExtraOffset);
                    }
                }

                if (!string.IsNullOrEmpty(sField))
                {
                    ItemObjectType.SetInstValue(sField, data, dataOffset + nExtraOffset, dataSize - nExtraOffset, reqType, value);
                }

                break;

            default: throw new ArgumentException();
            }
        }