private void addOperandAddress(UnitronicsPLC plc, OperandType type, ushort address) { ushort maximumAddress = plc.GetMaximumOperandAddress(type) ?? ushort.MaxValue; if (isBitOperandType(type)) { if (_operandRequests.ContainsKey(type) == false) { VectorialOperandRequest newRequest = new VectorialOperandRequest(type, address, 8); if (newRequest.EndAddress > maximumAddress) { newRequest.StartAddress = (ushort)(maximumAddress - 7); } _operandRequests.Add(type, newRequest); return; } if (_operandRequests.TryGetValue(type, out IOperandRequest genericRequest) && genericRequest is VectorialOperandRequest existingRequest) { if (address >= existingRequest.StartAddress && address > existingRequest.EndAddress) { existingRequest.Count = (ushort)(address - existingRequest.StartAddress + 1); } if (existingRequest.Count % 8 != 0) { existingRequest.Count = (ushort)(existingRequest.Count + (8 - (existingRequest.Count % 8))); } if (existingRequest.EndAddress > maximumAddress) { existingRequest.StartAddress -= (ushort)(existingRequest.EndAddress - maximumAddress); } } } else { if (_operandRequests.ContainsKey(type) == false) { _operandRequests.Add(type, new NonVectorialOperandRequest(type)); } if (_operandRequests.TryGetValue(type, out IOperandRequest genericRequest) && genericRequest is NonVectorialOperandRequest request && request.Addresses.Contains(address) == false) { request.Addresses.Add(address); } } }
private bool newOperandAddressFitsBuffer(OperandType type, ushort address, ushort maximumBufferSize) { ushort requestBufferSize = calculateRequestBufferSize(); ushort responseBufferSize = calculateResponseBufferSize(); byte operandByteLength = calculateOperandByteLength(type); if (operandByteLength < 2) { operandByteLength = 2; } if (_operandRequests.ContainsKey(type) == false) { if (requestBufferSize + 6 > maximumBufferSize || responseBufferSize + operandByteLength > maximumBufferSize) { return(false); } return(true); } if (_operandRequests.TryGetValue(type, out IOperandRequest genericRequest) == false) { return(false); } if (isBitOperandType(type)) { if (genericRequest is not VectorialOperandRequest) { return(false); } VectorialOperandRequest request = (VectorialOperandRequest)genericRequest; if (address < request.StartAddress) { return(false); } if (address >= request.StartAddress + request.Count) { int additionalBitCount = address - request.StartAddress - request.Count + 1; if (request.Count % 8 != 0) { additionalBitCount -= 8 - (request.Count % 8); } if (additionalBitCount <= 0) { return(true); } int additionalBytes = additionalBitCount / 8; if (additionalBitCount % 8 != 0) { additionalBytes += 1; } int currentBytes = request.Count / 8; if (request.Count % 8 != 0) { currentBytes += 1; } if ((currentBytes + additionalBytes) % 2 != 0) { additionalBytes += 1; } if (responseBufferSize + additionalBytes > maximumBufferSize) { return(false); } } } else { if (genericRequest is not NonVectorialOperandRequest) { return(false); } NonVectorialOperandRequest request = (NonVectorialOperandRequest)genericRequest; if (request.Addresses.Contains(address)) { return(true); } if (requestBufferSize + 2 > maximumBufferSize || responseBufferSize + operandByteLength > maximumBufferSize) { return(false); } } return(true); }