void AlignCurrent(ModelAction action) { if (action.AlignmentBits < 8) currentBit += action.AlignmentBits - 1 - (currentBit - 1) % action.AlignmentBits; else { if (currentBit != 0) ++currentByte; var alignmentBytes = action.AlignmentBits / 8; currentByte += alignmentBytes - 1 - (currentByte - 1) % alignmentBytes; } if ((action.Type != ModelAction.ActionType.Bit) && (currentBit != 0)) throw new Exception("All items (except for bits) must be byte-aligned"); }
public ModelActionVM(ModelDataVM modelDataVM, ModelAction action) { this.modelDataVM = modelDataVM; this.action = action; Type = action.Type; CodePage = action.CodePage; StringType = action.StringType; Encoding = action.Encoding; FixedWidth = action.FixedWidth; Model = action.Model; Location = action.Location; AlignmentBits = action.AlignmentBits; RepeatType = action.RepeatType; Repeat = action.Repeat; SaveName = action.SaveName; Description = null; // Flag for reevaluation }
public ModelResult(ModelAction action, int num, string name, string value, long startByte, int startBit, long endByte, int endBit) { Action = action; Num = num; Name = name; Value = value; StartByte = startByte; StartBit = startBit; EndByte = endByte; EndBit = endBit; Location = ""; Location += startByte; if (startBit != 0) Location += $".{startBit}"; Location += $" - {endByte}"; if (endBit != 0) Location += $".{endBit}"; Length = GetLength(startByte, startBit, endByte, endBit); }
bool HandleAction(ModelAction action) { current = EvalExpression(action.Location); var repeat = Convert.ToInt64(EvalExpression(action.Repeat)); var end = long.MaxValue; if (action.RepeatType == ModelAction.ActionRepeatType.DataPosition) { end = repeat; repeat = long.MaxValue; } while (repeat > 0) { if (currentByte >= end) break; --repeat; AlignCurrent(action); if (!SaveResults(action)) return false; } return true; }
bool SaveResults(ModelAction action) { switch (action.Type) { case ModelAction.ActionType.Bit: if (!HandleBit(action)) return false; break; case ModelAction.ActionType.BasicType: if (!HandleBasicType(action)) return false; break; case ModelAction.ActionType.String: if (!HandleString(action)) return false; break; case ModelAction.ActionType.Unused: if (!HandleUnused(action)) return false; break; case ModelAction.ActionType.Model: if (!HandleModel(action.Model)) return false; break; } return true; }
bool HandleUnused(ModelAction action) { var startByte = currentByte; var startBit = currentBit; var fixedLength = Convert.ToInt64(EvalExpression(action.FixedWidth)); currentByte += fixedLength; return true; }
bool HandleString(ModelAction action) { var startByte = currentByte; var startBit = currentBit; switch (action.StringType) { case ModelAction.ActionStringType.StringWithLength: { var count = Coder.BytesRequired(action.CodePage); var bytes = GetBytes(currentByte, count, start, end); currentByte += count; if (bytes == null) return false; var strLen = long.Parse(Coder.BytesToString(bytes, action.CodePage)); bytes = GetBytes(currentByte, strLen, start, end); currentByte += strLen; if (bytes == null) return false; SaveResult(action, Coder.BytesToString(bytes, action.Encoding), startByte, startBit, currentByte, currentBit); } break; case ModelAction.ActionStringType.StringNullTerminated: { var nullBytes = Coder.StringToBytes("\0", action.Encoding); var resultBytes = new byte[0]; while (true) { var bytes = GetBytes(currentByte, nullBytes.Length, start, end); currentByte += nullBytes.Length; if (bytes == null) return false; var found = true; for (var ctr = 0; ctr < nullBytes.Length; ++ctr) if (bytes[ctr] != nullBytes[ctr]) { found = false; break; } if (found) break; Array.Resize(ref resultBytes, resultBytes.Length + bytes.Length); Array.Copy(bytes, 0, resultBytes, resultBytes.Length - bytes.Length, bytes.Length); } SaveResult(action, Coder.BytesToString(resultBytes, action.Encoding), startByte, startBit, currentByte, currentBit); } break; case ModelAction.ActionStringType.StringFixedWidth: { var fixedLength = Convert.ToInt64(EvalExpression(action.FixedWidth)); var bytes = GetBytes(currentByte, fixedLength, start, end); currentByte += fixedLength; if (bytes == null) return false; SaveResult(action, Coder.BytesToString(bytes, action.Encoding), startByte, startBit, currentByte, currentBit); } break; default: throw new Exception("Invalid string type"); } return true; }
bool HandleBasicType(ModelAction action) { var startByte = currentByte; var startBit = currentBit; var codePage = action.CodePage; var count = Coder.BytesRequired(codePage); var bytes = GetBytes(currentByte, count, start, end); currentByte += count; if (bytes == null) return false; SaveResult(action, Coder.BytesToString(bytes, codePage), startByte, startBit, currentByte, currentBit); return true; }
bool HandleBit(ModelAction action) { var startByte = currentByte; var startBit = currentBit; var bit = currentBit; var bytes = GetBytes(currentByte, 1, start, end); ++currentBit; if (bytes == null) return false; SaveResult(action, (bytes[0] & (1 << bit)) == 0 ? "0" : "1", startByte, startBit, currentByte, currentBit); return true; }
void SaveResult(ModelAction action, string value, long startByte, int startBit, long endByte, int endBit) { if (string.IsNullOrEmpty(action.SaveName)) return; values[action.SaveName] = value; if (!nameCounts.ContainsKey(action.SaveName)) nameCounts[action.SaveName] = 0; var name = $"{action.SaveName} #{++nameCounts[action.SaveName]}"; results.Add(new ModelResult(action, results.Count + 1, name, value, startByte, startBit, endByte, endBit)); }