// 打包为 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()); }
// 打包为 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(); }