1515
1616using System ;
1717using System . Collections . Generic ;
18- using System . Linq ;
19- using System . Text ;
20- using System . Threading . Tasks ;
2118
2219namespace S7CommPlusDriver
2320{
@@ -90,6 +87,12 @@ private void AddFlatSubnodes(Node node, string names, string accessIds)
9087 names += node . Name ;
9188 accessIds += "." + String . Format ( "{0:X}" , node . AccessId ) ;
9289 break ;
90+ case eNodeType . StructArray :
91+ names += node . Name ;
92+ // TODO: Hier Besonderheit: Zwischen Array-Index und Zugriffs-ID steht noch eine 1.
93+ // Unklar ob die 1 fix ist, oder sich aus einem weiteren Wert ergibt.
94+ accessIds += "." + String . Format ( "{0:X}" , node . AccessId + ".1" ) ;
95+ break ;
9396 default :
9497 names += "." + node . Name ;
9598 accessIds += "." + String . Format ( "{0:X}" , node . AccessId ) ;
@@ -134,6 +137,11 @@ public void BuildTree()
134137
135138 private void AddSubNodes ( ref Node node , PObject o )
136139 {
140+ uint ArrayElementCount ;
141+ int ArrayLowerBounds ;
142+ uint [ ] MdimArrayElementCount ;
143+ int [ ] MdimArrayLowerBounds ;
144+
137145 int element_index = 0 ;
138146 // Sind in einem Bereich überhaupt keine Variablen vorhanden, dann ist diese Liste auch nicht vorhanden.
139147 if ( o . VartypeList != null )
@@ -149,33 +157,73 @@ private void AddSubNodes(ref Node node, PObject o)
149157 node . Childs . Add ( subnode ) ;
150158 // Arrays verarbeiten
151159 // TODO: Besonderheiten der Übersichtlichkeit wegen in eigene Methoden auslagern.
152- if ( vte . OffsetInfoType . GetType ( ) == typeof ( POffsetInfoType_Array1Dim ) )
160+
161+ if ( vte . OffsetInfoType . Is1Dim ( ) )
153162 {
154- POffsetInfoType_Array1Dim oit = ( POffsetInfoType_Array1Dim ) vte . OffsetInfoType ;
155- Console . WriteLine ( "AddSubNodes: POffsetInfoType_Array1Dim" ) ;
156- // Die Zugriffs-ID beginnt hier immer bei 0, unabhängig vom Inter
157- for ( uint i = 0 ; i < oit . ArrayElementCount ; i ++ )
163+ #region Struct/UDT oder flaches Array mit einer Dimension
164+
165+ var ioit = ( IOffsetInfoType_1Dim ) vte . OffsetInfoType ;
166+ ArrayElementCount = ioit . GetArrayElementCount ( ) ;
167+ ArrayLowerBounds = ioit . GetArrayLowerBounds ( ) ;
168+
169+ // Die Zugriffs-ID beginnt hier immer bei 0, unabhängig von Lowerbounds
170+ for ( uint i = 0 ; i < ArrayElementCount ; i ++ )
158171 {
159- var arraynode = new Node
172+ // Struct Array gesondert behandeln/kennzeichnen. Hier ist noch eine zusätzliche ID hinter Array Index
173+ // und Zugriffs-LID vorhanden.
174+
175+ if ( vte . Softdatatype == Softdatatype . S7COMMP_SOFTDATATYPE_STRUCT )
160176 {
161- NodeType = eNodeType . Array ,
162- Name = "[" + ( i + oit . ArrayLowerBounds ) + "]" ,
163- Softdatatype = vte . Softdatatype ,
164- AccessId = i
165- } ;
166- subnode . Childs . Add ( arraynode ) ;
177+ var arraynode = new Node
178+ {
179+ NodeType = eNodeType . StructArray ,
180+ Name = "[" + ( i + ArrayLowerBounds ) + "]" ,
181+ Softdatatype = vte . Softdatatype ,
182+ AccessId = i
183+ } ;
184+ subnode . Childs . Add ( arraynode ) ;
185+
186+ // Alle OffsetInfoTypes die hier kommen, sollten eine Relation Id besitzen.
187+ var ioit2 = ( IOffsetInfoType_Relation ) vte . OffsetInfoType ;
188+
189+ foreach ( var ob in m_objs )
190+ {
191+ if ( ob . RelationId == ioit2 . GetRelationId ( ) )
192+ {
193+ AddSubNodes ( ref arraynode , ob ) ;
194+ break ;
195+ }
196+ }
197+ }
198+ else
199+ {
200+ var arraynode = new Node
201+ {
202+ NodeType = eNodeType . Array ,
203+ Name = "[" + ( i + ArrayLowerBounds ) + "]" ,
204+ Softdatatype = vte . Softdatatype ,
205+ AccessId = i
206+ } ;
207+ subnode . Childs . Add ( arraynode ) ;
208+ }
167209 }
210+ #endregion
168211 }
169- else if ( vte . OffsetInfoType . GetType ( ) == typeof ( POffsetInfoType_ArrayMDim ) )
212+ else if ( vte . OffsetInfoType . IsMDim ( ) )
170213 {
171- POffsetInfoType_ArrayMDim oit = ( POffsetInfoType_ArrayMDim ) vte . OffsetInfoType ;
172- Console . WriteLine ( "AddSubNodes: POffsetInfoType_ArrayMDim" ) ;
214+ #region Struct/UDT oder flaches Array mehr als einer Dimension
215+
216+ var ioit = ( IOffsetInfoType_MDim ) vte . OffsetInfoType ;
217+ ArrayElementCount = ioit . GetArrayElementCount ( ) ;
218+ ArrayLowerBounds = ioit . GetArrayLowerBounds ( ) ;
219+ MdimArrayElementCount = ioit . GetMdimArrayElementCount ( ) ;
220+ MdimArrayLowerBounds = ioit . GetMdimArrayLowerBounds ( ) ;
173221
174222 // Feststellen wie viele Dimensionen das Array besitzt
175223 int actdimensions = 0 ;
176224 for ( int d = 0 ; d < 6 ; d ++ )
177225 {
178- if ( oit . MdimArrayElementCount [ d ] > 0 )
226+ if ( MdimArrayElementCount [ d ] > 0 )
179227 {
180228 actdimensions ++ ;
181229 }
@@ -190,7 +238,7 @@ private void AddSubNodes(ref Node node, PObject o)
190238 aname = "[" ;
191239 for ( int j = actdimensions - 1 ; j >= 0 ; j -- )
192240 {
193- aname += ( xx [ j ] + oit . MdimArrayLowerBounds [ j ] ) . ToString ( ) ;
241+ aname += ( xx [ j ] + MdimArrayLowerBounds [ j ] ) . ToString ( ) ;
194242 if ( j > 0 )
195243 {
196244 aname += "," ;
@@ -201,50 +249,82 @@ private void AddSubNodes(ref Node node, PObject o)
201249 }
202250 }
203251
204- var arraynode = new Node
252+ if ( vte . Softdatatype == Softdatatype . S7COMMP_SOFTDATATYPE_STRUCT )
205253 {
206- NodeType = eNodeType . Array ,
207- Name = aname ,
208- Softdatatype = vte . Softdatatype ,
209- AccessId = id
210- } ;
211- subnode . Childs . Add ( arraynode ) ;
254+ var arraynode = new Node
255+ {
256+ NodeType = eNodeType . StructArray ,
257+ Name = aname ,
258+ Softdatatype = vte . Softdatatype ,
259+ AccessId = id
260+ } ;
261+ subnode . Childs . Add ( arraynode ) ;
262+
263+ // Alle OffsetInfoTypes die hier kommen, sollten eine Relation Id besitzen.
264+ var ioit2 = ( IOffsetInfoType_Relation ) vte . OffsetInfoType ;
212265
266+ foreach ( var ob in m_objs )
267+ {
268+ if ( ob . RelationId == ioit2 . GetRelationId ( ) )
269+ {
270+ AddSubNodes ( ref arraynode , ob ) ;
271+ break ;
272+ }
273+ }
274+ }
275+ else
276+ {
277+ var arraynode = new Node
278+ {
279+ NodeType = eNodeType . Array ,
280+ Name = aname ,
281+ Softdatatype = vte . Softdatatype ,
282+ AccessId = id
283+ } ;
284+ subnode . Childs . Add ( arraynode ) ;
285+ }
213286 xx [ 0 ] ++ ;
214287 // Bei BBOOL-Arrays wird die ID bei Überlauf des kleinsten Array-Index immer auf ein Vielfaches von 8 gerundet.
215- if ( subnode . Softdatatype == Softdatatype . S7COMMP_SOFTDATATYPE_BBOOL && xx [ 0 ] >= oit . MdimArrayElementCount [ 0 ] )
288+ if ( subnode . Softdatatype == Softdatatype . S7COMMP_SOFTDATATYPE_BBOOL && xx [ 0 ] >= MdimArrayElementCount [ 0 ] )
216289 {
217- if ( oit . MdimArrayElementCount [ 0 ] % 8 != 0 )
290+ if ( MdimArrayElementCount [ 0 ] % 8 != 0 )
218291 {
219292 id += 8 - ( xx [ 0 ] % 8 ) ;
220293 }
221294 }
222295 for ( int dim = 0 ; dim < 5 ; dim ++ )
223296 {
224- if ( xx [ dim ] >= oit . MdimArrayElementCount [ dim ] )
297+ if ( xx [ dim ] >= MdimArrayElementCount [ dim ] )
225298 {
226299 xx [ dim ] = 0 ;
227300 xx [ dim + 1 ] ++ ;
228301 }
229302 }
230303 id ++ ;
231304 n ++ ;
232- } while ( n <= oit . ArrayElementCount ) ;
305+ } while ( n <= ArrayElementCount ) ;
306+ #endregion
233307 }
234-
235- if ( subnode . Softdatatype == Softdatatype . S7COMMP_SOFTDATATYPE_STRUCT )
308+ else
236309 {
237- POffsetInfoType_Struct oit = ( POffsetInfoType_Struct ) vte . OffsetInfoType ;
238- foreach ( var ob in m_objs )
310+ #region Struct/UDT aber keine Art von Array
311+ if ( subnode . Softdatatype == Softdatatype . S7COMMP_SOFTDATATYPE_STRUCT )
239312 {
240- if ( ob . RelationId == oit . RelationId )
313+ // Alle OffsetInfoTypes die hier kommen, sollten eine Relation Id besitzen.
314+ var ioit = ( IOffsetInfoType_Relation ) vte . OffsetInfoType ;
315+
316+ foreach ( var ob in m_objs )
241317 {
242- AddSubNodes ( ref subnode , ob ) ;
243- break ;
318+ if ( ob . RelationId == ioit . GetRelationId ( ) )
319+ {
320+ AddSubNodes ( ref subnode , ob ) ;
321+ break ;
322+ }
244323 }
324+ // Es kann durchaus vorkommen, dass kein Eintrag gefunden wird, z.B. wenn ein Bereich wie Merker oder
325+ // Ausgänge leer ist. Darum nicht weiter als Fehler auswerten.
245326 }
246- // Es kann durchaus vorkommen, dass kein Eintrag gefunden wird, z.B. wenn ein Bereich wie Merker oder
247- // Ausgänge leer ist. Darum nicht weiter als Fehler auswerten.
327+ #endregion
248328 }
249329 element_index ++ ;
250330 }
@@ -284,6 +364,7 @@ public enum eNodeType
284364 Undefined = 0 ,
285365 Root ,
286366 Var ,
287- Array
367+ Array ,
368+ StructArray
288369 }
289370}
0 commit comments