Example #1
0
        // 打包为 byte[] 形态
        // TODO: 对于修改的情形,要避开已经 lock 的元素,对元素进行空间布局
        // parameters:
        //      block_map   块地图。用
        //                  字符 'l' 表示原来就是锁定状态的块
        //                  字符 'w' 表示需要新锁定的块
        public byte[] GetBytes(int max_bytes,
                               int block_size,
                               GetBytesStyle style,
                               out string block_map)
        {
            block_map = "";

            // 先对 elements 排序。确保 PII 和 Content Parameter 元素 index 在前两个
            this.Sort(max_bytes,
                      block_size,
                      (style & GetBytesStyle.ContentParameterFullLength) == 0);

            List <char> map     = new List <char>();
            int         start   = 0;
            List <byte> results = new List <byte>();

            foreach (Element element in this._elements)
            {
                if (element.Locked)
                {
                    if (start != element.StartOffs)
                    {
                        throw new Exception($"element {element.ToString()} 的 StartOffs {element.StartOffs} 不符合预期值 {start}");
                    }
                }

                var bytes = element.OriginData;
                results.AddRange(bytes);

                // 设置 block map
                if (element.WillLock || element.Locked)
                {
                    char ch = NormalMapChar;
                    if (element.Locked)
                    {
                        ch = 'l';
                    }
                    else if (element.WillLock)
                    {
                        ch = 'w';
                    }
                    for (int i = start / block_size; i < (start + bytes.Length) / block_size; i++)
                    {
                        SetBlockStatus(ref map, i, ch);
                    }
                }

                start += bytes.Length;
            }

            if (start > max_bytes)
            {
                throw new Exception($"实际产生的 byte 数 {start} 超过限制数 {max_bytes}");
            }

            block_map = new string(map.ToArray());
            return(results.ToArray());
        }
Example #2
0
        // 打包为 byte[] 形态
        // 注意,本函数执行后 this._elements 内各个元素的顺序可能会发生变化
        // 对于修改的情形,要避开已经 lock 的元素,对元素进行空间布局
        // parameters:
        //      block_map   [out]块地图。用 
        //                  字符 'l' 表示原来就是锁定状态的块
        //                  字符 'w' 表示需要新锁定的块
        //                  如果为全部 "....",和 "" 是等同的。缺省的 char 是 '.'
        public byte[] GetBytes(int max_bytes,
            int block_size,
            GetBytesStyle style,
            out string block_map)
        {
            block_map = "";

            if ((max_bytes % block_size) != 0)
                throw new ArgumentException($"max_bytes({max_bytes}) 不是 block_size({block_size}) 的整倍数");

            // 删除空元素
            for (int i = 0; i < this._elements.Count; i++)
            {
                Element element = this._elements[i];
                if (string.IsNullOrEmpty(element.Text)
                    && element.OID != ElementOID.ContentParameter
                    && element.Locked == false)
                {
                    this._elements.RemoveAt(i);
                    i--;
                }
            }

            // 先对 elements 排序。确保 PII 和 Content Parameter 元素 index 在前两个
            this.Sort(max_bytes,
                block_size,
                (style & GetBytesStyle.ContentParameterFullLength) == 0);

            List<char> map = new List<char>();
            int start = 0;
            List<byte> results = new List<byte>();
            foreach (Element element in this._elements)
            {
                if (element.Locked)
                {
                    if (start != element.StartOffs)
                        throw new Exception($"element {element.ToString()} 的 StartOffs {element.StartOffs} 不符合预期值 {start}");
                }

                var bytes = element.OriginData;
                results.AddRange(bytes);

                // 设置 block map
                if (element.WillLock || element.Locked)
                {
                    char ch = NormalMapChar;
                    if (element.Locked)
                        ch = 'l';
                    else if (element.WillLock)
                        ch = 'w';
                    for (int i = start / block_size; i < (start + bytes.Length) / block_size; i++)
                    {
                        SetBlockStatus(ref map, i, ch);
                    }
                }

                start += bytes.Length;
            }

            if (start > max_bytes)
                throw new Exception($"实际产生的 byte 数 {start} 超过限制数 {max_bytes}");

            block_map = new string(map.ToArray());
            return results.ToArray();
        }