/// <summary> /// Get the next record data /// </summary> /// <param name="rec">Record data</param> /// <returns>True if the operation was succesfull</returns> public bool getNextUpdaterData(ref s19rec rec) { bool bOk = false; do { m_currentIdx++; if (m_currentIdx >= m_aS19Data.Count) { return(false); } if (checkDataType(getS19RecType(m_currentIdx))) { rec = getS19Rec(m_currentIdx); bOk = true; } } while (!bOk); return(true); }
public string[] ConvertS19Data(int iLengthDataBlock) { List <string> sTarget = new List <string>(); int icount = recordCount(); s19rec rec = default(s19rec); int recDecimalAddress = 0; int recDataLength = 0; List <dataBlock> listDataBlock = new List <dataBlock>(); List <dataBlock> listAlignedDataBlock = new List <dataBlock>(); List <byte> currentBlockData = new List <byte>(); int currentBlockAddress = 0; //Dim prevBlockData As New List(Of Byte) //Dim prevBlockAddress As Integer = 0 int nextStartAddress = 0; List <byte> bytesTemp = new List <byte>(); for (var i = 0; i <= icount - 1; i++) { rec = getS19Rec(System.Convert.ToInt32(i)); switch (rec.type) { case '0': myAddS19Record(sTarget, rec.type, convBytesToHexa(rec.address.ToArray()), convBytesToHexa(rec.data.ToArray())); break; case '1': break; case '2': break; case '3': //dirección y longitud del bloque de datos recDecimalAddress = RoutinesLibrary.Data.DataType.IntegerUtils.BytesToInt(rec.address.ToArray(), true); //is BigEndian recDataLength = rec.data.Count; //address gap if (recDecimalAddress > nextStartAddress) { //new block. recording cumulative data if (currentBlockData.Count > 0) { dataBlock block = new dataBlock(currentBlockAddress, currentBlockData.ToArray()); listDataBlock.Add(block); } //accumulates new data currentBlockData.Clear(); currentBlockData.AddRange(rec.data.ToArray()); currentBlockAddress = recDecimalAddress; //no gap } else { //add to current block currentBlockData.AddRange(rec.data.ToArray()); } //calculate next address, to control gaps nextStartAddress = recDecimalAddress + recDataLength; break; case '5': break; case '7': case '8': case '9': break; } } //add remaining data in last block if (currentBlockData.Count > 0) { dataBlock block = new dataBlock(currentBlockAddress, currentBlockData.ToArray()); listDataBlock.Add(block); } //'Align all directions to 128 (iLengthDataBlock) //For i = 0 To listDataBlock.Count - 1 // If listDataBlock.Item(i).m_Address Mod iLengthDataBlock <> 0 Then // 'Calculamos el gap inicial // Dim nInitialGap As Integer = listDataBlock.Item(i).m_Address - ((listDataBlock.Item(i).m_Address \ 128) * 128) // 'Rellenamos los datos iniciales con FF // Dim alignData(listDataBlock.Item(i).m_Data.Length + nInitialGap - 1) As Byte // setArrayTo(alignData, &HFF) // Array.Copy(listDataBlock.Item(i).m_Data, 0, alignData, nInitialGap, listDataBlock.Item(i).m_Data.Length) // 'Actualizamos el array de datos // listDataBlock.Item(i).m_Data = alignData // 'Actualizamos el address // listDataBlock.Item(i).m_Address -= nInitialGap // End If //Next //Align all directions to 128 int lastAlignedDataBlock = -1; for (var i = 0; i <= listDataBlock.Count - 1; i++) { lastAlignedDataBlock = listAlignedDataBlock.Count - 1; if (listDataBlock[System.Convert.ToInt32(i)].m_Address % iLengthDataBlock != 0) { //If listDataBlock.Item(i).m_Address > 486635784 Then // MsgBox("> 486635784") //End If int nInitialGap = 0; int nEndGap = 0; byte[] alignData = null; int nCopyDataLength = 0; int nTargetBufferToCopyLength = 0; // ver si la dirección está dentro del bloque alineado anterior (múltiplo de 128) bool bAlignBlock = true; if (i > 0 & lastAlignedDataBlock >= 0) { int iPreviousBlockAddress = System.Convert.ToInt32(listAlignedDataBlock[lastAlignedDataBlock].m_Address); int iPreviousBlockDataLength = System.Convert.ToInt32(listAlignedDataBlock[lastAlignedDataBlock].m_Data.Length); int iPreviousBlockAlignedBlocks = iPreviousBlockDataLength / iLengthDataBlock; if (iPreviousBlockDataLength / iLengthDataBlock != (double)iPreviousBlockDataLength / iLengthDataBlock) { iPreviousBlockAlignedBlocks++; } if (listDataBlock[System.Convert.ToInt32(i)].m_Address < iPreviousBlockAddress + (iPreviousBlockAlignedBlocks * iLengthDataBlock)) { // copiar parte de los datos al bloque anterior // primero el gap entre el fin de datos y la nueva dirección nEndGap = System.Convert.ToInt32(listDataBlock[System.Convert.ToInt32(i)].m_Address - (iPreviousBlockAddress + iPreviousBlockDataLength)); // espacio que tengo para copiar = el total alineado menos los datos existentes y el gap añadido nTargetBufferToCopyLength = (iPreviousBlockAlignedBlocks * iLengthDataBlock) - (iPreviousBlockDataLength + nEndGap); // datos a copiar: mínimo entre espacio destino y datos origen nCopyDataLength = Math.Min(nTargetBufferToCopyLength, System.Convert.ToInt32(listDataBlock[System.Convert.ToInt32(i)].m_Data.Length)); //Rellenamos los datos iniciales con FF alignData = new byte[nEndGap + nCopyDataLength - 1 + 1]; setArrayTo(ref alignData, (byte)(0xFF)); Array.Copy((System.Array)(listDataBlock[System.Convert.ToInt32(i)].m_Data), 0, alignData, nEndGap, nCopyDataLength); // copiar a bloque anterior bytesTemp.Clear(); bytesTemp.AddRange(listAlignedDataBlock[lastAlignedDataBlock].m_Data); bytesTemp.AddRange(alignData); listAlignedDataBlock[lastAlignedDataBlock].m_Data = bytesTemp.ToArray(); // quitar estos datos del bloque actual y modificar address bytesTemp.Clear(); bytesTemp.AddRange(listDataBlock[System.Convert.ToInt32(i)].m_Data); bytesTemp.RemoveRange(0, nCopyDataLength); if (bytesTemp.Count > 0) { listDataBlock[System.Convert.ToInt32(i)].m_Data = bytesTemp.ToArray(); // modificar address listDataBlock[System.Convert.ToInt32(i)].m_Address = listDataBlock[System.Convert.ToInt32(i)].m_Address + nCopyDataLength; } else { bAlignBlock = false; } } } if (bAlignBlock) { //Calculamos el gap inicial nInitialGap = System.Convert.ToInt32(listDataBlock[System.Convert.ToInt32(i)].m_Address - ((listDataBlock[System.Convert.ToInt32(i)].m_Address / iLengthDataBlock) * iLengthDataBlock)); //Rellenamos los datos iniciales con FF alignData = new byte[listDataBlock[System.Convert.ToInt32(i)].m_Data.Length + nInitialGap - 1 + 1]; setArrayTo(ref alignData, (byte)(0xFF)); Array.Copy((System.Array)(listDataBlock[System.Convert.ToInt32(i)].m_Data), 0, alignData, nInitialGap, System.Convert.ToInt32(listDataBlock[System.Convert.ToInt32(i)].m_Data.Length)); //Actualizamos el array de datos listDataBlock[System.Convert.ToInt32(i)].m_Data = alignData; //Actualizamos el address listDataBlock[System.Convert.ToInt32(i)].m_Address -= nInitialGap; // add aligned block listAlignedDataBlock.Add(listDataBlock[System.Convert.ToInt32(i)]); } } else { // add block, already aligned listAlignedDataBlock.Add(listDataBlock[System.Convert.ToInt32(i)]); } } // build SREC in iDataBlock format byte[] newData = null; newData = new byte[iLengthDataBlock - 1 + 1]; int iCopyLength = 0; int iDataLengthRemainder = 0; int iAddress = 0; int nextStartByte = 0; int iBlockNumber = 0; bool bEnd = false; //recorrer todos los bloques de datos //For i = 0 To listDataBlock.Count - 1 for (var i = 0; i <= listAlignedDataBlock.Count - 1; i++) { //dirección y datos del bloque de datos //currentBlockAddress = listDataBlock.Item(i).m_Address currentBlockAddress = System.Convert.ToInt32(listAlignedDataBlock[System.Convert.ToInt32(i)].m_Address); currentBlockData.Clear(); //currentBlockData.AddRange(listDataBlock.Item(i).m_Data) currentBlockData.AddRange(listAlignedDataBlock[System.Convert.ToInt32(i)].m_Data); //If currentBlockAddress > 486635784 Then // MsgBox("> 486635784") //End If nextStartByte = 0; iBlockNumber = 0; bEnd = false; //loop por el bloque para dividir en direcciones de 128 do { //determinar cuanto queda por copiar iDataLengthRemainder = currentBlockData.Count - nextStartByte; if (iDataLengthRemainder > 0) { //copiamos un bloque entero de datos o el resto if (iDataLengthRemainder > iLengthDataBlock) { iCopyLength = iLengthDataBlock; } else { iCopyLength = iDataLengthRemainder; } //número de bloque a copiar iBlockNumber++; //el buffer de 128 a HFF setArrayTo(ref newData, (byte)(0xFF)); //copy data Array.Copy(currentBlockData.ToArray(), nextStartByte, newData, 0, iCopyLength); //la nueva dirección es la dirección base del bloque más la cantidad de bloques copiados iAddress = currentBlockAddress + (iLengthDataBlock * (iBlockNumber - 1)); //grabar el bloque myAddS19Record(sTarget, '3', convBytesToHexa(intToBytesAddress(iAddress, true)), convBytesToHexa(newData)); //actualizar la siguiente dirección nextStartByte += iCopyLength; } else { bEnd = true; } } while (!bEnd); } return(sTarget.ToArray()); }
/// <summary> /// Get record at a specific line /// </summary> /// <param name="idx">Record line index</param> /// <returns>Record</returns> private s19rec getS19Rec(int idx) { s19rec rec = new s19rec(); int lengthHex = 0; int addressBytes = 0; int posDataHex = 0; int dataLengthHex = 0; // rec type (0 to 9) rec.type = getS19RecType(idx); // qty of bytes of address + data + checksum fields rec.length = int.Parse(System.Convert.ToString(m_aS19Data[idx].Substring(2, 2)), System.Globalization.NumberStyles.AllowHexSpecifier); lengthHex = rec.length * 2; switch (rec.type) { case '0': addressBytes = 2; break; case '1': addressBytes = 2; // data address 16 bit break; case '2': addressBytes = 3; // data address 24 bit break; case '3': addressBytes = 4; // data address 32 bit break; case '5': addressBytes = 2; // S1+S2+S3 record count break; case '7': addressBytes = 4; // starting address of the program 32 bit break; case '8': addressBytes = 3; // starting address of the program 24 bit break; case '9': addressBytes = 2; // starting address of the program 16 bit break; } //Address rec.address = convHexToByteArray(System.Convert.ToString(m_aS19Data[idx].Substring(4, addressBytes * 2))); //Posición inicial de data posDataHex = 2 + 2 + (addressBytes * 2); // Sx + length(2) + address hex length //Longitud de data dataLengthHex = lengthHex - (addressBytes * 2) - 2; // total hex length - address hex length - checksum(2) //Data if (dataLengthHex > 0) { rec.data = convHexToByteArray(System.Convert.ToString(m_aS19Data[idx].Substring(posDataHex, dataLengthHex))); } else { rec.data = new List <byte>(); } //Checksum rec.checksum = convHexToByteArray(System.Convert.ToString(m_aS19Data[idx].Substring(posDataHex + dataLengthHex, 2))); return(rec); }